This page is public — anyone with the link can read it, including the client names and incidents below. Sign-in is built and switched off; remove PUBLIC=1 to turn it on.
v0.1.0 private

What one project learned,
on the next one.

63 artifacts from 5 projects. Each one is an incident that cost something, written down so the next project does not pay for it again. This page is generated from the repo on every build, so nothing on it can go stale without the build going with it.

the number

artifacts recalled on a project that did not produce them
46 / 63

46 of 63 live artifacts have been recalled on a project that did not write them. That is the only figure on this page that is evidence of anything. Everything under it counts how much was written down, which is a cost, not a return.

63
live artifacts
2
retired
7
projects bound
3
promoted public
16
gates proven
1
recall runs

where it came from

Every artifact names the project whose incident produced it, checked against projects.json. An artifact from a project this layer has never been told about cannot be written at all.

projectrepoartifactswith codepublic
CapitalCodabrij-coda/VCOS4102
MeraPeonbrij-coda/merapeon + brij-coda/aipark1801
procuresherpabrij-coda/procuresherpa200
sherpa-privatebrij-coda/sherpa-private100
sherpabrij-coda/sherpa100

nismpass, stack-template have produced nothing. A bound project with no artifacts is either genuinely uneventful or has never been swept, and from here the two look identical.

63
type · prose
63
scope · shared
63
vocabulary tokens

the artifacts

Each one opens on what went wrong, not on what the rule is. A rule with no incident behind it gets argued with; a rule that cost something does not.

A baselined gate that stores absolute paths cries wolf on every other machineCapitalCoda

The typecheck baseline normalised each error's location but stored the message verbatim — and some messages embed absolute file:// URLs. Two of 33 entries only ever matched on the machine that generated them, so the gate reported them as new errors on every fresh clone.

id
a-baseline-that-pins-one-machines-paths
verified
Reproduced on a second machine, where exactly those two entries stopped matching; fixed by normalising inside the message text as well as the locationCapitalCoda backend typecheck gate, 33 baseline entries
applies to
build gate testing verification
source
memory:typecheck-baseline-portability.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
A build-skip rule that diffs against a previous SHA breaks the first production deployCapitalCoda

An ignoreCommand comparing the previous deployed SHA to HEAD worked on dev, where that SHA was present, and broke the first production deploy — because the build runs from a shallow clone and the production project had no previous SHA in it.

id
a-build-skip-that-reads-a-shallow-clone
verified
Found on the deploy it broke, v0.14.4 to v0.14.5, and fixed by guarding the case where the previous SHA is absent from the shallow cloneCapitalCoda, both Vercel projects, 2026-07-26
applies to
build ci cost deploy vercel
source
memory:vercel-spend-optimisation.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
A check that finds nothing looks exactly like a check that passesCapitalCoda

Four separate times in one session, a confident all-clear was printed underneath a command that had checked nothing — head truncation, a crashed regex, a pipeline exit status taken from sed, and 2>/dev/null discarding the only stream carrying the data.

id
a-check-that-finds-nothing
verified
Each of the four was caught only by re-running the check in a way that could produce a positive, and the corrected counts differed every time — 31 orphaned processes reported as 3, and so onCapitalCoda, one session, 2026-08-01
applies to
debugging gate verification
source
memory:dont-trust-a-truncated-check.md
as of
2026-08-05
reaches
sherpa, sherpa-private
Trimming the fragments of a delta stream corrupts every multi-word valueCapitalCoda

Live transcription arrives as fragments with the leading spaces already in place. Trimming each fragment before joining turned "Rebright Partners" into "re bright par tner s", so every downstream name match silently missed.

id
a-delta-stream-owns-its-whitespace
verified
Measured on a live call by speaking synthesized audio into a real session, not inferred from the response shapeCapitalCoda voice path, Gemini Live bidiGenerateContent
applies to
agent-loop gemini streaming voice
source
memory:gemini-live-transcription-deltas.md
as of
2026-08-05
A gate that cannot run must fail — silence is not a passCapitalCoda

A frontend type gate printed a tick all day while checking nothing. It shelled out to npx, which does not exist on that machine; the spawn failure left stdout and stderr empty, the catch read them as "no errors", and six real type errors reached Vercel where the deploy failed.

id
a-gate-that-cannot-run-must-fail
verified
Fixed by resolving node_modules/.bin/tsc directly instead of a PATH lookup, and by exiting 2 when tsc produces no output at allCapitalCoda frontend, v0.18.6, after the same gate had failed a second time in a new way
applies to
build gate testing verification
source
memory:frontend-typecheck-noop.md, memory:frontend-gate-vite-build.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
A presigned upload works from the server and fails from the browser, and the URL is not the problemCapitalCoda

Browser document upload failed with "Failed to fetch" while the same presigned URL returned 200 from a server-side PUT. The URL was correct throughout; the bucket had no CORS policy allowing the app origin, so the browser blocked the preflight.

id
a-presigned-url-still-needs-bucket-cors
verified
Confirmed by contrast — server-side PUT to the identical presigned URL returned 200 while the browser PUT never left the preflightCapitalCoda, AWS S3 us-east-1, browser presigned PUT flow
applies to
auth aws-s3 debugging
source
memory:s3-doc-storage-cors.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
Dogfooding a shared contract by building off it produces the orphan you were demonstrating againstCapitalCoda

