HomeZero · Agent Model on Flue · 2026-06-23

The Market Agent — the brain of a place.

One agent per market. It gathers everything knowable about the homes there — listings, parcels, sales, distress, water — into a structured brain and a vector mind, weaves a living wiki of briefs, and serves it to the advisor and the app. This is the full capability, captured.

Flue · Cloudflare DO :id = north-fork-valley Turso · structured + vector status: DESIGN CAPTURE — not in current build
00 · In one breath

What the market agent is

If the advisor is one buyer's relationship, the market agent is one place's memory. It's the only thing in the system that scrapes, ingests, and reasons over the raw facts of a market — and the advisor reads its brain rather than ever touching a source itself.

It already does the thin slice (Zillow listings → Turso → per-home verdicts in Convex). This spec captures the parity rebuild of everything the old Delta agent did, on Flue: county records, a vector mind, and a wiki — all on the full storage stack every agent gets.

01 · Ground truth

Where we are — as-built

Unlike the advisor, the market agent is real end-to-end for its current scope (flue/src/agents/market.ts + flue/src/market/{brightdata,publish,tools,store}.ts, 74 vitest specs).

What's done live

  • Sweep. Bright Data dataset → 4 NFV ZIPs → Turso listings → publish_cards (clobber-safe). Fired by the 0 9 * * * cron via {kind:'sweep'}.
  • Drain. {kind:'drain'} doorbell → per-home verdict / valueFactors / deepDive → Convex listings:upsert / setDeepDive.
  • Brain (thin). Turso via getTursoClient(), env TURSO_DATABASE_URL / TURSO_AUTH_TOKEN; tables listings + ingest_runs.
  • 6 model tools, the same auth/route gate as the advisor.

The parity gap designed, not built

  • No county records. The old Delta agent ingested parcels, assessor, deeds, foreclosures, permits, water — none of that is on Flue yet.
  • No vector mind. listings is scalar only; no embeddings, no vector_top_k.
  • No wiki. Briefs aren't interlinked; there's no comps graph.
  • No metric skill. The daily-alarm "how's this market doing" measure is the one acknowledged gap even within current scope.
  • Writes no board card. The "market half" of a card is a render-time JOIN in the app, not an authored row. authorship
02 · The model

The full storage stack

Every agent in HomeZero gets the same five places to keep things. The point of the market agent is that it's the one that uses all of them, hard. The advisor uses a lean slice of the same stack — shown alongside so the two specs read as one model.

Filesystem workspace · files
market keepsSkill files (SKILL.md), study notes & source playbooks, wiki source it can edit.
advisor keeps/IDENTITY.md, /JOURNAL.md, its own skill files.
Tools hands · code
market keepssweep, drain, county-ingest, embed, wiki-weave, comps, metric — defineTools.
advisor keepsauthor_card, read_reactions, scout_query, brain/journal r-w.
Structured brain Turso · tables
market keepshouses & their facts: parcels, listings, sales, deeds, foreclosures, permits, tax, EAV facts.
advisor keepsyearnings, skill_metrics, skill_params.
Vector mind Turso · F32_BLOB
market keepslisting & brief embeddings → comps, substitution, demand shape (used creatively, §05).
advisor keepsreads the market's vectors via scout; optional small recall vector.
Shared projection Convex · app-served
market writesthe listings/verdicts/cards the app shows. The thin, public face.
advisor writesboard cards, the learning panel.
The boundary Pete drew: the Turso brain is the agent's own — structured house data and vectors it keeps to reason, which may or may not surface to Convex. Convex is shared state with the applications — only what the app needs to serve. The good stuff (raw county evidence, the comps graph, demand vectors) lives in the brain; Convex gets the conclusions.

The agent invariant (shared with the advisor): the market's Turso db is its complete, addressable mind — a files table (its filesystem: skills, wiki source, study notes), its structured + vector brain, and a session log — keyed 1:1 to the market (north-fork-valley) and reachable from any libSQL client (SSH/TUI operability). Flue's flue_* engine tables stay in the DO.
03 · Shared with the advisor

