What was built, and when.
One line per functionality, in UTC, from BUILD_PERIOD.md in the repository. Newest first.
23 Sep
- V3-08Last Call reminders: a Session Max borrower can ask the Credit page to notify them when Last Call opens and five minutes before it closes
- V3-07Kerb Terms and its four consumers across the site: Home, Developers (SDK, REST, Solidity with a live KerbQuote read, Agents with the x402 call and the MCP config), Proof, Credit, README
- V3-06The OKX DEX cross-check as a record: one exit check per mainnet post, an Exit check panel with a 72 h strip on each asset, counts on Proof
- V3-05KerbQuote and KerbMarkFeed, read-only consumers of Kerb Terms any X Layer contract can call; valuation equals KerbCredit's to the wei (fuzzed, and live on testnet); deployed and Sourcify-verified on testnet, mainnet fork tests green
- V3-04Every term change explains itself: an exact attribution of each posted Carry, Session Max and debt ceiling move into horizon, volatility, exit cost, depth and the attester's loosening cap, from the two posts' own input bundles; Why these terms and What changed on each asset, a line under each Credit mode card, a hover card on the Board
- V3-03Kerb for Agents: paid credit and exit checks over x402 on X Layer (USDT0, one cent, OKX facilitator), answered from the posted terms and the report recomputed from the posted bundle, with collateral valued exactly as KerbCredit does; a free MCP server with six read-only tools; settled calls recorded append-only
- V3-02The demo keeper runs: one Session Max position on kHKEXCx every demo cycle, curable at each demo Last Call, decided from chain state only (a restart never opens twice, a pending nonce blocks every send), with its status at
/v1/credit/1952/keeper; a stranger cured it through the real Credit page - V3-01First paint is never shown stale: live pages date their data by the payload's own stamp and refresh at once when it is old, a guard dims values with "Refreshing live data" or "Last known" with Retry, countdowns never run from the past, every calendar transition has a word, and
kerb-web-warmerkeeps each live route regenerating; first paint went from 2 h 17 m old to under 35 s - V3-00V3 started: the V3 pack under
docs/v3/, AGENTS.md section 13, a truth sweep of public copy (bundles are published, not pinned; the repo is public; mainnet terms are denominated in USDG) andscripts/claims-check.sh, a denylist of unsupported claims that fails CI
22 Sep
- V2-11Kerb V2 live on www.usekerb.xyz (cut over 16:00 UTC, tag
v2.0.0): the full E2E suite passes against production, Lighthouse mobile scores 94 to 100 on every route, and a real-user walkthrough of every page at three widths in both themes was run on the live site with its findings fixed the same hour. Releases now swap with no dropped requests - V2-11Hardening begun: E2E is a required CI job against a production build and recorded real API responses; axe on every route in both themes (zero serious or critical); a link sweep and a dead-button sweep (277 buttons, none dead); every route incrementally regenerated instead of rendered per request; a rate limit on the positions feed; a secret scan of the whole history. Report #1 gained a dated appendix of executable depth in USDG; Report #2's generator and its captures are scheduled for Thursday
- V2-08Credit, the hero workflow, proven in real browsers on X Layer testnet: four runs with fresh wallets (one keyboard only, one in Day), each a Session Max borrow cured by a stranger from the public Curable now table during the demo Last Call, then repaid and withdrawn; every transaction receipt checked and the latest run shown on /proof. The runs found and fixed three real bugs: gas estimates made in the block of the last interest accrual ran out of gas, a MAX that rounded a balance up past what was deposited, and a hydration mismatch from the shared wallet config
- V2-10Methodology as a reference with a contents rail: the regime ladder with the live rule highlighted, the real impact curve, the mark waterfall, KTS-0.2 margins broken into multiplier, vol, gap and horizon, the replay, the covenant timeline, and the parameter set as wrapping grouped lists (nothing off-screen at 390). Proof opens on an eight-tile status matrix;
/v1/proofnow decodes the Builder Code of every recent post and recomputes the latest report from its stored bundle, field by field against the chain. Developers: SDK, REST and Solidity tabs with live responses, the endpoint table generated from docs/API.md, ABIs to download - V2-09Research rebuilt: a forest-band index on The Record with the latest report as a featured card and a Scheduled row for Report #2 counting down to its publication; each report page shows liquidity change as sorted diverging bars (asset pools and route legs apart), the window against both markets' sessions with the hole in the record drawn where it actually is (new read-only
/v1/market-time/:id/gaps), findings as claim and evidence, and an appendix with L labelled as protocol units - V2-05..07The time components (SessionRail in four variants, MarketClocks, the Tape), the editorial Home on the operator's Kerbstone plates, the Board and the Asset page rebuilt, and The Record, The Standard and Fog placed on Research, Methodology and the 404; Playwright E2E for the rail transition, the Board filter, sort and row link, the Asset tabs and copy buttons
21 Sep
- V2-04Kerbstone foundation on staging: the design tokens as CSS layers, General Sans, Instrument Serif and IBM Plex Mono actually loaded, Night, Day and Market-time themes painted before first paint, a new header with a live status pill, a wallet sheet listing EIP-6963 wallets with OKX Wallet first, a mobile drawer with a focus trap, a footer with the market clocks, an error map that turns every contract error into a sentence with its numbers, toasts and a transaction stepper, 20 UI primitives, 404, error and loading routes, per-route metadata and social cards, and 308 redirects from /market and /reports to /credit and /research
- V2-02API for the V2 frontend: every Board row now carries its fixed liquidation threshold read from chain, its market and exchange coordinates, the next transition, the Last Call window, the KTS version and margins and a 24-hour depth sparkline, with a Board summary;
/v1/tape,/v1/stats, the demo clock as a schedule, and a feed of every open credit position found from the market's own events, curable first.docs/API.mddocuments every endpoint with a real captured response - V2-01KTS-0.2 live on mainnet and testnet: Carry and Session Max are now the fixed liquidation threshold minus a margin tied to the horizon each mode must survive, so they move with market time. Replayed over 3,286 real bundles and posted 1,357 times through the real mainnet KerbTerms on a fork before going live; every 0.1 report still verifies under 0.1
- V2-00The repo reads like a company's: planning documents under
docs/planning/, the standard and the architecture underdocs/, private strategy notes out of the tree; no em dash anywhere in public copy, enforced in CI; GitHub Actions CI for TypeScript and Solidity; MockUSDG, KerbClockDemo, both mirrors and KerbCredit verified on Sourcify (exact match), so every Kerb contract is now verified; the mirror liquidation threshold explained in the API and the architecture; the pinning gap stated in words - V2-KV2 started: the audit, the Kerbstone design system, KTS-0.2 and the phase prompts committed under
docs/v2/, AGENTS.md section 12 appended, and a staging deployment for V2 at v2.usekerb.xyz built byscripts/deploy-web.sh, which compiles each release in its own worktree and only swaps it in after it answers on a spare port - K-43Pinata hit its free-plan limit after ~1,800 pins in a day, so bundles stopped pinning and
/proofwas reporting "pinning is not configured" when it was configured and blocked. The attester now writes every bundle to disk under its owninputsHashbefore posting,/v1/bundle/:hashserves it, andkerb verifyfalls back to the API when no IPFS gateway has the CID./proofcounts how many bundles are actually retrievable and says which are not and why. Pinning backs off for 30 minutes when the service refuses - K-41The Session Strip now appears on every page, as ARCHITECTURE.md section 9 specifies. It was on three of nine: the landing page, the Board and the asset page. Pages that lead with their own asset render it themselves; the rest get a compact one led by whichever asset currently carries the most capacity, and it renders nothing at all rather than an error if the clock cannot be read
- K-33bCure executed from the UI on X Layer testnet: a second account, in a real browser, brought a Session Max position back to its Carry target. Transaction 0x91c40151, block 41514829, gas 153,904, LTV 60.00% to 55.013% against a 55% target, and the calldata carries Builder Code
kt0hl6xyhlx8xmt - K-38b
/reportsindex, and the mirror relay moved into PM2 askerb-mirror-relayon a 5-minute loop: a stale mirror report correctly makeseffectiveTermsunusable, which stops borrowing, and on a demonstration market that just reads as broken - K-34bThe KTS parameter set is served from the live params file at
/v1/paramsand rendered as a table on/methodology - K-31bPhase 6 gaps closed: the ERC-8021 Builder Code suffix is now attached to every transaction the web app sends, not only the attester's; supply and withdraw for lenders; a positions list; a position card with health against the fixed threshold, the covenant target, a cure countdown and a plain-language sentence saying what happens next and what the borrower can do about it; the mode choice reframed as one plainly-worded question with Carry and Session Max side by side in loan-asset amounts, not just percentages
- K-38Market-Time Report #1, generated from the observation store by
pnpm --filter @kerb/engine market-time-reportand published at/reports/1: 42.25 hours, 35,130 pool readings across 15 pools, in-range liquidity fell on 7 of 10 asset pools while the underlying markets were shut (largest fall MIXUx -49.12%, largest rise SLVx +4.94%). The 3h16m hole in the record is reported, not interpolated across - K-35
/v1/termsnow carries the pinned bundle's CID, gateway URL and verify command, and the asset page links the inputs hash straight to those bytes: Board, asset, bundle: a displayed number to its exact inputs in two clicks - K-34
/methodology: KTS-0.1 stated rule by rule and worked through on whichever asset currently carries the most capacity, using live measured numbers. The specification's own worked example is marked "not measured" and is deliberately not reproduced - K-39
kerb verify <inputsHash>now works from a chain hash alone: it finds the CID the bundle was pinned under, fetches those bytes from IPFS, checks they hash to that CID, recomputes the whole report, and compares every value against what was actually posted on chain. A value the attester clamped tighter into the onchain guardrails is named as such rather than reported as a mismatch - K-36Slither 0.11.6 over all contracts: 67 results, none High.
SECURITY.mdrecords the disposition of every finding, the key model, and the known limitations; raw output committed underdata/security/ - K-29Full credit lifecycle executed on X Layer testnet: supply, collateral, borrow at Session Max, Last Call opens on the compressed clock, permissionless cure by a second account, repay, withdraw. Cure computed 1202.094527 mUSDG against 1202.092123 executed; LTV 64.1667% to 55.00005% against a 55% covenant target
- K-31
/marketpage: pool state, each mirror with its regime, Credit Mark, Carry and Session Max ceilings, the FIXED liquidation threshold, cure and default bonuses, and a permissionless position lookup showing health and the exact cure amount. Testnet, mirror collateral and the demo clock are stated at the top, not buried - K-30
/v1/credit/:chainand/v1/credit/:chain/position/:user/:assetId: market state, the fixed liquidation threshold, the covenant target, health, and the exact cure amount, read from chain rather than from the indexer - K-29Credit plane deployed to X Layer testnet:
MockUSDG(rung 2, labelled),KerbClockDemo,kKOxandkHKEXCxmirrors,KerbCredit; both mirrors listed with a fixed liquidation threshold and the real mainnet Credit Mark relayed onto them by the attester - K-26106 contract tests: the full QA matrix for contracts, eight invariants under a guided handler (16,384 calls per run), deterministic handler-coverage tests so no invariant is vacuous, and fork tests against the real xStocks V2 wrapper and the live mainnet KerbTerms on X Layer 196
- K-25
KerbMirror(testnet collateral, capped faucet, name and symbol that say MIRROR TESTNET) andKerbClockDemo(one compressed trading week per hour,DEMO_CALENDARon construction, testnet only) - K-25
contracts/KerbCredit.sol: isolated market, shares-based accounting both sides, two-slope kink interest with a reserve factor, Carry and Session Max modes, the cure covenant, default liquidation at a FIXED liquidation threshold, guardian pausing that can never block repay, cure, liquidate or a withdrawal to safety
20 Sep
- K-24Deployed at https://www.usekerb.xyz behind Caddy with TLS, under PM2 as
kerb-web; the public API is live at https://api.usekerb.xyz - K-24
apps/web: the Session Strip (trading week, live cursor, Last Call window, one orchestrated motion on regime change, instant under reduced motion),/,/board,/asset/[symbol]with the impact curve drawn from real observations, and/proof. Both themes first class, screenshots at 390 and 1440 reviewed and defects fixed - K-23Fixed a 1e12 error in
/v1/terms: debt ceilings and executable depth are posted in loan-asset units (USDG, 6 decimals) and were declared as WAD, so every SDK consumer would have read them 1,000,000,000,000 times too small. Regression test added against the board's own numbers - K-23
/v1/clock,/v1/reportand/v1/proofon the public API: session geometry from the same resolver the onchain KerbClock is equivalence-tested against, the full Market-Time Report recomputed from current observations, and a proof surface assembled entirely from live state - K-22IPFS pinning live (Pinata); a probe confirmed the pinned CID is byte-identical to the CIDv1 the engine computes locally. Registered Builder Code
kt0hl6xyhlx8xmtreplaces the placeholder on every transaction - K-22Recovery after the VPS OOM kill: all five kerb services restarted and persisted into the PM2 dump,
oom_score_adj=-800so the recorders are never the kernel's victim, 8 GB of additional swap,vm.min_free_kbytesraised - K-21
apps/indexer(TermsPosted and RegimeChanged into Postgres, idempotent by tx hash, reorg-aware by block hash, restartable from a stored cursor),apps/api(Fastify: /v1/board, /v1/terms, /v1/reports, /v1/bundle, /health, 15s board cache, provenance on every value),packages/sdk - K-20X Layer mainnet risk plane live: KerbClock and KerbTerms deployed to chain 196 with operator approval, Sourcify verified, calendars and guardrails loaded, attester posting all ten assets every five minutes with Builder Code attribution
- K-08Depth cross-check live: OKX DEX v6 aggregator quotes at the notional ladder every 5 minutes (append-only
obs_quote), quote-implied impact measured against the same mid as the simulation, and the conservative value taken when divergence exceeds the configured maximum. Executable depth moves to rung 1 - K-18Builder Codes (ERC-8021): data suffix on every transaction Kerb sends, plus a decoder and a round-trip test; decoded from real onchain calldata
- K-18
apps/attester: builds the report, pins the bundle, signs EIP-712 with the attester key, posts with the poster key every 5 minutes and on every regime change, skips unchanged reports, holds increases during the loosen cooldown, hard-stops on low gas - K-17Deployed KerbClock and KerbTerms to X Layer testnet (1952), source verified on Sourcify (exact match), calendars and guardrails loaded onchain
- K-16
contracts/KerbTerms.sol: EIP-712 signed reports, attester set, absolute guardrails, monotonic observedAt, tighten-fast loosen-slow,effectiveTermsusability; every revert path in AGENTS.md section 9 tested - K-15
contracts/KerbClock.sol: onchain calendars, holidays, asset-to-market mapping, expiring halt flags, session and transition views; equivalence with the TypeScript resolver on 1,000 timestamps across XNYS and XHKG - K-14Input bundles: canonical JSON, keccak256 inputsHash, deterministic IPFS CIDv1, Pinata pinning when configured;
kerb reportandkerb verify - K-13Regime machine with the KTS 4.2 resolution order and the 4.3 tighten-fast loosen-slow asymmetry
- K-13KTS capacity: stress capacity, debtCeiling = k*C(1%), position cap, Carry and Session Max at their two horizons, guardrail clamping recorded
- K-12Underlying daily bar ingestion (append-only), gap quantiles by horizon, 20d/5y volatility scaler with clamping, and a conservative universe fallback for assets without five years of history
- K-11Credit Mark: reference median with FX conversion, pool price along the whole path, TWAP from pool observations, dispersion guard, regime haircuts, band, provenance on every component; legacy v1 wrappers rejected
19 Sep
- K-08
apps/enginedepth assembly from live observations with staleness, dust and route exclusions;pnpm --filter @kerb/engine depth-report - K-10Clock resolver: session, next transition, next weakening, next reference close, cure window, horizon H; pure function of (market, time)
- K-09
packages/calendar: XNYS, XNAS, ARCX, XHKG (lunch break first class, half days), XCOM (CME Globex metals) for 2026 to 2027, DST via the IANA database; holiday overrides cross-checked against Pyth's published market-hours schedules - K-08OKX DEX quote client (signed, v6) and quote-curve capacity with the min-never-max cross-check rule; runs on rung 2 until credentials exist
- K-08Multi-hop paths (asset -> xETH -> USDG, asset -> USDC -> USDG) with compounded impact and recorded path; venue aggregation with the fragmentation factor; exclusions recorded with reasons
- K-07
C(i)by bisection with the guarantee impact(C) <= i; impact curve at the KTS default ladder - K-07
packages/v3math: exact bigint Uniswap v3 exact-input simulation walking initialised ticks from slot0; matches QuoterV2 to the wei on 150 quotes over 15 real X Layer pools at one pinned block; refuses to step into unobserved bitmap words - K-06Collector live on the VPS under PM2 from 06:37 UTC,
/healthwith per-source ages and row counts, freshness alarm at 5 minutes - K-05
apps/collector: pool (60s), price (30s) and multiplier (10m) loops writing append-only rows with source, timestamp, keccak content hash and raw payload blob; DB triggers reject UPDATE, DELETE, TRUNCATE; fixture mode by default,KERB_LIVE=1for live - K-04
packages/adapters:AssetAdapterinterface andXStocksAdapter(issuer API + token and wrapper contracts), Uniswap v3 pool snapshot reader pinned to one block, Yahoo and Pyth reference clients - K-03Asset discovery: ten campaign pools resolved from the xStocks issuer API and the Uniswap v3 factory, each confirmed onchain (token0, token1, fee, tickSpacing, slot0, liquidity, factory);
config/assets.json - K-02X Layer mainnet (196) and testnet (1952) viem clients, explorer link helpers,
pnpm chain:ping - K-01
packages/types: shared decimal module (decimal.js, no floats on value paths), provenance labels,Regimeenum matching KTS-0.1 4.1,assetId = keccak256(abi.encode(chainId, token)), canonical JSON - K-01pnpm workspace (Node 22, TS strict, exactOptionalPropertyTypes), apps and packages scaffold, Foundry project with forge-std, ESLint, Vitest,
.env.example