An agent was built to demonstrate the new shared paradigm, on the old bespoke spine — its own tables, a hand-rolled pipeline, a standalone console. Then a document held that build up as the golden path, recommending reuse of components the same plan said to retire.

id
a-reference-build-does-not-justify-a-bespoke-one
verified
Torn down entirely rather than migrated; the owner caught both the self-contradicting document and the fact that the promised consolidation had never happened on the frontendCapitalCoda, 2026-07-23
applies to
agent-loop planning
source
memory:dogfood-agent-orphaning-lesson.md
as of
2026-08-05
A required field in a structured-output schema makes the whole run all-or-nothingCapitalCoda

A required nested scores object was added to an LLM output schema. When the model legitimately omitted one score for a thin candidate, the parser rejected the entire batch, an empty catch swallowed it, and the run returned zero results while the UI silently fell back to sample data.

id
a-required-field-the-model-cannot-always-fill
verified
Reproduced as a live failure for a second tenant on the same default model while passing locally for the first — non-determinism, not a weaker modelCapitalCoda, v0.12.12 regression fixed in v0.12.13
applies to
agent-loop anthropic error-handling
source
memory:llm-schema-strictness-regression.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
A user who cannot see progress concludes the app is dead, and reports a bug that is not oneCapitalCoda

A run that completed correctly was reported as "I tried asking a question in chat, nothing happened". Runs take 15 to 200 seconds and the only indicator was a seconds counter, which the owner described as almost invisible — the second time he had raised it.

id
a-run-with-no-visible-progress-reads-as-broken
verified
Replaced with a shared full-width progress component used by every surface that shows a run in flight, so the affordance cannot differ per screenCapitalCoda, v0.14.2, after the complaint recurred
applies to
agent-loop ui ux
source
memory:run-progress-visibility.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
A reusable component that special-cases one caller rots into half-covered behaviourCapitalCoda

Shared components rendering across many entity types were acquiring per-entity branches, which produced inconsistent behaviour — the same tab behaving differently depending on which entity you reached it from.

id
a-shared-component-must-not-branch-on-entity-type
verified
Established as the standing pattern from a component built the right way, where adding an entity is a one-line registry change rather than a new branchCapitalCoda, 2026-07-16
applies to
planning react ui
source
memory:standard-components-generic.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
When an explanation is not landing, the next version must be shorterCapitalCoda

Across four rounds of pushback on positioning copy, each revision answered by adding structure — four stages, then eight agents and sixteen named skills, then four memory lanes and three autonomy rungs. Every version was more elaborate and less persuasive.

id
adding-a-framework-is-the-tell
verified
Halted by the owner with the diagnosis stated directly — either the platform is very complicated, or it is not being explained plainly, or bothCapitalCoda, 2026-07-31
applies to
planning writing
source
memory:explain-plainly-not-architecture.md
as of
2026-08-05
A watermark sync passing clean is not evidence the data arrivedCapitalCoda

A production seed died mid-run having materialised 960 of 2,023 rows. The incremental sync then reported clean every 15 minutes — correctly — because the 1,063 missing rows were last edited before the watermark and no incremental pull could ever select them again.

id
an-incremental-sync-cannot-recover-what-it-skipped
verified
A coverage check was added that counts mapped source rows with no corresponding link, so a gap makes the run fail rather than pass; it is the check that would have caught the half-dead seedCapitalCoda, dev 0.28.5, after a 2026-08-03 production seed failure
applies to
data-import gate verification
source
memory:mirror-coverage-detection.md
as of
2026-08-05
reaches
sherpa, sherpa-private
After a deploy, an open tab is still running the old build and its chunks are goneCapitalCoda

Errors kept appearing on production after a fix had shipped, because open tabs were still running the pre-fix bundle. The generic error card people reported was the OLD build's boundary, not a failure of the deployed fix — which made the fix look broken.

id
an-old-tab-runs-the-previous-build
verified
Distinguished by which error boundary rendered — the old build's generic card versus the new one's — and resolved by a version poll plus a retry at the import promise across all 105 route laziesCapitalCoda frontend, v0.9.43
applies to
deploy error-handling react spa vite
source
memory:stale-chunk-auto-reload.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
jsonb_build_object needs a cast on the KEY, not just the valueCapitalCoda

Both writers into firms.settings carried the same bug, so every save of an org profile failed with "could not determine data type of parameter $1" — casting the value alone was not enough.

id
an-uncast-bound-parameter-rejects-the-whole-statement
verified
Fixed by adding ::text to the key interpolation; both writers exercised afterwards during the v0.14.7 backfillCapitalCoda, drizzle over Neon Postgres, 2026-07-27
applies to
data-import drizzle postgres
source
memory:jsonb-key-cast-bug.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
A batch of findings gets one section per item, each led by what was found in the codeCapitalCoda

Terse batches of five or more findings from the owner's own passes were being answered by fixing one and leaving the rest unexamined, so each reply generated another round.

id
answer-every-item-before-replying-to-any
verified
The format that worked let the owner answer all five items in one short reply, and was adopted as standing on the strength of thatCapitalCoda, 2026-07-27
applies to
planning verification writing
source
memory:long-form-assessment-style.md
as of
2026-08-05
When something has never run in an environment, ask whether it CAN before asking what is missingCapitalCodapublic