Flue skills — same primitive

The market uses the identical skill model proven in the advisor spec: a skill is a SKILL.md in .agents/skills/, discovered from the workspace, loaded on demand via activate_skill (progressive disclosure), reusable across agents. Tools stay agent-level code; each tool is paired to a skill by convention — the tool is the hands, the skill is the know-how that teaches its use.

shared  The brain skill (how to use Turso — read/write, the schema, when) is written once and dropped into both the advisor and the market. The market also owns heavier skills the advisor never needs (county-ingest, wiki-weave, embed). One model, two appetites.
04 · The exemplar

Self-improving skills · the metric skill

Self-improvement is built the same way (Flue has no native hook): a skill carries a metric from real signal and tunable state (params in Turso and/or its own SKILL.md body), and the nightly dream rewrites the playbook. The market is where this pattern is most obviously native — its missing "metric skill" is a self-improving skill:

// market's daily billboard / metric beat
const snap = brain.computeMarketMetrics()   // median asking, DOM, verdict-mix, honest-deal count
brain.writeMetrics(snap)                       // → skill_metrics (Turso)
const drift = compare(snap, lastWeek)         // what's moving in this market
fs.writeFile('.agents/skills/comps/SKILL.md', retune(body, drift))  // the comps playbook adapts

The same loop tightens the comps skill (do its comps agree with what actually sold?), the county-ingest skills (did a source's parse drift?), and the study cadence (which yearning is worth a pulse). Every market skill measures itself.

Verify before trusting the field aliases. The Bright Data → listings mapping must be checked against one real record before the metric skill computes medians off it — a silent alias drift would poison every metric.
05 · Structured + vector

The brain — structured + vector

Structured spine — houses and their facts

A parcel-centred schema, jurisdiction-agnostic via an EAV facts table so a new county doesn't need new columns. Vectors are native libsql — F32_BLOB(n) + libsql_vector_idx (DiskANN) + vector_top_k — no Stoolap, no new dependency, just an ensureSchema add.

parcels( pin PRIMARY, geom, acres, owner_inst, … )        // the spine (ArcGIS + assessor)
parcel_facts( pin, key, value, source, observed_at )       // EAV — water, zoning, soil, CDL…
parcel_listings( pin, zpid )                              // bridge scalar listings → the spine
sales( pin, price, date, doc_ref )                         // real comps, not estimates
deeds · foreclosures · distress · permits · tax_history
listing_vectors( zpid, embedding F32_BLOB(1024) )         // the vector mind
brief_vectors(  slug, embedding F32_BLOB(1024) )
wiki_links( from_slug, to_slug, kind, weight )              // the comps graph (§06)
yearnings · skill_metrics · skill_params             // shared brain shape

The vector mind, used creatively

Pete's nudge — "a vector we can think of creatively." A few ways the market puts it to work beyond plain similarity:

06 · The compounding asset

The wiki — a comps engine

The wiki is the market's edge that grows with every zero. It's not a separate store — it's the wiki_links edge table over the briefs, woven at publish time. Each new brief is linked into its neighbours (same street, same band, substitute, comp, shares-a-risk), so comps become a graph traversal seeded by a vector search, not a SQL WHERE. Built fresh — the old Delta agent never had it.

07 · Rhythm

The loop — five beats

Same primitive as the advisor (extend + scheduleEvery over DO alarms, cron as the floor). The market's daily study is bounded — one yearning per pulse on a study budget — which doubles as the source rate-limiter so it never hammers a county site.

react · drain
event · per zero

live A home is zeroed → produce verdict / valueFactors / deepDive → Convex.

sweep
daily

live Pull current listings (Bright Data) → Turso → publish cards. Lifecycle reconcile.

study
daily · 1 yearning

One demand-weighted standing question → ingest a county source via its pattern adapter → into the brain.

billboard
daily

Compute & publish market metrics (the metric skill): median asking, DOM, verdict-mix, honest-deal count.

dream
nightly

Weave the wiki, refresh embeddings, reweight yearnings by demand, rewrite skill playbooks from their metrics.

08 · The pairs

The skill catalog

Market tool↔skill pairs. live = the tool exists today; new = parity rebuild. shared = same skill object as the advisor.

sweep live
toolssweep · publish_cards
know-howWhen to pull, how to map Bright Data fields, clobber-safe publish.
metricCoverage & freshness; alias-drift alarms.
tunesWhich ZIPs, cadence, field mapping.
drain live
toolsdrain → verdict/valueFactors/deepDive
know-howHow to brief one home; the cost-to-zero scorecard.
metricDo verdicts hold up vs what sells?
tunesScorecard weights, deep-dive depth.
county-ingest new — a family, one adapter per source
toolsfetch_parcels · fetch_assessor · fetch_distress · fetch_permits · fetch_water
know-howEach source's quirks, the pattern adapter that makes it fit one pulse.
metricParse success; did the schema drift?
tunesSelectors/field maps as sites change.
embed new
toolsembed → listing_vectors / brief_vectors
know-howWhat text to embed for comps vs demand; refresh policy.
metricDo nearest-neighbours agree with sales?
tunesEmbedding inputs, dimensions, refresh cadence.
wiki-weave / comps new
toolsweave_links · find_comps (vector_top_k + graph)
know-howWhich edge kinds to draw; how to walk the graph for comps.
metricComp → actual sale agreement.
tunesEdge-kind trust weights.
metric new — the acknowledged gap
toolscompute_market_metrics
know-howWhat "this market is doing X" means; the billboard.
metricSelf — metric stability vs noise.
tunesWindows, which measures matter.
brain shared with advisor
toolsbrain_read · brain_write
know-howThe Turso schema; read vs write; structured + vector queries.
metric—(infrastructure).
tunesMostly static; the shared contract.
09 · Resolved

County data & egress

The egress question is settled (spike-verified): no county or state source needs a residential IP — that was a Zillow-only artifact. 8 of 9 sources are a direct datacenter Worker fetch(); the lone exception has a clean replacement. Residential egress stays scoped to Zillow.

SourceEndpointAccess
Parcel spineservices3.arcgis.com/…/Delta_County_Parcels/FeatureServer/0/querydirect · public (TaxPIN_GIS join)
Assessor / deedsassessor.deltacountyco.gov/assessor/web/direct · server-HTML, no wall
Permitsapps2.colorado.gov/dora/…direct · Tyler eLicense HTML
Foreclosure docsdeltacoco.api.civicclerk.com/v1/Eventsdirect · OData JSON
Public Trusteeptrustee.deltacounty.comdirect · HTTP-only ASP.NET
Water rightsdwr.state.co.us/Rest/GET/api/v2/structures?county=DELTAdirect · open REST
Soil / cropsSSURGO SDA · CDL/CropScapedirect · open REST
qPublic (fallback)qpublic.schneidercorp.comBrowser Rendering · optional — EagleWeb replaces it

So Phase 2 = direct fetch + an optional Cloudflare Browser Rendering binding for the one bot-walled source. No wells, no proxy. Each source is a pattern adapter sized to fit one study pulse.

10 · The handoff

Boundaries & the advisor handoff

11 · Sequencing

Build status

The market agent is not in the current build. We ship the advisor first (1A–1D). This spec is the capture so the parity rebuild is ready to lift when its turn comes. When it does, the order roughly mirrors the advisor's:

Phase 2 milestoneDelivers
2A · SpineParcel schema + EAV facts + the structured brain tables; bridge listings to parcels.
2B · RecordsCounty-ingest skills on the study beat (assessor, distress, permits, water) via pattern adapters.
2C · Vector mindNative libsql vectors + embeddings; comps via vector_top_k.
2D · Wiki + metricsWiki-weave on publish; the metric skill + billboard; market dream (reconcile, reweight, self-tune).

Same skill model, same rhythm, the shared brain skill already authored in the advisor build. Nothing here is orphaned — it's queued.