One human, twenty repos: how hosaka is architected
Series: How hosaka is built, Part 1 of 2. Part 2 is How agents build hosaka. Audience: engineers curious how a solo-operator + AI-agent fleet designs and runs a real multi-repo data platform. As of: early July 2026. Live-system numbers are from a deterministic audit run on 2026-06-29 unless noted. Names of repos and public data sources are real; infrastructure identifiers are deliberately generalized. The repositories described here are private (the SDK is the one public exception), so file and path references are illustrative rather than links.
Subscribe free
1. What hosaka is
Hosaka is a music-intelligence factory built from free, lawful, public data. Operated by one human and built almost entirely by AI agents, one agent per repository. Its job is to answer six questions about every record ever pressed:
- What exists? The catalogue (a monthly CC0 Discogs data dump: 16.3M releases, 11.4M artists, 65.3M per-release credits)
- What's said about it? An editorial corpus (579K articles, 41 GB, crawled from ~50 music publications)
- Who plays it? The live circuit (DJ tracklists, radio shows, festival lineups, event listings)
- Who owns and wants it? Collector behavior (publicly visible collections, wantlists, seller inventory)
- Who wrote it? Rights genealogy (writer/composer/publisher claims)
- Where was it used? Placements (soundtracks, film/TV usage signals)
Each question has an owning repository, and the raw material is public, no-paywall data (the catalogue is CC0-licensed; the crawlers' legal bright lines are CI-enforced in §7). The answers join into per-artist and per-label dossiers served through a metered API at the consumer edge. Everything runs on a deliberately small footprint: an AWS Fargate task fleet driven by ~42 scheduled rules, one shared Postgres instance, and (this is the part people don't believe) an LLM tier that is one consumer GPU workstation in a house.
Two things make the architecture worth studying:
- The constraint set is honest. No SRE team, no on-call rotation, no meetings. Every mechanism has to be operable by one person plus stateless agents, which rules out most textbook answers (service meshes, event streams, schema registries) and forces cheaper inventions that are interesting in their own right.
- The engineers are agents. Most code is written by per-repo Claude agents in sessions that begin with total amnesia. That changes which failure modes dominate, and therefore what the architecture defends against. Hosaka's signature bug class is the coordination bug: producer and consumer each individually correct, written by different agents with no shared memory, silently drifted from each other. The architecture is, to a large degree, a machine for preventing exactly that.
(A note on the names: the vocabulary (hosaka, Loa, simstim, flatline) reads as Gibson's Sprawl by way of vodou; "carrefour," the coordination repo, is named in its own docs for the loa of the crossroads.)
2. The fleet, in three rings
About twenty repositories (counting every org checkout including scaffolds and SDK mirrors, as of early July 2026), in three rings around a shared data substrate:
Ring 1: the heavy producers. These own acquisition pipelines and publish the substrate everyone else builds on.
| Repo | Owns | Scale markers |
|---|---|---|
| ridden | The CC0 Discogs catalogue substrate + the editorial corpus + LLM extraction + the cross-source identity spine | 579K articles; 48 hand-written source clients; 162 forward migrations; ~64K published artist clusters |
| seen | The live circuit: tracklist/lineup harvesting, a four-block matcher against the catalogue, the performing entity identity keyspace | 253 migrations; ~26 apps (~20 per-source crawlers); 48 published contract surfaces |
| mirror | Collector behavior (Discogs public state) + cross-source identity stitching + satellite enrichment (Bandcamp, MusicBrainz, Wikidata) | 211 migrations; 119 published tables; 3.1M name-minted bridge edges |
Ring 2: the thin verticals. Single-axis repos that bootstrap cheaply on the producers' published surfaces: deadwax (vinyl pressing provenance, matrix/runout etchings mined from the CC0 dump), hearsay (social-signal scouting), ledger (rights claims, Python), tonearm (audio features), sync (usage/placement). A new vertical here can need no crawler and no ETL fleet at all. Just a consumed.yaml pinning another repo's published tables, a read-only database role, and contract tests. Deadwax is the purest case: it exists because its "hardest to harvest" signal was already sitting unparsed in a dump the fleet downloads monthly. (Others bring their own narrow harvesters (open rights data, placement databases, social firehoses) but never re-ingest what a producer already owns.)
Ring 3: the product edge. crate is the API-first "dossier gateway": it composes ~71 producer tables (28 mirror, 28 seen, 15 ridden) into cluster-keyed artist/label dossiers behind a metered API key, with five pricing tiers and Stripe billing wired. cube is a thin public visualization page. crate-sdk packages the typed client, published from a scrubbed one-commit public mirror that is, deliberately, the fleet's only public repository (nothing that ever transited the agent working repos can leak via git archaeology). taste is the newest repo and the deliberate inverse of crate: it ingests people data (listening histories) in a fully isolated stack and joins the fleet through crate's public API with an API key, like a stranger. To be honest about maturity: the public web surface went live days before this was written; nothing here should be read as implying paying customers yet.
Around the rings sits a governance-and-infra layer: carrefour (the cross-repo contract library and RFC forum in §6), box (the GPU workstation's config-as-code in §10), and a set of nascent coordination repos (scribe, a cross-repo drift watcher; switchboard, chartered inter-agent mailboxes; dix/runtime, an agent-orchestration and operator-comms layer). Part 2 covers those.
3. The core tension: a microservices org on a monolith database
Here is the sentence that explains most of hosaka's architecture:
The org topology is microservices-shaped (one agent per repo, agents never cross repo lines) but the data substrate is monolith-shaped: one shared Postgres where every schema is reachable from every role.
That mismatch is productive (any repo can JOIN against 24 GB of catalogue for free) and dangerous (the database will happily permit what the architecture forbids). In May 2026 it produced the fleet's formative incident, known internally as seen#205: one repo designed a cross-schema UPDATE into another repo's table against a misremembered shape. The design assumed a master-keyed table, but the real table (had anyone read its migration) was pair-keyed. The database would have accepted the write without complaint. It was caught only after the PR was opened.
The response was not to patch the aggregator. It was to treat the incident as an architectural failure and ship a fleet-wide pattern in a single day.
4. Contracts: producer publishes, consumer integrates
The pattern is three rules, stated in ridden's own docs: producer owns its tables; consumer owns its integration; no cross-schema writes, ever.
Concretely:
- Every repo lists what it publishes in a committed
contracts/published.yaml: table shapes, invariants, grants, consumers, and the migration that created each grant. The file must be updated in the same PR as any change to a published table. (Same-PR coupling is the enforcement trick: memory that must ship with the change can't lag it.) - Every consumer lists what it reads in
consumed.yaml, pinned to the producer's file by commit SHA. Crate goes further: a CI test greps everyFROM/JOINin its data layer and asserts two-way parity with the registry. The contract file cannot lie. - Grants are the API. In a shared-database world, an "API change" is a
GRANT SELECTmigration plus a YAML update in one PR. The consumer's ask ritual: open an issue on the forum repo, producer ships the grant migration, consumer pins and adds a contract test. Migration headers read like API changelogs. - Integration lives on the consumer's side. A consumer's analyzer reads the producer's tables and materializes what it needs into its own schema. Nobody pushes into anyone else's tables.
What makes this stack interesting is that it's five independent defense layers, each catching a different failure mode, each nearly free:
| Layer | Catches | Cost |
|---|---|---|
| Postgres grants (SELECT-only per consumer role) | runtime writes | free: the DB enforces |
A NEVER rule in the agent's context file | bad designs during agent sessions | a paragraph |
| A mandatory pre-flight checklist ("read the consumer's actual migration files; do NOT trust memory") | stale-memory designs | ~15 min/session |
| A CI grep for cross-schema writes | code that slips past design | one script |
| Consumer-side contract tests + SHA pins | producer drift | a test file |
Notice the second layer. When your engineers are LLMs, design-time context is an enforcement point: a prompt rule sits in the defense-in-depth table alongside database grants, because it catches the one failure class (plausible-but-wrong designs from decayed memory) that no runtime control can reach.
The pattern is also expressive enough to encode its own exceptions and its own inverse:
- The one sanctioned cooperative write: two services share a third-party API rate limit (60 rpm) through a single Postgres row. A token bucket with
SELECT … FOR UPDATEand inline refill math. The foreign role holds an UPDATE grant scoped to exactly two columns. The exception is documented in the contract file, bounded, and requires a forum issue to replicate. No new infrastructure; a one-page signed quota contract (reserved floor, dynamic burst, starvation protocol) does the governance. - The hosted namespace (the pattern run backwards): crate's billing/admin schema physically lives on ridden's Postgres. The host provisions the schema and writer role, the guest owns all DDL and writes, and CI guards on both sides forbid each repo from touching the other's tables. Why? The alternative was a dedicated database instance for under 100 admin writes a day plus a low-rate fire-and-forget usage-event stream. The 2026-06-29 audit found the whole grants layer intact: 14 consumer roles live, the CI guard passing with a zero-length allowlist.
5. Identity without an ID service: the key is a hash function
Joining music data across sources has a canonical hard problem: the same artist appears everywhere under different ids, and (measured on this corpus) 39% of artists on the editorial spine and 47.9% on the booking graph have neither a Discogs nor a MusicBrainz id at all (source: ridden audit 2026-06-29). Any design that keys on a canonical-catalogue id silently drops the long tail, which is exactly the part an emerging-artist product cares about. (When seen measured its flagship dossier surface, 63.4% of clusters produced no dossier row under a Discogs-keyed gate. It re-keyed the surface.)
Hosaka's answer is radical in its cheapness. There is no identity service. The artist key is:
cluster_id = SHA-256( "pe-norm-v1" ‖ 0x1F ‖ kind ‖ 0x1F ‖ normalise(name) )- Any process in any repo can mint the same key deterministically: no sequence coordination, no request-time fuzzy matching, no RPC. Unresolved artists get first-class identity; external ids (Discogs, MusicBrainz, Bandcamp) are nullable binds resolved onto the cluster, never the key itself.
- The normalisation is the real spec. The version string is hashed into the key, so a normalizer "improvement" is a loud, deliberate, cross-repo re-key event instead of silent identity corruption. The authoritative definition is not prose (prose already failed: two load-bearing rules, NFC-keeps-diacritics and
and↔&substitution, were lost in a written spec and only recovered when a second-language implementation diverged). It is a golden conformance fixture: one JSON file of normalisation axes and known-answer vectors (Björk proves diacritics survive; "The Stooges" proves article-stripping; "Simon and Garfunkel" = "Simon & Garfunkel" proves the substitution), against which four independent implementations (three TypeScript, one Python) assert byte-equality in their own CI. Four hash implementations agreeing byte-for-byte is the identity system working. - Ownership is per-grain: one repo owns the artist-name normaliser, another owns the label normaliser; everyone else vendors the canonical code verbatim under golden-vector tests. Cross-repo runtime imports are forbidden (each repo deploys independently), so parity is achieved by vendoring plus a version literal that repos bump only in lockstep.
- The known failure modes are published, not hidden. Homonyms over-merge under a name hash, so mirror's bridge tables carry a per-cluster
discogs_artist_id_countcolumn and the worst buckets are human-audited before a surface is trusted, while seen's externally-attested identity bridge measured the legitimate-homonym rate directly (295 clusters, 0.5% carry multiple real identities (source: ridden audit 2026-06-29)). And hash-of-name schemes have a landmine: the empty-string preimage. Every symbol-only name (!!!,❤,$) normalises to""and mints the same key. Mirror discovered 64 unrelated Bandcamp artists fused into one phantom row with ~9,800 summed reach. The fix is defense-in-depth: producers skip minting on empty, and the contract-level JSON Schema excludes the sentinel hash machine-checkably. Pattern-valid hex does not imply identity-valid.
Artist identity is one of four spines, each at its own grain with its own owner: artist (cluster_id, name-hash), work (scheme-prefixed iswc:/prov: canonical work keys, owned by the rights repo), recording (ISRC with fallbacks for the DJ-set tail), and catalogue (discogs_master_id). The four-spine ratification was the fleet's biggest coordination event, which brings us to how coordination happens at all.
6. carrefour: a contract library that is deliberately not a service
Carrefour is the answer to "how do independent agents agree on anything?" The striking thing is what it isn't. It owns zero tables, zero writes, zero runtime. It is a versioned npm library of join-surface schemas plus an issue forum, and its README scopes it in one line: "Not a runtime, not a transport, not a service. Schemas + invariants + validation only." There is nothing to be "down"; the contract cannot outage the fleet. Schemas-as-DDL stay in each owning repo's migrations: copying them into a registry would just create a second source of truth that drifts.
Four mechanisms are worth stealing:
invariants.yamlwith named enforcement points. Twenty cross-repo invariants (at last count), each carrying severity, a curated category vocabulary, andverified_in:back-references naming the exact file and symbol in sibling repos that enforce it. A contract that names its enforcement points is auditable and refactor-aware: touch a listed file, and your PR owes the contract an update. "We agreed" becomes "here is the line of code where the agreement lives."- RFC ratification by receipt. Cross-repo decisions are GitHub issues (120+ so far: RFCs, jurisdiction rulings, ops notices). The four-spine ratification collected nine producer ratification comments, each with file:line receipts from the commenter's own repo. A principal-engineer review surfaced 6 blockers / 11 majors / 12 minors, and the spine-owning producers returned corrected invariant text verbatim. Why the ceremony? Because an earlier RFC drafted from memory ratified a view shape whose columns didn't exist: memory descriptions of other repos' schemas decay, so ratification requires evidence from live code. Deferral authority follows ownership; only the repo whose taxonomy was still moving could defer freezing it.
- Process invariants with kill criteria. The most novel move: versioning a planning discipline in the same semver'd contract file as data schemas. INV-014 ("Frame Validation") requires every PRD to steelman its own inverse framing. Born from a week in which two framing-class bugs (one produced 64,926 silently wrong rows from a single missing API request field) would each have been caught by one forced question at design time. And because process rules rot into checkbox theater, the invariant carries its own kill criterion: four weeks of zero catches and it retires itself. A process rule that can't be falsified is ritual, not engineering.
- Sentinel forward-compat for enums. Schemas stay strict (
additionalProperties: false, closed enums), but every vocabulary union ends in a reservedunknown_to_contractliteral and consumers normalize-then-validate at version boundaries. Strictness catches typos; the sentinel lets a producer roll forward without halting consumers. Per-row you can't tell a typo from a new value, but in aggregate you can (new values ramp to real traffic share; typos hover near zero), so the monitoring story is part of the contract design.
7. The editorial pipeline: from a webpage to the spine
Ridden's pipeline is the fleet's biggest machine. End to end:
Crawl. 48 hand-written per-source clients (each with tests and fixtures) under ~16 per-source daily crons plus a 6-hour dispatch-fleet fanout with lease dedup. Sources that block cloud egress get a transport ladder. The best story in it: three escalating anti-bot countermeasures were on the table (a paid unlocker API, a Worker proxy, headless rendering) until a single verification probe showed the block was pure IP reputation with no active challenge. The correct fix was the cheapest possible: a ~50-line relay on a residential connection. Diagnose before you buy.
The acquisition layer's legal bright lines are encoded as code, not judgment calls: no auth circumvention, no paid-feed exfiltration, no contact/financial PII. Enforced by CI greps on schema files, URL allowlists in scrapers, and a hash of each source's terms-of-service recorded at collection time. (An honest gap the fleet's own audits acknowledge: those bright lines are strongest in the verticals; a formal takedown/rights-posture document for the full-text article corpus itself is still owed.)
Extract: twice, on purpose. Two parallel LLM extraction pipelines run over the same articles, and the temptation to unify them has been explicitly resisted:
- v1 (analyser) extracts narrative relations (influenced-by, reaction-against, with quotes and speaker attribution, ~7 mentions/article) feeding the human-readable artist dossier.
- v2 (tuple-extractor) extracts subject tuples at ~39/article, feeding a mechanical identity-resolution ladder and the cross-source attention spine.
Different consumers want different precision/recall trade-offs at different grains; collapsing the pipelines would force one prompt and one schema to serve both a prose product and an identity graph. (v1 also carries a cautionary scar: it was built for one magazine's column format and for months silently returned empty results for every other source. The note is preserved in the code.)
Resolve. A five-rung resolution ladder maps tuples to catalogue identity with explicit per-rung confidence (0.97 exact → 0.95 alias → 0.92 year-disambiguation → 0.90 article-stripped + label-disambiguation → 0.85 fuzzy trigram). At the last audit, 46.7% of assertions resolved to a Discogs master and 53.3% to a release-group MBID (source: ridden audit 2026-06-29).
Emit to the spine: without coupling. The resolver writes spine events through a SAVEPOINT-guarded outbox inside its own transaction. If the outbox insert fails, only the savepoint rolls back, a metric bumps, and a daily reconcile heals the gap by re-diffing source rows against evidence (48-hour recovery SLO). The hot path's success is never hostage to a downstream consumer's availability, idempotency comes from ON CONFLICT composite keys, and the module documents its invariants formally with per-invariant violation signals and chaos tests.
8. LLM as detector, dictionary as resolver
The cost-obvious design for corpus-wide mention extraction was gazetteer-first: string-match every article body against the 11M-name artist dictionary (essentially free) and reserve the LLM for ambiguity. Versus an estimated $5.7–8.2K for a naive full-corpus LLM pass (source: ridden cost analysis 2026-06). The discipline that saved the project was piloting on one source, dark-shipped, before any rollout.
The pilot produced ~800 matches per article, roughly 99% false positives (source: ridden staging pilot 2026-06). The failure is intrinsic to an 11-million-name catalogue: "Yes", "Low", "Health", "false", "creator", "opinion" are all genuinely the names of obscure artists somewhere in Discogs. String containment cannot know that "Opinion" in a nav bar isn't a techno producer. The 176,048 garbage rows were staging-only (that's what dark-shipping is for) and rolled back with zero consumer impact.
Then the key move: invert the roles instead of discarding the assets. The LLM became the detector. It understands "is this an artist reference in context" and surfaces ~38 clean candidates per article. The dictionary was demoted to the resolver, an exact lookup of only LLM-surfaced names, yielding catalogue ids. Same components, opposite roles: precision went to ~98% (source: ridden audit 2026-06-29). Division of labor by comparative advantage. The expensive model does only the ambiguity resolution it is uniquely good at; the free lookup does the rest. The falsified design went into a register with an explicit reopen condition so no future planning session re-walks it (Part 2, §8).
9. The shared database: honest engineering around a single point of failure
The whole fleet's data lives in one self-managed Postgres. A single container task on network storage (ECS on EFS), fronted by PgBouncer, serving 14 consumer roles. It is not RDS. The original reason was a graph extension (Apache AGE) no managed Postgres supports; the extension was later removed, but by then the operational arrangement (custom image, backup tooling, cross-schema grants, one DB serving the fleet) had accreted, and migrating became a bigger risk than operating it. To this day the database's internal nickname is the extension it no longer runs: a clean example of a technical constraint creating an operational arrangement that outlives the constraint.
Its shape dictates real design consequences, all documented where they bite:
- Stop-before-start deploys (
min_healthy=0): two postmasters on one EFS data dir corrupt it. - The health check was deliberately deleted. Exec-based checks fork a Postgres backend per probe; under a weekly heavy import the fork queue stalls, probes time out, and the orchestrator kills a healthy database. Four rounds of retry/interval/timeout/CPU knob-tweaking never fixed it. The removal and the reasoning are recorded so nobody re-adds it. (What replaced it, and how the replacement was calibrated against a real incident's logs, is a Part 2 story.)
- Refresh idiom chosen by measurement: on this deliberately small instance (2 vCPU/8 GB serving everyone),
REFRESH MATERIALIZED VIEW CONCURRENTLYon a 2.5M-row rollup took >14 minutes doing a TID-diff;TRUNCATE+INSERTinside one transaction (an atomic swap under MVCC) took ~30 seconds (source: ridden perf measurement 2026-06). The idiom also encodes ownership: "TRUNCATE+INSERT in the analyzer" is how the fleet recognizes an analyzer-owned table nobody else may write. - Snapshot tables as privilege firewalls: the internet-facing API role gets zero cross-schema grants; analyzers materialize cross-schema joins into API-readable snapshots, and the staleness budget (~24h) is written down next to the DDL as the price of the firewall.
Is a single-task Postgres serving a whole fleet a single point of failure? Yes. The architecture says so out loud, prices it (auto-heal + dual backup lines + a rehearsal gap the last audit flagged honestly), and accepts it as a launch-scale trade rather than pretending otherwise.
10. The hybrid split: a cloud fleet and a gaming PC
The infrastructure story people remember: hosaka's entire LLM tier is one consumer GPU workstation (a single ~32 GB card) in a house, joined to the AWS VPC over a mesh VPN through a subnet-router gateway. Cloud Fargate tasks call it like any API. It serves a quantized ~30B-class extraction model (a Mixture-of-Experts whose inference is memory-bandwidth-bound: the GPU runs cool at full throughput, which once caused an operator to misdiagnose a working GPU as idle by touch; the runbook now says trust the request stream, not the temperature) and, on demand, a 235B judge model.
What makes this production-grade rather than a hack is that the box is under the same contract discipline as any data producer:
- It publishes itself through a provider contract file (
contracts/inference.yaml): model aliases as the schema, gateway virtual keys as the grants, changes in the same PR, breaking changes through a forum issue. Onboarding an inference consumer looks identical to onboarding a data consumer. - No SLA, by design: "box-down means slower/pricier, never broken." Every consumer keeps a paid-path fallback. A contract rule, though honesty compels the footnote that the last audit caught the fallback itself non-functional at one point (the cutover happened because paid credits had run out), and flagged it as an accepted launch ceiling rather than papering over it. A residential machine can't honestly promise availability, so the architecture prices box failure as a cost event, not an outage event.
- Failure semantics differ by failure class. Box unreachable (an availability event) falls through to the paid path, visibly, with a
fallback_occurredtelemetry flag as the watched anti-signal. Local 4xx (a misconfiguration) is terminal and halts bulk extraction, because the "graceful" alternative would silently re-route corpus-scale volume to a paid API and convert a config typo into a five-figure bill. For batch work, automatic fallback is a footgun, not a feature. - Zero-cost models need synthetic prices: the gateway skips budget enforcement for zero-cost models, so local models carry synthetic per-token prices (source: box contracts/inference.yaml). Pricing then becomes policy: the 235B judge is tariffed ~30× the extraction model specifically to deter casual calls that would evict the workhorse from VRAM.
- VRAM is the scarce resource, and its mutual exclusion is enforced in config, not convention. The card cannot hold both the extraction model and the judge. The router pins the extractor resident and auto-unloads the judge; the sweep runner independently verifies the served model every batch and self-pauses on drift. The reason it's structural: the GPU's platform (WSL) oversubscribes VRAM into system RAM instead of failing. A co-residency mistake doesn't crash; it silently runs ~20× slower (measured: 0.21 vs 4.58 tok/s (source: box perf measurement 2026-06)). When a failure mode is silent, the invariant can't live in a runbook.
- Every long-running job is a boot-enabled systemd unit, and nothing counts as done until it joins the verified power-on resurrection chain. A residential node reboots for Windows updates without ceremony, so the whole duty set must self-resurrect from a cold power button (under 3 minutes, no login (source: box runbook 2026-06)).
The economics: 52,654 matched extractions in one 7-day window at zero marginal cost, an estimated ~$2K+ of paid-API extraction replaced by electricity (source: ridden audit 2026-06-29). But the most instructive number is the one that failed: before cutover, a 50-article bake-off gated the local model against a ≥95% replacement bar. It scored 90.5. The gate was honored, not argued away. The local path shipped as additive capacity with the paid model retained as the quality path, and the FAIL verdict stands in the contract file. (The fleet-quiesce choreography this box forces, stopping ~24 cloud tasks so one GPU can change hats to judge, is a Part 2 story.)
Everything else is deliberately boring AWS: Fargate task fleet, ~42 EventBridge scheduled rules as the cron lattice, Terraform per repo, ECR, Secrets Manager, CloudWatch alarms routed to a confirmed-subscription topic. Two honest footnotes an educated reader deserves: the fixed cloud spine is an estimated ~$500–1,000/month (component-based, not billed figures (source: ridden cost estimate 2026-06)), and the live fleet runs entirely on infrastructure named staging. For a solo operator, staging is production, and the docs say so instead of pretending there's a second environment.
11. The consumer edge: APIs designed for agents
Crate (the dossier gateway) is where the fleet's data meets users, and it's designed on the assumption that many of its callers are AI agents. That assumption turns out to be a concrete design checklist, not a vibe:
- An empty answer is a first-class answer: HTTP 200 with
present: false/state: 'honest_gap'instead of 404. An agent can't distinguish "you called it wrong" from "the data doesn't exist" in a 404, and tends to retry or fabricate. - Errors teach: every typed error carries
.hint(what's wrong) and.next(a copy-pasteable corrected call), so an agent recovers from the response alone, no docs round-trip. The stated bar: a human reaches a green result in under a minute; an agent succeeds first-try. - Identity-first surface:
cluster_idis the API's root key; platform ids are demoted to "locators"; releases, Bandcamp standing, and editorial coverage attach to the artist as dossier dimensions rather than top-level resources. Resolve once, key everything off it. - Billing on delivered value: metering charges on successful 2xx data responses (honest gaps are answers; errors are free), with the tier ladder consolidated into one canonical module after a pricing review found the tables triplicated, and a legacy tier accidentally cheaper per-unit than premium. The fix included a unit test asserting the economic invariant (effective $/1k never rises with volume). Pricing tables drift like any other duplicated data; test your economics.
- Misses are a product asset: every artist name that fails to resolve lands in a demand-capture stream (fire-and-forget, never blocking a request) that becomes a ranked data-gap list. The API's misses literally set the producer fleet's crawl priorities.
And at the trust boundary, repo boundaries follow blast radius, not code convenience: taste (PII: people's listening data) lives in its own repo, database, VPC, and key hierarchy, and consumes crate exclusively through the public paid API. Simultaneously containing the PII blast radius and dogfooding the B2B product as customer zero.
12. What this architecture teaches
If you strip the music domain away, hosaka's architecture is a set of answers to one question: what does rigorous engineering look like when your engineers forget everything between sessions and your ops team is one person?
- Encode architecture as executable guards, not documentation. Grants, CI greps, contract files with same-PR coupling, and (for agent engineers) context rules as a real defense layer.
- Make identity content-derived and version-hashed. No coordination service, loud re-keys, byte-parity fixtures instead of prose specs, and published (not hidden) failure modes.
- Let contracts own the seams at every layer. Database schemas, YAML manifests, inference endpoints, even a frozen 7-message Unix-socket protocol between two tooling repos: freeze the contract, version it, let each side ship independently.
- Price unreliability instead of denying it. The no-SLA GPU box with mandated fallbacks, synthetic prices so budgets engage even for free-to-run models, per-failure-class semantics.
- Prefer the cheapest mechanism that actually prevents the failure class. A token-bucket row over a rate-limit service; a residential relay over an unlocker subscription; TRUNCATE+INSERT over materialized-view machinery; a YAML forum over a schema registry.
- Be honest in the artifact. Failed gates that stand, SPOFs that are named, staleness budgets written next to the DDL, and "staging is production" said out loud.
The oldest routing table keeps one address in a hand nobody claims; mail sent there returns unopened, postmarked twice.
The other half of the story is the part most readers came for: how do stateless agents actually build and operate all this without wrecking it? That's Part 2 →
Get the next post
Free membership: new posts on how the fleet is built, delivered by email. Subscribe free
Read next
- The repo remembers: how agents build hosaka
- The Same Operating System on Every Machine
- The harness that ships: why completion is the moat
Post history
- 2026-07-21: crosslinker + enrich phase + OQ-1 spike + caption-uniqueness law
- 2026-07-21: BLOG SURFACE ENRICHMENT: four corners + engine images + backfill (sprint-25)
- 2026-07-17: bring ridden essays up to current canon law: shadow sentences + colophons + category tags; merge main (posts.json union)
№ 4190