The last blocker on the voice stack was reported twice and was wrong both times. Each was the next visible gap, not the real one, and the ceiling that actually made it impossible was knowable from the first day.

id
ask-if-it-can-run-here-first
verified
The third answer held. Once the environment question was asked, the stack moved to a long-lived worker and a real two-way call completed.CapitalCoda voice stack, 2026-08-01 to 2026-08-03
applies to
debugging deploy serverless verification
source
memory:voice-worker-ec2.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
public at
HARNESS.md#III.4a · When it has never run there
A serverless Postgres pool hangs on a large statement rather than erroringCapitalCoda

A 500-row bulk insert hung forever with no error against the serverless WebSocket pool — which is the production driver, so it was not a local quirk. Chunking to about 100 rows per statement fixed it.

id
bulk-writes-need-chunking-and-a-reaper
verified
Found while fixing an import timeout and fixed by chunking; the surrounding gotchas were each hit in the same build and verified by the working queryCapitalCoda backend, Neon serverless pool, commit 5217915
applies to
data-import drizzle neon postgres
source
memory:vcos-bulk-db-gotchas.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
The distinction is whether a CLI holds its own credential, not control plane versus data planeCapitalCodapublic

The rule used to say the control plane needs the owner. That was wrong and it cost a standing hand-off on every project for no reason — neonctl, vercel and gh each hold their own credential and answer immediately.

id
check-for-a-cli-before-saying-dashboard
verified
Corrected on 2026-08-01 by simply running them — gh auth status, vercel whoami and neonctl me all returned an identityneonctl, vercel and gh on the owner's machine, re-verified 2026-08-05
applies to
debugging deploy neon vercel
source
memory:provider-cli-access.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
public at
HARNESS.md#III.6a · The provider CLI is authenticated
Picking an option authorises thinking; a plan authorises building; neither is the otherCapitalCoda

A feature was started immediately after the owner picked it from an options question. Later the same mistake was made through a decision widget titled "Build it, and from where" — a widget answer was read as build approval and a milestone shipped off it.

id
choosing-a-direction-is-not-approval-to-build
verified
Both times the owner stopped the work and restated the gate; the second time it was written into the widget rules themselves so the affordance could not imply the authority againCapitalCoda, 2026-07-11 and again 2026-08-03
applies to
planning writing
source
memory:feature-approval-required.md
as of
2026-08-05
Removing a module from the registry makes its routes visible to everyone, not to nobodyCapitalCoda

Hiding a module by deleting its registry entry turned every one of its routes into an unmapped route — and the access check treats unmapped routes as always visible. It would have exposed a column to all eight tenants, including the five never entitled to the module.

id
hiding-a-thing-by-unregistering-it-reveals-it
verified
Caught before shipping while hiding one module at v0.17.11, by reading the access check to its last line rather than assuming what unregistering doesCapitalCoda, 8 tenants, 2026-07
applies to
privacy tenancy ui
source
memory:hiding-a-module-trap.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
A selection matched by comparing display text is dropped the moment the user edits itCapitalCoda

A complaint that an agent "only returns one result" was neither the model nor cardinality. The chosen capability was retained only while the request text stayed verbatim what the suggestion chip wrote, so typing your own text or renaming what you cared about silently reverted to the default.

id
identity-inferred-from-mutable-text-is-lost-on-edit
verified
Root-caused by reading the retention condition rather than the model output, and fixed by declaring the choice explicitly instead of inferring it; every historical run on the bench read "1 signal", which matched the complaint exactlyCapitalCoda, dev v0.18.8, after three complaints from a customer call
applies to
agent-loop debugging ui
source
memory:policy-agent-skill-picker.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
Abandoned dev servers accumulate invisibly, because each one looks tinyCapitalCoda

A laptop running hot and draining on battery had 31 deno processes alive, 15 of them watch-mode backends, the oldest up 3 days 16 hours — every one an abandoned dev server from an earlier session.

id
kill-every-process-you-start
verified
Killing them dropped swap from 11.2 GB to 8.3 GB immediatelythe owner's machine, 2026-08-01
applies to
context-management debugging verification
source
memory:kill-dev-servers-at-session-end.md
as of
2026-08-05
Dark mode is not a token swap, and the number that proves it takes five minutes to getCapitalCoda

A dark mode setting was asked for and deferred within the same conversation. Before it was dropped, the codebase was counted rather than estimated — and 156 of 301 component files hardcode colours that no token swap will flip.

id
measure-before-scoping-a-cross-cutting-change
verified
Counted directly in the frontend source on 2026-08-03 — 79 theme tokens in a single block, one light palette, no dark counterpart, and 52% of components hardcoding coloursCapitalCoda frontend, 301 .tsx files
applies to
planning react tailwind ui
source
memory:dark-mode-scope.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
Do not propose a production deploy between implementation phasesCapitalCoda

A prod merge was recommended after each sub-phase of a multi-phase build. Restated after a report ended with "or ship to prod first — my lean would be to ship", which pushed a decision back at the owner that had already been made.

id
multi-phase-work-stays-on-dev-until-the-owner-calls-it
verified
Two separate corrections eight days apart, the second explicitly asking that it be rememberedCapitalCoda, 2026-07-22 and 2026-07-30
applies to
deploy planning release
source
memory:dev-first-full-build-then-prod.md, memory:no-prod-nudges-mid-phase.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
Remaining context is yours to manage, not something to report or to stop short forCapitalCoda

