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
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.
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.
| project | repo | artifacts | with code | public |
|---|---|---|---|---|
| CapitalCoda | brij-coda/VCOS | 41 | 0 | 2 |
| MeraPeon | brij-coda/merapeon + brij-coda/aipark | 18 | 0 | 1 |
| procuresherpa | brij-coda/procuresherpa | 2 | 0 | 0 |
| sherpa-private | brij-coda/sherpa-private | 1 | 0 | 0 |
| sherpa | brij-coda/sherpa | 1 | 0 | 0 |
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.
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.
| artifact | origin | replaced by |
|---|---|---|
| RETIRED — release notes with every ship | MeraPeon | release-notes-on-medium-and-major |
| RETIRED — the control plane needs the owner | procuresherpa | check-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.
| artifact | projects |
|---|---|
the-plugin-loads-from-a-symlink-not-an-install | 6 |
random-fixtures-are-a-time-bomb-with-a-fuse | 6 |
an-expensive-suite-is-not-a-default-step | 6 |
a-proof-harness-that-proves-nothing | 6 |
a-gate-that-walks-only-part-of-the-tree | 6 |
a-gate-that-cannot-run-must-fail | 6 |
a-gate-nobody-can-run-is-reported-as-green | 6 |
a-deploy-that-fails-inside-a-successful-release | 6 |
a-build-skip-that-reads-a-shallow-clone | 6 |
a-baseline-that-pins-one-machines-paths | 6 |
validate-a-model-id-before-shipping-it | 5 |
the-version-lives-in-the-file-not-the-commit | 5 |
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.
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.