Work that was ready and approved was stopped twice in one session, each time with a paragraph explaining that the session was running low on context — based on a wrong model of the environment, where compaction is automatic.

id
never-narrate-your-own-runway
verified
The factual claim underneath it was checked and was false — the window compacts automatically, carrying a summary plus remaining context, and work continuesCapitalCoda, 2026-07-28
applies to
context-management writing
source
memory:manage-context-dont-report-it.md
as of
2026-08-05
A text extractor that always returns something returns garbage, and the pipeline believes itCapitalCoda

The old extractor decoded any file as latin1 and kept the printable ASCII, so a PDF yielded its uncompressed structural skeleton — plausible-looking text that was not the document's content, passed downstream as though it were.

id
never-return-junk-from-a-document-reader
verified
Replaced by a ladder that decides whether a type is readable BEFORE downloading and returns nothing plus a reason otherwise; the old function is deleted with a tombstone rather than left callableCapitalCoda, dev v0.17.8–0.17.10, Mistral OCR
applies to
data-import error-handling ocr
source
memory:document-reading-ocr.md
as of
2026-08-05
UI that offers an action the backend does not have is worse than no UICapitalCoda

A tab shipped a prompt to connect a storage provider and pull documents in. The picker it promised was never built, so once a user connected, the prompt vanished and nothing replaced it. A potential customer hit the dead end.

id
never-ship-a-promise-the-product-cannot-keep
verified
Confirmed by walking the flow as the customer had — connect, then find nothing thereCapitalCoda, 2026-07-15
applies to
planning ui ux
source
memory:ship-complete-features.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
Migrations applied by hand leave no record, and the environments diverge silentlyCapitalCoda

Migrations were applied by hand with psql because the runner pointed at a retired SDK. Nothing recorded what had run where, and a migration was found applied to production that had never been applied to dev.

id
nothing-recorded-what-had-run-where
verified
A real runner with a ledger was built and baselined across both databases; the drift it exposed was migration 166, live on prod and absent from devCapitalCoda, dev v0.19.12, ledger baselined at 188 on both databases
applies to
deploy migration postgres verification
source
memory:migration-runner-and-drizzle-stock.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
Everything gettable is a tool; the model call is for the part that is genuinely a judgementCapitalCoda

Agent runs were making multiple model calls for work that was retrievable — lookups and registry reads dressed up as reasoning — which cost money, added latency and made each run non-deterministic in places it did not need to be.

id
one-model-call-where-judgement-is-required
verified
Shipped as the shared loop for the first agent and then adopted as the pattern every other agent was standardised onto — a new agent became a spec entry rather than a copied pipelineCapitalCoda, dev v0.12.17, then all seven agents
applies to
agent-loop anthropic cost
source
memory:lean-llm-agent-pipeline.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
A paginated list ordered by a non-unique column duplicates and skips rows, and the UI goes quietly deadCapitalCoda

A 570-row list where 533 shared one bulk-import timestamp. Paging by created_at only returned 570 rows containing 532 distinct ids, and the duplicate React keys made search, facet filters and column sort all silently stop working.

id
paginated-lists-need-a-unique-tiebreaker
verified
Proven on production — six pages of LIMIT 100 OFFSET by created_at alone returned 570 rows but only 532 distinct idsCapitalCoda, 2026-07-18, a 570-prospect list with a single July-4 import timestamp
applies to
pagination postgres ui
source
memory:paginated-list-tiebreaker.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
Autocapture off means your exception count is only the errors you wrapped by handCapitalCoda

Exception autocapture was off, so only errors caught by a hand-written boundary ever arrived. Async handlers, event listeners and unhandled promise rejections were invisible, and the exception count read as healthy because it was counting a subset nobody had described as a subset.

id
read-production-behaviour-with-a-management-key
verified
Audited by querying the analytics management API directly with a personal API key, then flipping autocapture through the same API and confirming the new classes of exception arrivedCapitalCoda, dev v0.26.1 to v0.26.3, 2026-08-02
applies to
error-handling logging posthog verification
source
memory:posthog-error-tracking.md
as of
2026-08-05
Read the real records first, opinion second, mockups with real content third, build lastCapitalCoda

Made the standard process after a design round where the order had been reversed — a view formed from the schema and an assumption about what the records contained, rather than from the records.

id
read-the-real-data-before-forming-a-view
verified
Adopted as the standing process for every feature brainstorm and implementation plan after the design it came out ofCapitalCoda, 2026-07-29
applies to
planning ui verification
source
memory:brainstorm-to-plan-process.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
Release notes ship with MEDIUM and MAJOR releases only — a channel people abandon is worse than no channelCapitalCoda

The rule first said every version bump. CapitalCoda ships several minors a week, which produces a notes page nobody finishes. The same codebase already had the proof — a Feature Log of 397 entries across 291 versions, appended on every ship and read by nobody.

id
release-notes-on-medium-and-major
verified
Corrected by the owner the same day the first version was written, against a measured example of the failure already running in the same codebaseCapitalCoda, 291 versions of Feature Log evidence, 2026-08-04
applies to
release writing
source
memory:release-notes-for-medium-releases.md
as of
2026-08-05
Do not say done until the plan's own stated verification has been run and reportedCapitalCoda

A plan said verbatim to verify with one question per module across seven modules. Four question shapes were tested on one firm, done was declared, and the owner had to ask "are you done?" four separate times — each time surfacing more unbuilt work.

id
run-the-plans-own-verification-before-saying-done
verified
Each of the four re-checks found a further gap, including a route filed as an optional later phase that turned out to be load-bearingCapitalCoda, the Universal Chat build, from v0.15.3, 2026-07-28
applies to
gate planning verification
source
memory:run-the-plans-own-verification.md
as of
2026-08-05
reaches
sherpa, sherpa-private
A document delivered as a hosted link has a dependency it never neededCapitalCoda

A plan was published as a hosted artifact, the link did not open, and the recipient had nothing at all — where a file would have opened from the desktop.

id
send-the-file-do-not-publish-a-link
verified
Reverted to sending self-contained .html files, which is how the earlier mockups had always been delivered; the hosted version was the deviationCapitalCoda, 2026-08-03
applies to
planning writing
source
memory:deliver-docs-as-html-files.md
as of
2026-08-05
A long call cannot run on request-scoped serverless, and it fails three separate waysCapitalCoda

A voice agent that holds one WebSocket for a 30-minute call was built against Vercel functions, which cap at 300 seconds. It had never run end to end and could not have.

id
serverless-cannot-hold-a-long-lived-socket
verified
Moved to a long-lived worker co-located with the media provider; a full 364-second two-way call then completed and was committedDeno + Hono on EC2 t4g.small us-west-2, gemini-2.5-flash-native-audio-latest
applies to
deploy long-lived-worker serverless vercel voice websocket
source
memory:voice-worker-ec2.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
A database that never suspends is being held awake by its fastest cron, not by its busiest oneCapitalCoda

Production Neon was active 82.3 of 84 hours and egressed 10.3 GB in 3.5 days. Nothing could go 300 seconds untouched because one cron ran every 2 minutes, so the autosuspend timer never elapsed once.

id
the-fastest-cron-sets-the-whole-duty-cycle
verified
Autosuspend floor tested directly against the API — 120, 180 and 240 all rejected as "suspend interval is too short for your plan", 300 accepted. Crons moved to */15+ with an expected duty cycle of ~100% to ~35%.CapitalCoda production Neon on Launch, 2026-08-04
applies to
cost deploy neon postgres
source
memory:neon-cost-optimisation.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
A version in a commit message is fiction — and only the owner calls a feature releaseCapitalCoda

Versions were being declared in commit subjects and changelog entries while the file that actually carries the version went unedited, so what shipped and what was announced diverged.

id
the-version-lives-in-the-file-not-the-commit
verified
Independently confirmed on 2026-08-05 in a different repo, where three consecutive commit subjects declared 0.4.1, 0.5.0 and 0.5.1 while the manifest sat at 0.4.0 — all three releases undeliverable to anyone already installedCapitalCoda, and reproduced in brij-coda/sherpa
applies to
deploy release verification
source
memory:version-bump-approval.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
A third-party connection expires while your own table still says connectedCapitalCoda

A real inbound lead produced no notification email. The record saved fine; only sending failed, and nothing recorded it — because the provider's connection had expired with a permanent auth error while the local integrations table still read "connected", and nothing reconciles the two.

id
two-systems-that-both-think-they-are-authoritative
verified
Both expired connections identified by querying the provider directly and comparing to the local status column — a read-only check taking about twenty secondsCapitalCoda, 2026-08-02, two connections expired including the app-level one
applies to
auth composio error-handling logging
source
memory:agent-email-composio-expiry.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, stack-template
A model id copied from a list in the codebase is not a model your account servesCapitalCoda

A model id was taken from a hardcoded list in the source, which was stale. The account's key did not serve it, so every research and enrichment call hard-failed on production.

id
validate-a-model-id-before-shipping-it
verified
Fixed by querying /v1/models with the account's own key and pinning an id the account actually servesCapitalCoda, v0.8.25 regression, 2026-07-17
applies to
agent-loop anthropic deploy verification
source
memory:anthropic-model-config.md
as of
2026-08-05
reaches
MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
Anything with the owner's name on it goes out in the owner's voiceCapitalCoda

Drafts kept coming back corrected line by line for the same tells — em-dashes, rhetorical rhythm, marketing cadence — until a voice profile was compiled from the owner's own messages and corrections rather than inferred from them.

id
write-in-the-owners-voice-not-yours
verified
Compiled from primary sources — his own messages, his line-by-line corrections of drafts, and a call transcript — rather than from a description of how he writesCapitalCoda and MeraPeon, profile compiled 2026-07-31
applies to
writing
source
memory:brij-voice-profile.md, memory:write-in-brijs-voice.md
as of
2026-08-05
One step exited 1 and scrolled off the top, and the release looked exactly like a good oneMeraPeon

An app distribution step failed while every other part of the release succeeded — both projects deployed, both version endpoints went green, the site served the new binary. The only sign was a single line already scrolled off the top, and users on the two routes were left a version apart.

id
a-deploy-that-fails-inside-a-successful-release
verified
Fixed by verifying each step rather than trusting an exit code, and by checking the SHA-256 the distribution URL carries against the binary the site serves — which proves one build, where a version string only proves what a build was namedMeraPeon release pipeline
applies to
ci deploy release verification
source
commit:8406cf7a
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
A documented gate command that never worked, in a project where shipping worked the whole timeMeraPeon

The documented gate command could not run on the machine that documented it — it needed two environment variables that were never exported, and pointed at a path in the wrong directory. It had been listed in commit messages as a gate that passed.

id
a-gate-nobody-can-run-is-reported-as-green
verified
Reproduced by pasting the documented line as written, which fails three separate ways in sequence — wrong directory, missing runtime, missing SDK locationMeraPeon, the Android gate
applies to
build ci gate verification
source
commit:cb8c4055
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
The scope gate exempted the directory where the riskiest code livesMeraPeon

The tenant-scoping gate walked only the source directory, so everything under scripts/ was exempt — including the legacy import that wrote 14,589 vehicle rows and their encrypted phone numbers into production.

id
a-gate-that-walks-only-part-of-the-tree
verified
Widened to include scripts/, which immediately caught a script reading a protected table directly — the gate found a real violation on the first run after the changeMeraPeon backend
applies to
gate privacy tenancy verification
source
commit:89b3f7b4
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
An installer swept in by git add -A stays in history after you delete itMeraPeon

A 61 MB gcloud tarball and the entire google-cloud-sdk install tree were committed alongside a JWKS fix. Untracking them later did not shrink anything — the repo's .git is 203 MB for 221 files.

id
a-large-file-committed-once-is-committed-forever
verified
Measured directly — git ls-files shows zero google-cloud paths tracked today, and du -sh .git still reports 203 MB against a 221-file working treebrij-coda/merapeon, 110 commits, measured 2026-08-05
applies to
git google-cloud repo-hygiene
source
commit:29573655, commit:e128a5e8, commit:cb235e11
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
Catching a config error in the same handler as an auth failure makes a broken deploy look like a forged tokenMeraPeonpublic

The Firebase key set was fetched from /jwks/ (plural) where Google serves /jwk/ (singular). The 404 was caught alongside every other verification failure and answered 401 Invalid token, so every phone sign-in would have failed forever with the only trace a line in a server log.

id
a-misconfiguration-that-looks-like-an-attack
verified
Verified end to end on the emulator with the dev door closed server-side so phone OTP was the only way in — number, code, Firebase UID bound to the existing admin row, session JWT stored, tenant resolved. A dedicated firebase-jwks_test.ts was added.MeraPeon backend, 61 backend tests and 61 Android tests green, all 7 gates proven
applies to
auth error-handling firebase jwt testing
source
commit:29573655
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
public at
HARNESS.md#Google serves JWKS at
The script that proves your gates fail can itself go vacuous, and it reports successMeraPeon

prove-gates reported "all 5 gates fail" while two of its checks were vacuous — after a file move, the paths it planted errors into no longer existed, so the copy and edit steps did nothing and the gate under test was never given anything to catch.

id
a-proof-harness-that-proves-nothing
verified
Caught by the proof harness's own run during a directory restructure, and fixed by asserting the plant landed before trusting the red resultMeraPeon, Phase 1A core/modules split
applies to
gate testing verification
source
commit:7a3a2140
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
A queue that has never held a single item, because both its filters name columns no code writesMeraPeon

A queue selected on two columns, neither of which is written anywhere in the product. One always-null column made its clause always true and was harmless; the other made its clause always false, so the query returned nothing on every day the feature had existed.

id
a-query-on-columns-nothing-writes
verified
Confirmed against production data — the queue had returned zero rows on every day since the feature shipped, and the columns are absent from every write pathMeraPeon production
applies to
postgres ui verification
source
commit:f4311612, commit:30adb81a
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
Opening a screen wrote a persisted preference it never needed, and pinned the device permanentlyMeraPeon

An end-of-day sweep tile set a persisted mode preference on its way to opening. Because the fallback consults that preference whenever a gate is marked as both directions — which both gates at the site are — touching the sweep once pinned the handset to exit mode for good.

id
a-side-effect-that-outlived-its-visit
verified
Traced from the persisted preference through the fallback that reads it, and fixed by removing the assignment entirely — the screen never needed the mode, since it opens over the capture tabMeraPeon, a supervisor's handset in the field
applies to
debugging mobile ui ux
source
commit:06503292
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
Resolving names to ids in a capped query silently drops the rest of the resultMeraPeon

An operator search resolved names to user ids in a separate query capped at fifty, then filtered by that list. On more than fifty people sharing a name it kept whichever fifty came back and quietly missed the others.

id
a-two-stage-query-with-a-cap-loses-the-answer
verified
Caught by a test written against the boundary rather than by inspection; the same commit also corrected a timezone bug where a typed local time was being stored as if it were UTCMeraPeon search and corrections
applies to
pagination postgres verification
source
commit:604be6ff
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
More than half of every capture reached the register with no plate, and two UI fixes did not move itMeraPeon

The record commits the moment the photograph is taken, so a capture nobody finishes syncs anyway — with a photo, a time and no plate. 302 of 566 real entries, and the rate did not move across four releases including two fixes aimed at it.

id
an-affordance-that-reads-as-optional-loses-the-data
verified
Proven by sync latency rather than by inspection — saved records land in a median of one second on the immediate nudge; the plateless ones land in 21, because they wait for somebody else's save to drain the queue. Nobody had pressed save on them.MeraPeon production, 566 entries across four releases
applies to
data-import offline-first ui ux
source
commit:1505ec29
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
A deletion that filtered on a vestigial column removed zero objects and reported successMeraPeon

The erasure path filtered on a column that had become vestigial when the design moved photographs onto their own primitive. It destroyed zero objects while reporting a clean erasure — and it only surfaced because the test used a real object in a real bucket rather than a fixture.

id
an-erasure-that-destroyed-nothing-and-reported-clean
verified
Found by a test that presigns, uploads and destroys a genuine object in a genuine bucket; against a fixture the same code reports successMeraPeon, the erasure launch gate
applies to
aws-s3 privacy testing verification
source
commit:56a9bab3
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
A test suite with real cost and side effects runs when asked, not on every iterationMeraPeon

An end-to-end suite was being run as a standard pre-deploy step. It takes minutes, makes a real paid model call, and writes a new tenant into the shared development database on every run — and it gets slower as the catalogue grows. The owner interrupted a ship to stop it.

id
an-expensive-suite-is-not-a-default-step
verified
Corrected independently on two different products — a Playwright suite before deploys, and an XCUITest suite after code changes — both by the owner, for the same reasonsprocuresherpa and the iOS client, 2026-07 to 2026-08
applies to
ci cost playwright testing
source
memory:e2e-only-when-asked.md, memory:vcos-ios-no-auto-e2e.md
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
Requests that never arrive, with no exception and no log, read as a wrong URLMeraPeon

Cleartext HTTP has been blocked by default since Android 9 and the block is silent — no catchable exception, no obvious log. Requests to a local development server simply never arrived, which reads as a wrong address or a firewall rather than as a platform policy.

id
cleartext-http-is-blocked-and-nothing-throws
verified
Fixed with a network security config scoped to the debug source set only, permitting the emulator loopback addresses; the release build keeps the default and still refuses cleartextMeraPeon Android client against a local backend
applies to
android auth debugging mobile
source
commit:c2bc64c9
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
Crypto-shredding is defeated by one copy of the source data in version controlMeraPeon

The spreadsheets a legacy import read held 13,682 and 14,301 phone numbers in plaintext, tracked in git. The same numbers in the database are encrypted under per-subject keys, so an erasure destroys the key and the number becomes unreadable everywhere at once — except in the repository.

id
encrypted-in-the-database-and-plaintext-in-git
verified
Untracked and confirmed still present in history back to the first commit, which is the point — removal from the tree does not remove them from a cloneMeraPeon, private repo, 2026-07
applies to
git privacy repo-hygiene tenancy
source
commit:e128a5e8, commit:cb235e11
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
A background worker that returns failure for "no signal" abandons the work foreverMeraPeon

A sync worker returning a terminal failure for the offline case would have left a guard's records sitting on the device with nothing ever attempting them again — on an offline-first product whose entire premise is that nothing is lost.

id
offline-must-never-be-a-terminal-failure
verified
The decision was extracted into a pure function so it could be tested without a platform context, and tested before the worker was wiredMeraPeon Android, WorkManager sync worker
applies to
android background-job error-handling offline-first
source
commit:ed28418c
as of
2026-08-05
A plan presented as prose is not a plan, and the format is not a formalityMeraPeon

A plan was presented as prose rather than through the defined artefacts. It recurred the same day, with the correcting memory already loaded — a research question was answered in prose and closed with a plain multiple-choice prompt.

id
plans-go-through-the-harness-not-into-chat
verified
Corrected twice on the same day by the owner, the second time with the rule already in context — which is what makes the recurrence the finding rather than the original mistakeMeraPeon, 2026-08-04
applies to
planning writing
source
memory:merapeon-planning-artefacts.md
as of
2026-08-05
A random fixture against a unique constraint works forever, then fails one run in fourMeraPeon

Test fixtures minted users from 90,000 possible random numbers against a unique constraint, in a table nothing cleans between runs. At 636 accumulated rows and ~39 per run, roughly one run in four died — and the failure landed in whichever test happened to draw the collision.

id
random-fixtures-are-a-time-bomb-with-a-fuse
verified
Diagnosed from the birthday-collision arithmetic against the accumulated row count, which predicts the observed one-in-four rateMeraPeon backend suite
applies to
gate postgres testing
source
commit:999f1971
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, sherpa, sherpa-private, stack-template
The verification id lived only in memory, so the code arrived for a challenge the app had forgottenMeraPeon

Anything destroying the activity between the SMS being sent and the code being typed threw away the verification id and returned the user to the number screen — holding a perfectly good code for a challenge the app no longer had. Sending again produced a second SMS and the same result.

id
state-that-only-lives-in-memory-dies-with-the-process
verified
Fixed by persisting the pending verification across process death; the failure is specific to a sideloaded build, where the platform falls back to a slower web challenge that widens the windowMeraPeon Android, phone sign-in
applies to
android auth mobile offline-first
source
commit:bd5cee18
as of
2026-08-05
reaches
CapitalCoda, nismpass, procuresherpa, stack-template
The platform infers the package-manager version from the lockfile at the project root, not from your configprocuresherpa

Three consecutive builds failed with "Ignoring not compatible lockfile" then "Headless installation requires a pnpm-lock.yaml file", because the project's configured root directory had no lockfile of its own and the platform inferred a different package-manager version.

id
a-lockfile-decides-which-package-manager-runs
verified
Resolved by ensuring a lockfile exists at every configured root directory; the same trap is now written into the template's bootstrap so a new project cannot hit itprocuresherpa, two Vercel projects, 2026-07-29
applies to
build deploy pnpm vercel
source
memory:procuresherpa-new-project.md
as of
2026-08-05
reaches
CapitalCoda, MeraPeon, nismpass, sherpa-private, stack-template
When disclosure is unlawful, no cross-tenant read path is the requirement — and a WHERE clause does not satisfy itprocuresherpa

The agent core was to be carried across from a product using ordinary firmId row-scoping, into one where it is illegal for the customer to disclose the data at all. Porting that model would have satisfied the code review and breached the constraint.

id
tenancy-is-a-legal-decision-before-a-technical-one
verified
Traced to the regulatory source rather than assumed — device purchase agreements carry manufacturer confidentiality clauses, GAO-12-126 names them as blocking hospitals from showing prices to their own surgeons, and the FTC/DOJ healthcare information-sharing safe harbor has been withdrawn since July 2023, so every case is case-by-caseprocuresherpa, tagged MUST in the PRD as the constraint that determines the architecture
applies to
planning privacy tenancy
source
memory:tenancy-is-the-architecture.md
as of
2026-08-05
reaches
CapitalCoda, MeraPeon, nismpass, stack-template
Installing a plugin you are actively editing gives you a version-pinned copy that never updatessherpa

A plugin installed from a marketplace is copied into a version-pinned cache, and update no-ops when the version string has not changed — so edits to the source never reached the loaded copy, and three consecutive releases were undeliverable to anyone already installed.

id
the-plugin-loads-from-a-symlink-not-an-install
verified
Proved by planting a marker in a skill file and confirming update reported "already at the latest version" with the marker absent from the cache; the symlink route reflected the same edit immediatelybrij-coda/sherpa and brij-coda/sherpa-private, 2026-08-05
applies to
deploy release verification
source
memory:harness-loads-from-symlink.md, session:2026-08-05
as of
2026-08-05
reaches
CapitalCoda, MeraPeon, nismpass, procuresherpa, sherpa-private, stack-template
Deployment protection can cover the deployment URL and miss the production aliassherpa-private

A dashboard naming three clients' incidents was deployed with Vercel deployment protection set, and served in full to an anonymous request for the few minutes it took to check. The mode that was accepted protected preview deployments and the long unique deployment URL; the short production alias was public the whole time.

id
protection-that-misses-the-production-alias
verified
Two anonymous curls with no cookies. The unique deployment URL returned the Vercel login page and none of the private strings; the production alias returned the real 84,887-byte page with four of them. Project deleted, both re-checked.Vercel Pro, ssoProtection deploymentType prod_deployment_urls_and_all_previews
applies to
deploy privacy vercel verification
source
session:2026-08-05-dashboard-move
as of
2026-08-05
reaches
CapitalCoda, MeraPeon, nismpass, procuresherpa, stack-template

retired

A superseded artifact stops loading the moment its replacement lands, and the pair is written in one commit. Two live artifacts giving opposite instructions is what this prevents: whichever the reader reaches first wins, silently, and nothing announces that the other one exists.

artifactoriginreplaced by
RETIRED — release notes with every shipMeraPeonrelease-notes-on-medium-and-major
RETIRED — the control plane needs the ownerprocuresherpacheck-for-a-cli-before-saying-dashboard

reach

What recall would surface on each project, excluding the one it came from. This is potential, not use — the ceiling the number at the top is climbing towards, and not a substitute for it. 9 artifacts are left out as universal practice rules: no file tree exhibits "writes release notes" the way it exhibits Vercel, so scoring those by stack facts measures the instrument rather than the artifact.

artifactprojects
the-plugin-loads-from-a-symlink-not-an-install6
random-fixtures-are-a-time-bomb-with-a-fuse6
an-expensive-suite-is-not-a-default-step6
a-proof-harness-that-proves-nothing6
a-gate-that-walks-only-part-of-the-tree6
a-gate-that-cannot-run-must-fail6
a-gate-nobody-can-run-is-reported-as-green6
a-deploy-that-fails-inside-a-successful-release6
a-build-skip-that-reads-a-shallow-clone6
a-baseline-that-pins-one-machines-paths6
validate-a-model-id-before-shipping-it5
the-version-lives-in-the-file-not-the-commit5

Snapshot taken 2026-08-05 — reach needs the other repos checked out, so it is measured where they are and read here from reports/reach.json. 5 reach only their origin, which is not necessarily wrong: an artifact that applies only where it came from is a project note, and the layer is not what it needed.


using it

One line starts a project. It creates the repo from the template, bootstraps it, binds it here so promotions out of it are possible, and writes the brief where prd will read it when the next session opens.

any session
Acme · acme.com · PRD: ./docs/prd.md

Inside a project the 5 skills load when the work matches them: recall surfaces what applies here, extract turns an incident into an artifact, promote generalises one into the public harness, and inventory says what exists.

Binding is the step that gets skipped. A project missing from projects.json resolves to unbound — harmless while every artifact is shared, and fatal the first time you promote a learning out of it, because the gate requires origin_project to be a known key. start-project.sh does it, and recall prints the command whenever it meets an unbound directory.