Repository Public
1/*2 groupe-ka-details.ts3 spboucher.ai Web4 Author: Simon-Pierre Boucher5 Mail: contact@spboucher.ai6*/78/*9 Detailed content for the /projects/[slug] pages. Sourced from each10 platform's README (figures as of 2026-08-24/25 unless noted).11*/1213export interface KaAppDetail {14 slug: string;15 headline: string;16 subheadline: string;17 overview: string[];18 stats: { value: string; label: string }[];19 features: { title: string; description: string }[];20 stack: { category: string; items: string[] }[];21 docUrl?: string;22}2324export const kaAppDetails: KaAppDetail[] = [25 {26 slug: "lou-ka",27 headline: "Every apartment for rent in Quebec, in one place",28 subheadline:29 "A dedicated connector per property manager visits each site, normalizes every listing to a single schema, and detects changes continuously — additions, updates and removals, automatically.",30 overview: [31 "Searching for an apartment in Quebec normally means opening dozens of sites, each with its own navigation, filters and format. Lou·Ka inverts the problem: one dedicated connector per property manager visits each site, normalizes every listing to a unified schema, and detects changes continuously through periodic sync plus content hashing — a listing that disappears from its source returns a true 410 Gone. Every listing links back to the manager's original ad through a transparent outbound gateway.",32 "The platform serves renters (filtered search, 3D map, complete listings), market watchers (a rent observatory with PDF reports) and property managers (claimable pages). As of 2026-08-24: 45,762 active published listings from 281 catalogued sources and 250 connectors (221 long-term + 29 short-term), across 1,233 cities and 11 regions, 97.4% geolocated, with a median rent of $1,700 — plus 41,460 short-term stays (cottages, Airbnb and more) in the dedicated /court-terme section.",33 "Listings are enriched with an unusual depth of neighbourhood data: the 2021 census, Quebec's rent registry (57,433 geocoded declarations), flood zones (BDZI), SPVM crime by category, air quality (RSQAQ/PST), gas prices, nearby shops and transit lines in their official colours, a live Hydro-Québec cost estimate, and KA Scores covering 95.5% of the stock. An editorial quality gate quarantines parking spots, garages and commercial spaces, and an anti-drift guard suspends removals if a source suddenly returns far fewer listings than usual.",34 ],35 stats: [36 { value: "45,762", label: "Active listings" },37 { value: "281", label: "Sources catalogued" },38 { value: "250", label: "Connectors" },39 { value: "1,233", label: "Cities" },40 { value: "97.4%", label: "Geolocated" },41 { value: "41,460", label: "Short-term stays" },42 ],43 features: [44 {45 title: "Unified list + map search",46 description:47 "One /api/search backs both the list and the 3D map (Ka Maps / Mapbox GL): price clusters, search-this-area, and a counter that always matches the markers.",48 },49 {50 title: "Neighbourhood data layers",51 description:52 "Rent registry, flood zones, crime, air quality, gas prices, shops, metro/REM lines and a live Hydro-Québec estimate — layered onto every listing page.",53 },54 {55 title: "KA Scores",56 description:57 "A homegrown scoring engine (OSM tiles + walkability data) grading each address, covering 95.5% of the published stock.",58 },59 {60 title: "Short-term rentals",61 description:62 "An isolated /court-terme subsystem aggregating 41,460 stays — cottages, Airbnb (quadtree map-grid crawl bounded to Quebec), Vrbo, Booking and direct-booking hotels.",63 },64 {65 title: "Market observatory",66 description:67 "Real-time KPIs, median rents by region/city/size, and multi-page PDF market reports plus a custom ReportBuilder.",68 },69 {70 title: "Anti-drift resilience",71 description:72 "Content-hash diffing with a grace period, a drift guard that suspends removals on sudden source drops, and an anti-bot fetch chain (Oxylabs → Scrapfly → Bright Data).",73 },74 ],75 stack: [76 { category: "Backend", items: ["Python 3.14", "FastAPI", "SQLite (WAL)", "SSR SEO"] },77 { category: "Frontend", items: ["React 18", "Vite", "TypeScript", "Mapbox GL (ka-maps)", "ka-ui"] },78 { category: "Platform", items: ["PM2", "ngrok", "KA ID SSO", "KA Agent widget", "iOS app (SwiftUI)"] },79 ],80 docUrl: "https://www.lou-ka.com/doc/",81 },82 {83 slug: "immo-ka",84 headline: "Every property for sale in Quebec, always up to date",85 subheadline:86 "An independent real-estate aggregator: 105 connectors covering broker banners, sub-agencies and no-broker platforms, deduplicated by Centris number, with direct links to the original listings.",87 overview: [88 "House-hunting in Quebec normally means juggling RE/MAX, Royal LePage, Sutton, Via Capitale, Century 21, DuProprio and dozens of other banners. Immo·Ka inverts the problem: one dedicated connector per source (105 registered connectors — central banner feeds, sub-agencies as plan B, no-broker platforms) visits each site, normalizes every listing to a single PropertyListing schema, deduplicates by Centris number and detects changes continuously, always linking back to the original ad.",89 "Agency sites offer no webhooks, so Immo·Ka reproduces the equivalent with periodic sync plus content hashing: new listings, price changes and removals (property sold) are detected automatically, with a grace period against transient site failures. Coverage as of 2026-08-24: 67,705 active properties, 48 sources, 22 banners, 159 sub-agencies and 3,262 cities. It is the for-sale counterpart of Lou·Ka, wired into the Vrai-Prix valuation engine and the shared KA ID account.",90 "Each listing page goes well beyond the ad: a Vrai-Prix market-value estimate with a P10–P90 gauge and an over/under verdict, the official assessment roll (land/building values, year built), a timestamped asking-price history, census-based neighbourhood profiles, and territorial layers — rent registry, flood zones, air quality, gas prices, shops and transit, plus a precomputed Hydro-Québec estimate.",91 ],92 stats: [93 { value: "67,705", label: "Active properties" },94 { value: "105", label: "Connectors" },95 { value: "22", label: "Banners" },96 { value: "159", label: "Sub-agencies" },97 { value: "3,262", label: "Cities" },98 ],99 features: [100 {101 title: "Centris-number dedup",102 description:103 "A property listed on three broker sites becomes one listing with every source credited — broker versions take priority, with an “Also published on…” box.",104 },105 {106 title: "Vrai-Prix estimate on every listing",107 description:108 "Hedonic model + adjusted comparables produce a market-value gauge and an over-priced / aligned / below-estimate verdict.",109 },110 {111 title: "Assessment roll & price history",112 description:113 "Official municipal values and year built joined locally from the Vrai-Prix base, plus a timestamped log of every asking-price change and days on market.",114 },115 {116 title: "Ka Maps search",117 description:118 "3D Mapbox GL map with price clusters, markers coloured by gap to the Vrai-Prix estimate, and search-as-you-move.",119 },120 {121 title: "Territorial layers",122 description:123 "Rent registry, BDZI flood zones, air quality, gas prices, shops/transit and precomputed Hydro-Québec estimates on each listing.",124 },125 {126 title: "Programmatic SEO",127 description:128 "Full server-side HTML with one indexable page per city, type and city+type, dynamic sitemaps and structured data.",129 },130 ],131 stack: [132 { category: "Backend", items: ["Python", "FastAPI", "SQLite (WAL)", "quality + imgaudit pipeline"] },133 { category: "Frontend", items: ["React 18", "Vite", "TypeScript", "ka-ui", "Ka Maps (Mapbox GL)"] },134 { category: "Platform", items: ["PM2 (web / sync / ngrok)", "4-hour sync cycle", "KA ID SSO"] },135 ],136 docUrl: "https://www.immo-ka.com/doc/",137 },138 {139 slug: "vrai-prix",140 headline: "The real market value of any Quebec property — with the why",141 subheadline:142 "3.75M properties, 22.15M observations and 745K real transactions feed a hedonic LightGBM model and an adjusted-comparables engine. Total transparency: every comparable, every dollar adjustment, published methodology.",143 overview: [144 "Vrai-Prix estimates the market value of any property in Quebec — single-family, plex, condo, cottage, land — and shows why: every comparable, every dollar adjustment, the model's weighting, the P10–P90 range and an A–D confidence grade. The differentiator is total transparency: no magic score, no black box. The full methodology (IAAO standards) is published on the site.",145 "Under the hood: the six vintages (2021–2026) of Quebec's georeferenced property-assessment rolls (MAMH open data) — 3,747,008 properties, 22,150,285 observations — spatially fused with 745,119 real transactions (99.88% match rate, 0.6 m median distance), feeding a hedonic LightGBM model (11.0% MdAPE, 0.995 median ratio in holdout) and an adjusted-comparables engine. The 2026 vintage puts the province's total stock at $2.01 trillion.",146 "The estimate is hybrid — 65% hedonic model, 35% adjusted comparables — with a quantile-regression P10–P90 range and a mandatory confidence grade. Full-text address search (SQLite FTS5) covers all 3.75M units with typo tolerance, and a manual estimation path works without an address. Programmatic SEO exposes 3.76M indexable URLs, and a conversational Ka agent (Claude with 12 server tools) answers valuation questions in plain language.",147 ],148 stats: [149 { value: "3.75M", label: "Properties" },150 { value: "22.15M", label: "Observations (6 vintages)" },151 { value: "745K", label: "Matched transactions" },152 { value: "1,097", label: "Municipalities" },153 { value: "$2.01T", label: "Total stock value (2026)" },154 { value: "11.0%", label: "Model MdAPE" },155 ],156 features: [157 {158 title: "Hybrid estimation engine",159 description:160 "65% hedonic LightGBM + 35% market/size/age-adjusted comparables, with a P10–P90 range from quantile regression and an A–D confidence grade.",161 },162 {163 title: "Address search over 3.75M units",164 description:165 "Full-text FTS5 search tolerant to typos, plus a no-address fallback: manual estimation by municipality and characteristics.",166 },167 {168 title: "Vrai-Prix Maps",169 description:170 "3D map search (Mapbox GL via ka-maps) with viewport-driven clusters of estimated values and a pure-SVG surveyor-style comparables plan.",171 },172 {173 title: "Bank-grade PDF reports",174 description:175 "100% vector reports (pdfkit): standard 3-page, professional 6-page bank format, consolidated portfolio (up to 40 properties), and provincial statistics.",176 },177 {178 title: "Conversational Ka agent",179 description:180 "A Claude-powered agent (SSE streaming) wired to 12 server tools — estimate, comparables, portfolio valuation, market index, municipal stats.",181 },182 {183 title: "3.76M indexable pages",184 description:185 "Programmatic SEO: municipality pages, municipality × type pages and 3.75M SSR estimation pages with unique metadata, JSON-LD and on-the-fly sitemaps.",186 },187 ],188 stack: [189 { category: "Model", items: ["LightGBM (hedonic, log-price)", "Quantile P10/P90", "IAAO methodology", "MAMH open data"] },190 { category: "App", items: ["Next.js 16 (App Router)", "better-sqlite3 + FTS5", "Ka Maps", "pdfkit"] },191 { category: "Platform", items: ["Bilingual FR/EN", "KA ID SSO", "iOS companion app", "PM2 + ngrok"] },192 ],193 docUrl: "https://www.vrai-prix.com/doc/index.html",194 },195 {196 slug: "house-ka",197 headline: "Homes for sale across Canada outside Quebec",198 subheadline:199 "The English-language sister of Immo·Ka: one generic connector covers every brokerage site running RealtyPress on the CREA DDF feed, with cross-site duplicates masked by DDF number.",200 overview: [201 "House·Ka continuously aggregates homes publicly listed by Canadian real-estate brokerages and teams whose sites run the RealtyPress WordPress plugin on the CREA DDF feed. Each such site exposes its board's full inventory; a single generic connector covers them all, and cross-site duplicates are masked by DDF number. Launched 2026-08-27 with 200,000+ Ontario listings, expanding province by province.",202 "The platform was forked from Immo·Ka, keeping the proven pipeline — connectors → ingestion → dedup → quality gate → API — while removing everything Quebec-specific (Hydro-Québec estimates, flood zones, rent registry, census profiles, Vrai-Prix). The publication rule is deliberately relaxed (price + city) with types and descriptions enriched over time through detail passes.",203 "The frontend is fully English with its own pine/cream/serif identity, deliberately distinct from Immo·Ka's cherry theme, and includes a Canada-wide mortgage engine with national rates shared with Immo·Ka. Thirteen canonical property types in English (House, Condo, Townhouse, Semi-detached, Duplex… through Parking) normalize the DDF data.",204 ],205 stats: [206 { value: "200K+", label: "Listings at launch" },207 { value: "1", label: "Generic connector (RealtyPress/DDF)" },208 { value: "13", label: "Canonical property types" },209 { value: "EN", label: "English-first" },210 ],211 features: [212 {213 title: "One connector, every brokerage",214 description:215 "A single generic RealtyPress connector covers every DDF-fed brokerage site in Canada; adding coverage means adding a registry row, not writing code.",216 },217 {218 title: "DDF-number dedup",219 description:220 "The same board inventory exposed by many brokerage sites collapses into one listing per DDF number, with sources credited.",221 },222 {223 title: "Mortgage engine",224 description:225 "Canadian national rates collected continuously (mortgage-sync), powering payment calculators on every listing — shared with Immo·Ka.",226 },227 {228 title: "Progressive enrichment",229 description:230 "DDF list cards carry no property type; detail passes fetch a bounded number of pages per source per sync to fill types and descriptions over time.",231 },232 {233 title: "English SEO",234 description:235 "Server-side HTML, JSON-LD and sitemaps rendered in English: /for-sale/{city}/{type} pages, /property/{uid}/{slug} listings.",236 },237 {238 title: "Ka Maps search",239 description:240 "The shared Groupe Ka 3D map framework, with a coordinate guard covering all of Canada.",241 },242 ],243 stack: [244 { category: "Backend", items: ["Python", "FastAPI", "SQLite", "CREA DDF via RealtyPress"] },245 { category: "Frontend", items: ["React", "Vite", "English (en-CA)", "Ka Maps"] },246 { category: "Platform", items: ["PM2 (web / sync / ngrok)", "remote-first repo on the node"] },247 ],248 },249 {250 slug: "rent-ka",251 headline: "Residential rentals across Canada outside Quebec",252 subheadline:253 "The English-language sister of Lou·Ka: platform-generator connectors turn each property-management platform into hundreds of sources — adding a manager anywhere in Canada is one registry row.",254 overview: [255 "Rent·Ka continuously aggregates rental listings published by Canadian property managers, REITs and national portals — Ontario first, national expansion in progress. Every listing keeps its photos, price, availability and a direct link to the original ad. It launched 2026-08-27 with roughly 9,000 published listings across eight provinces.",256 "Forked from Lou·Ka, it organizes 81 connectors into three families. Platform generators (53) cover LiftSystem/Rentsync, RentCafe, Buildium and AppFolio — one JSON client registry per platform, so adding a property manager anywhere in Canada means appending a single client row with its province. National landlords (12) bring whole portfolios: Boardwalk, CAPREIT, Minto, Morguard, Killam and more. National portals (5) — Rentals.ca, Zumper, Kijiji, Apartments.com, Facebook Marketplace — cover major metros in every province.",257 "Canada-wide enrichment kept from Lou·Ka: KA Scores (walk/transit/bike/quiet/services from OSM), fair rental value, building passports, listing history, re-listed-unit detection, a Winter Score, photo audits and manager profiles. Everything Quebec-only was removed, and a central French-to-English label funnel keeps the database uniformly English — Quebec's “n½” unit notation converts automatically.",258 ],259 stats: [260 { value: "~9,000", label: "Listings at launch" },261 { value: "8", label: "Provinces covered" },262 { value: "81", label: "Connectors" },263 { value: "53", label: "Platform generators" },264 { value: "12", label: "National landlords" },265 ],266 features: [267 {268 title: "Platform-registry expansion",269 description:270 "Find a property manager on LiftSystem, RentCafe, Rentsync, Buildium or AppFolio and add one client row — the platform connector does the rest.",271 },272 {273 title: "National landlord portfolios",274 description:275 "Dedicated connectors for Canada's biggest residential owners pull their full inventory outside Quebec, AB/SK/BC/MB/NS/NB included.",276 },277 {278 title: "KA Scores across Canada",279 description:280 "Walk, transit, bike, quiet and services scores computed from OpenStreetMap for any Canadian address — no Quebec dependency.",281 },282 {283 title: "Fair rental value & unit history",284 description:285 "Market-value badges, building passports, listing history and re-listed-unit detection carried over from the Lou·Ka engine.",286 },287 {288 title: "Uniformly English data",289 description:290 "A FR→EN label funnel in the schema finalizer translates amenities and availability coming from fr-ca templates; canonical unit types from Studio to Room.",291 },292 {293 title: "Winter Score",294 description:295 "A Canada-appropriate metric grading each building for winter livability.",296 },297 ],298 stack: [299 { category: "Backend", items: ["Python (rentka)", "FastAPI", "SQLite", "Nominatim geocoding"] },300 { category: "Frontend", items: ["React", "Vite", "English (en-CA)", "cobalt skin", "Ka Maps"] },301 { category: "Platform", items: ["PM2 (web / sync 60 min / ngrok)", "snapshot tests on recorded fixtures"] },302 ],303 },304 {305 slug: "auto-ka",306 headline: "Quebec's used vehicles, tracked at the dealership source",307 subheadline:308 "A connector per dealership — no resold listing platforms — with arrivals, price drops and sales detected automatically, VIN dedup, and safety recalls cross-referenced on every vehicle.",309 overview: [310 "Auto·Ka is an independent used-vehicle aggregator covering the province of Quebec. Instead of opening dozens of dealership sites, one dedicated connector per business visits each site at the source, normalizes every vehicle to a single schema and detects changes continuously. Dealer sites offer no webhooks, so periodic sync plus content hashing reproduces them: arrivals, price drops and sales are detected automatically, and a vehicle that disappears returns a true 410 Gone.",311 "As of 2026-08-24 the inventory counts 48,388 vehicles from 138 dealerships (129 active sources on a 143-source registry) across Quebec's 18 regions, with 16,969 safety recalls cross-referenced and 10,158 VIN duplicates masked. Three verticals share one engine: cars, motorcycles and scooters each get dedicated tabs through a `kind` field that traverses the whole pipeline.",312 "Fidelity is a rule: no invented prices (a vehicle without a displayed price shows “Price on request”), polite crawling with identified User-Agent, and connector families for the major dealer-site platforms (D2C Media, SM360, AMVOQ, Convertus, HGrégoire…) — adding a dealership is a ~6-line connector subclass.",313 ],314 stats: [315 { value: "48,388", label: "Vehicles" },316 { value: "138", label: "Dealerships" },317 { value: "129", label: "Active sources" },318 { value: "18", label: "Regions" },319 { value: "16,969", label: "Recalls referenced" },320 { value: "10,158", label: "VIN duplicates masked" },321 ],322 features: [323 {324 title: "Price-drop tracking",325 description:326 "The content-hash diff engine detects new / changed / sold on every sync, with a grace period and drift detection — every price change is historized.",327 },328 {329 title: "VIN deduplication",330 description:331 "The same vehicle advertised on several sites is detected by VIN and masked, keeping one listing with all sources.",332 },333 {334 title: "Safety recalls",335 description:336 "Manufacturer recalls are cross-referenced per vehicle (16,969 referenced), alongside a decoded VIN sheet (NHTSA).",337 },338 {339 title: "Market analysis per listing",340 description:341 "A price/km scatter plot situates each vehicle against the market, plus a composite KA Score and similar vehicles across all sources.",342 },343 {344 title: "Three verticals, one engine",345 description:346 "Cars, motorcycles and scooters flow through the same pipeline with dedicated tabs and JSON-LD types.",347 },348 {349 title: "Massive programmatic SEO",350 description:351 "Server-rendered pages per make, region, city and body style, dynamic sitemaps with real lastmod, sold → 410.",352 },353 ],354 stack: [355 { category: "Backend", items: ["Python 3.14", "FastAPI", "SQLite", "BeautifulSoup", "Firecrawl/Scrapfly fallback"] },356 { category: "Frontend", items: ["React 18", "Vite", "TypeScript", "racing-orange editorial design"] },357 { category: "Platform", items: ["PM2 (web / watch 2h / ngrok)", "reportlab + fpdf2 PDF reports", "KA ID SSO"] },358 ],359 },360 {361 slug: "job-ka",362 headline: "Every job from Quebec employers, straight from their ATS",363 subheadline:364 "969 direct employer connectors across 21 applicant-tracking platforms — the original career-page offer always wins over reposted portal listings.",365 overview: [366 "Big job boards mix paid ads, reposted duplicates and dead offers; the only reliable source is the employer's own career page. Job·Ka plugs directly into the applicant-tracking systems of Quebec employers: 969 direct employer connectors across 21 ATS platforms (Workday, SmartRecruiters, Dayforce, Greenhouse, Lever, BambooHR and more), complemented by three public portals (Guichet-Emplois, Jobillico, Espresso-Jobs) — the direct offer always wins.",367 "As of 2026-08-24 the base holds 21,492 active offers from 1,653 employers (963 sources), of which 19,856 are direct offers and 6,856 display a salary (average ≈ $62,283/yr) — salaries normalized to $/h and $/yr, never invented: parsing requires an explicit currency sign or unit, with plausibility bounds and a change log.",368 "Connectors are auto-discovered — any BaseConnector subclass with a source_id is registered automatically, so plugging a new employer on a known ATS platform takes about ten lines. A diff engine compares content hashes on every sync: an offer missing for two syncs goes inactive (never deleted), and if a source returns a quarter of its historical median, removals are suspended and an alert raised. Compliance is documented per connector: 995 generated compliance sheets, no candidate personal data, ever.",369 ],370 stats: [371 { value: "21,492", label: "Active offers" },372 { value: "1,653", label: "Employers" },373 { value: "969", label: "Direct ATS connectors" },374 { value: "21", label: "ATS platforms" },375 { value: "6,856", label: "With posted salary" },376 { value: "$62,283", label: "Average posted salary" },377 ],378 features: [379 {380 title: "Direct-from-employer offers",381 description:382 "19,856 offers come straight from career pages and ATS APIs; portal listings only complement, never override.",383 },384 {385 title: "Salaries normalized, never invented",386 description:387 "parse_salary() requires explicit currency or unit, applies plausibility bounds, converts $/h ↔ $/yr and logs every change.",388 },389 {390 title: "Ten-line connectors",391 description:392 "Auto-discovery via pkgutil: a new employer on a known ATS platform is a ~10-line subclass with throttling and an identifiable JobKaBot User-Agent.",393 },394 {395 title: "Anti-drift diff engine",396 description:397 "Offers absent two syncs go inactive (never deleted); a source below 25% of its historical median suspends removals and raises an alert.",398 },399 {400 title: "Geocoded job map",401 description:402 "16,303 offers geocoded via Nominatim with the official Adresses Québec fallback, served as GeoJSON on a MapLibre map.",403 },404 {405 title: "Employer self-serve",406 description:407 "A direct-submission form with manual moderation lets employers publish without an ATS.",408 },409 ],410 stack: [411 { category: "Backend", items: ["Python", "FastAPI", "SQLite", "pkgutil auto-discovery", "74 offline pytest tests"] },412 { category: "Frontend", items: ["Editorial premium design", "MapLibre", "ka-ui"] },413 { category: "Platform", items: ["PM2 + ngrok", "KA ID SSO", "PDF reports (kacharts/kapdf)"] },414 ],415 docUrl: "https://www.job-ka.com/doc/",416 },417 {418 slug: "food-ka",419 headline: "Grocery prices tracked at the source, comparable at last",420 subheadline:421 "A connector per grocery banner normalizes every product to a single schema with a comparable unit price in $/100 g, and historizes every price change.",422 overview: [423 "Comparing grocery prices normally means opening Metro, IGA, Maxi, Super C, Provigo, Walmart — each with its own navigation, cart and format. Food·Ka inverts the problem: one dedicated connector per banner visits each site, normalizes every product to a single schema with a comparable unit price in $/100 g, and detects price changes continuously, historizing every variation in a price log.",424 "As of 2026-08-24 the catalogue counts 50,892 products from 57 sources in 18 canonical categories, including 8,818 products on sale — major banners as well as specialized and independent grocers (Mayrand, Avril, PA, Tau, Giant Tiger, SAQ…). Each product page shows equivalents at other banners through a cross-banner matching engine.",425 "Fidelity rules mirror the rest of the ecosystem: no invented prices (null when absent), inconsistent regular prices rejected, throttled requests with an identified User-Agent, and every non-connectable banner documented with its reason in the source registry. The PWA front end is mobile-first with a real-time ticker and the shared ka-ui design system.",426 ],427 stats: [428 { value: "50,892", label: "Products" },429 { value: "57", label: "Sources" },430 { value: "18", label: "Categories" },431 { value: "8,818", label: "On sale" },432 { value: "$/100 g", label: "Comparable unit price" },433 ],434 features: [435 {436 title: "Comparable unit prices",437 description:438 "Every product is reduced to $/100 g so a 340 g jar and a 500 g jar can actually be compared.",439 },440 {441 title: "Sale detection & price history",442 description:443 "Current vs regular price, sort by discount, and a complete historized log of every price variation.",444 },445 {446 title: "Cross-banner comparison",447 description:448 "A matching engine shows each product's equivalents at other banners directly on its page.",449 },450 {451 title: "Nutrition enrichment",452 description:453 "Product pages enriched with nutritional data.",454 },455 {456 title: "Advanced grocery filters",457 description:458 "Category, banner, brand, price presets, format (weight/volume/unit) and claims (organic, local, gluten-free, vegan, lactose-free) with live facet counters.",459 },460 {461 title: "Installable PWA",462 description:463 "Mobile-first editorial-sharp design with a real-time ticker, KA Tabbar, and the KA Agent chat widget.",464 },465 ],466 stack: [467 { category: "Backend", items: ["Python 3.14", "FastAPI", "SQLite (WAL)", "price_log / sync_log"] },468 { category: "Connectors", items: ["Server-rendered HTML", "Shopify products.json", "WooCommerce Store API", "__NEXT_DATA__", "Scrapfly/Firecrawl fallback"] },469 { category: "Frontend", items: ["React 18", "Vite", "TypeScript", "PWA", "ka-ui"] },470 ],471 },472 {473 slug: "resto-ka",474 headline: "Every restaurant, every dish, every price — real takeout prices",475 subheadline:476 "The exhaustive aggregator of Quebec restaurants: menus captured on the restaurants' own ordering platforms, never on delivery apps and their 25–30% markups.",477 overview: [478 "Resto·Ka aggregates Quebec's restaurants across all 17 administrative regions: every resto, every dish, every price — searchable by restaurant or by dish. Prices are real, unmarked takeout prices captured on the restaurants' own ordering platforms, not on delivery apps (which inflate 25–30%). A price is never shown without its context (dine-in / takeout / delivery), and a menu without a price context is rejected at ingestion.",479 "As of 2026-08-24: 14,716 active restaurants (OpenStreetMap discovery, 17/17 regions), 149,569 priced dishes, 1,682 captured menus, 180 identified chains including 116 discovered UEAT integrations, 2,994 MAPAQ inspections imported, 1,859 liquor licences (RACJ), 155,312 price-history entries, 80% of items with photos and 100% of restaurants geolocated.",480 "Dish search groups results by brand so a chain's poutine doesn't repeat dozens of times; options and size supplements are captured because they change the real price; and menu protection rules ensure a dine-in menu is never overwritten by a delivery menu. Official enrichments (MAPAQ inspections, liquor permits) and review crossings (Yelp, Uber Eats) round out each listing.",481 ],482 stats: [483 { value: "14,716", label: "Active restaurants" },484 { value: "149,569", label: "Priced dishes" },485 { value: "1,682", label: "Menus captured" },486 { value: "116", label: "UEAT chain integrations" },487 { value: "2,994", label: "MAPAQ inspections" },488 { value: "17/17", label: "Regions covered" },489 ],490 features: [491 {492 title: "Real prices, in context",493 description:494 "Every price carries its context (dine-in / takeout / delivery); menus without context are rejected, and delivery never overwrites dine-in.",495 },496 {497 title: "Search by dish",498 description:499 "Full search across 149,569 items, grouped by brand so chains don't flood the results.",500 },501 {502 title: "Price history per item",503 description:504 "155,312 historized entries track every menu-price change over time.",505 },506 {507 title: "OpenStreetMap discovery",508 description:509 "Overpass sweeps found 13,427 named establishments across the 17 regions; a templated UEAT GraphQL connector captures real takeout menus for 116 chains.",510 },511 {512 title: "Official enrichments",513 description:514 "MAPAQ health inspections matched to restaurants and RACJ liquor permits, plus Yelp ratings and Uber Eats crossings marked as delivery-priced.",515 },516 {517 title: "Drift protection",518 description:519 "Abnormal drops in a source's volume or a menu's item count suspend removals and keep the previous menu.",520 },521 ],522 stack: [523 { category: "Backend", items: ["Python", "FastAPI", "SQLite", "Nominatim + Adresses Québec geocoding"] },524 { category: "Discovery", items: ["OpenStreetMap Overpass", "UEAT GraphQL", "Serper /maps site-finder", "Scrapfly"] },525 { category: "Frontend", items: ["Editorial premium v2", "ka-ui", "KA Tabbar", "KA Agent widget"] },526 ],527 },528 {529 slug: "fabri-ka",530 headline: "All Quebec-made products. One place.",531 subheadline:532 "385K products from 1,582 online stores across the 17 regions — one connector per e-commerce platform, an A–E origin classification with kept evidence, and no sales on Fabri·Ka itself.",533 overview: [534 "Fabri·Ka is the directory of Quebec-made products: a discovery aggregator indexing 385,308 products (as of 2026-08-24) from 1,582 online stores, covering all 17 administrative regions. Every product links to its original store — Fabri·Ka sells nothing; prices, photos and stock belong to the source merchants.",535 "Buying local normally requires knowing hundreds of scattered stores — sugar shacks, microbreweries, soap makers, woodworkers, roasters, farms. Fabri·Ka inverts the problem: a discovery pipeline catalogues Quebec's online stores (4,082 verified in the registry), platform connectors ingest their full public catalogues, and one search engine makes them findable — filtered by category, region and manufacturing-origin class (A–E, each store justified by kept evidence such as Aliments du Québec certifications).",536 "Unlike a classic aggregator (one connector per site), Fabri·Ka uses one connector per e-commerce platform: the same Shopify code serves hundreds of stores, driven by the store registry. Nine platform connectors cover Shopify, WooCommerce, Wix, Squarespace, Square, Votresite.ca and a generic JSON-LD fallback — with accent-insensitive FTS5 search over the whole catalogue and 385,000+ indexable SEO pages.",537 ],538 stats: [539 { value: "385,308", label: "Products" },540 { value: "1,582", label: "Live stores" },541 { value: "4,082", label: "Verified stores in registry" },542 { value: "17/17", label: "Regions" },543 { value: "20", label: "Categories" },544 { value: "9", label: "Platform connectors" },545 ],546 features: [547 {548 title: "One connector per platform",549 description:550 "The same Shopify connector serves 715 stores, WooCommerce 545, Wix 302 — the store registry does the routing, not custom code.",551 },552 {553 title: "A–E origin classification",554 description:555 "Each store's Quebec-made claim is graded with kept evidence: certifications, association memberships, site wording.",556 },557 {558 title: "Discovery pipeline",559 description:560 "35+ sources — directory sitemaps, hidden map APIs, htmx pagination, Firecrawl sessions — feed a harvest → verify → classify pipeline into the 4,082-store registry.",561 },562 {563 title: "Accent-insensitive search",564 description:565 "SQLite FTS5 full-text search over 385K products with category, region, origin and price filters.",566 },567 {568 title: "Store profiles",569 description:570 "Logo, region, platform, price stats, shipping policy extracted from policy pages, and similar stores.",571 },572 {573 title: "Programmatic SEO",574 description:575 "385,000+ indexable pages with full HTML on first request, JSON-LD, exhaustive sitemaps and clean 301/404/410.",576 },577 ],578 stack: [579 { category: "Backend", items: ["Python 3.14", "FastAPI", "SQLite + FTS5 (3.2 GB)", "content-hash diffing"] },580 { category: "Connectors", items: ["Shopify", "WooCommerce", "Wix GraphQL", "Squarespace", "Square", "Votresite.ca", "generic JSON-LD", "Scrapfly/Firecrawl"] },581 { category: "Frontend", items: ["React 18", "Vite", "TypeScript", "Fraunces serif DA v3", "ka-ui"] },582 ],583 },584 {585 slug: "sorti-ka",586 headline: "Every outing in Quebec's 17 regions, updated hourly",587 subheadline:588 "An independent event aggregator — a faithful index with direct links to the box office or original source: no invented prices, no guessed dates, every listing attributed.",589 overview: [590 "Finding something to do in Quebec normally means opening ten sites: box offices only show their own shows, municipal calendars their own city, tourist sites their members. Sorti·Ka inverts the problem: one dedicated connector per source visits each calendar, normalizes every event to a single schema, deduplicates across sources and detects changes continuously — with hourly resync.",591 "After the 2026-08-25 connector wave, the platform tracks 22,900+ active events from 61 active sources across 332 cities in all 17 administrative regions, including thousands of free events. Sources span box offices (evenko, Ticketpro, Eventbrite…), official open data (SIT Québec, Montreal CKAN), venues and broadcasters (Place des Arts, La Vitrine), and regional portals — with every abandoned source documented with evidence in the registry.",592 "Sorti·Ka is not a box office: it is a faithful index. Cross-source dedup fingerprints title + city + date so one concert published by three sources becomes one card (the richest listing wins). A municipal repertory of 1,250 cities resolves homonyms by population and attaches every event to its region. SSR with JSON-LD Event markup covers SEO, and 69 pytest tests run on real recorded fixtures with zero network.",593 ],594 stats: [595 { value: "22,900+", label: "Active events" },596 { value: "61", label: "Active sources" },597 { value: "332", label: "Cities" },598 { value: "17/17", label: "Regions" },599 { value: "3,614+", label: "Free upcoming events" },600 { value: "Hourly", label: "Resync cadence" },601 ],602 features: [603 {604 title: "Cross-source deduplication",605 description:606 "Title + city + date fingerprinting merges duplicate events; the richest listing wins the card.",607 },608 {609 title: "Direct-to-source links",610 description:611 "Every listing links to the box office or original calendar — no invented prices, original price labels preserved.",612 },613 {614 title: "Municipal repertory",615 description:616 "1,250 cities, boroughs and aliases from MAMH, homonyms resolved by population, automatic attachment to the 17 regions.",617 },618 {619 title: "Quick access & geo filters",620 description:621 "Tonight / weekend / free / near-me shortcuts, a near=lat,lng filter with distance sorting, and list|map results.",622 },623 {624 title: "Robust persistence",625 description:626 "Content-hash upserts, a two-sync grace period before removal, drift alerts and a quality quarantine.",627 },628 {629 title: "Offline test suite",630 description:631 "69 pytest tests replay real recorded fixtures — connectors, normalization, database, auth — with zero network.",632 },633 ],634 stack: [635 { category: "Backend", items: ["Python", "FastAPI", "SQLite", "hourly PM2 watcher"] },636 { category: "Sources", items: ["Box-office APIs", "Open data (CKAN, Tourinsoft)", "JSON-LD venues", "Apify actor", "Oxylabs→Scrapfly→Bright Data"] },637 { category: "Frontend", items: ["Cultural-guide v2 design", "Leaflet on demand", "ka-ui", "KA Tabbar"] },638 ],639 docUrl: "https://www.sorti-ka.com/doc/",640 },641 {642 slug: "crea-ka",643 headline: "Quebec's creators and all their links, in one public directory",644 subheadline:645 "A searchable directory crossed with a collective link-in-bio: one canonical profile per creator grouping every public account, with metrics and a link-confidence score.",646 overview: [647 "Créa·Ka is the public, Quebec-focused, cross-platform directory of content creators — a cross between a searchable directory and a collective Linktree. As of 2026-08-24: 12,791 creators and 18,942 linked accounts across 19 platforms. Each Quebec creator gets one canonical profile grouping all their public accounts — Instagram, TikTok, YouTube, Twitch, X, Facebook, Snapchat, Kick, Substack, Patreon, podcasts and more — each with canonical URL, metrics (followers, posts, likes, views, episodes) and a link-confidence score.",648 "The audience is threefold: the public discovering creators by niche, region, language or audience size; creators themselves (profile claims, opt-out); and brands or media looking for a public directory where existing databases are paid, generalist and anglophone.",649 "Ethics come first: public and professional profiles only, private-data purge, immediate and persistent opt-out, a restricted regime for minors, and Law 25 compliance. Discovery runs through connectors (Twitch public GraphQL, Kick via Scrapfly, bio-declared cities) and 13 custom Apify actors enriching profiles across platforms.",650 ],651 stats: [652 { value: "12,791", label: "Creators" },653 { value: "18,942", label: "Linked accounts" },654 { value: "19", label: "Platforms" },655 { value: "13", label: "Custom Apify actors" },656 { value: "51", label: "pytest tests" },657 ],658 features: [659 {660 title: "Canonical creator profiles",661 description:662 "One profile per creator groups every public account with its metrics and a link-confidence score for each attachment.",663 },664 {665 title: "Cross-platform metrics",666 description:667 "Followers, posts, likes, views and episodes tracked per account across 19 platforms.",668 },669 {670 title: "Discovery connectors",671 description:672 "Twitch public GraphQL discovery, Kick via Scrapfly with self-declared link verification, and region attribution from declared bios.",673 },674 {675 title: "Apify enrichment fleet",676 description:677 "13 custom actors (residential proxies) enrich Instagram, TikTok, X, YouTube, Twitch, Kick, Fansly, Facebook, Threads and Snapchat profiles.",678 },679 {680 title: "Ethics by design",681 description:682 "Public professional profiles only, purge of private data, instant persistent opt-out, restricted regime for minors, Law 25 compliance.",683 },684 {685 title: "Search by niche & region",686 description:687 "Filter by niche, region, language and audience size — the discovery layer Quebec's creator economy lacked.",688 },689 ],690 stack: [691 { category: "Backend", items: ["Python 3.14", "FastAPI", "SQLite (WAL)", "51 pytest tests"] },692 { category: "Enrichment", items: ["13 Apify actors", "Twitch GraphQL", "Scrapfly"] },693 { category: "Frontend", items: ["Zero-build SPA", "ka-ui", "KA Agent widget"] },694 ],695 },696 {697 slug: "trouve-ka",698 headline: "A real search engine, built from scratch in Quebec",699 subheadline:700 "Not a metasearch: crawler, frontier, parser, classification, index, ranking and semantics are all homegrown — zero dependency on Google, Bing or Brave for results.",701 overview: [702 "Trouve·Ka is a real search engine — not a metasearch. Crawler, frontier, parser, Quebec classification, index, ranking, semantics: everything is built in-house, with no dependency on Google, Bing or Brave for results. Born as an open Quebec-web engine (64 high-authority seeds, 7,898 discovered domains), it pivoted on 2026-08-23 to become the search engine of Groupe Ka: it continuously indexes the ecosystem's 14 sites, fed by daily sitemap ingestion — the frontier alone exceeds 4.6M pending URLs.",703 "The engine's motto: crawl continuously, index immediately, search immediately, improve asynchronously. Every fetched page is scored deterministically for Quebec relevance (TLDs, toponyms, postal codes, area codes, known organizations, language — no LLM in the hot path) and indexed inline in OpenSearch: searchable in about 2–4 seconds. Enrichment — domain authority, entities, embeddings, reranking — arrives afterwards via Redis Streams without ever blocking, with 100% semantic coverage of the index.",704 "In production: 302,000+ pages indexed (and growing by 100K+ on good days), bilingual BM25 ranking with FR/EN synonyms (thermopompe ↔ heat pump), semantic search plus a dedicated reranker, and 258–425 ms measured latency with both active. The crawl is polite and self-healing: an identified TrouveKABot honoring robots.txt and crawl delays, SSRF guards, crawl-trap detection, and nine workers across five cluster nodes coordinated without an orchestrator through Postgres FOR UPDATE SKIP LOCKED — proven to survive node reboots on its own.",705 ],706 stats: [707 { value: "302K+", label: "Pages indexed" },708 { value: "14", label: "KA sites indexed" },709 { value: "4.6M", label: "Frontier URLs" },710 { value: "100%", label: "Semantic coverage" },711 { value: "9", label: "Crawl workers / 5 nodes" },712 { value: "~2–4 s", label: "Crawl-to-searchable" },713 ],714 features: [715 {716 title: "Immediate indexing",717 description:718 "Fetch → parse → score → index inline (OpenSearch refresh 1 s): a page is searchable seconds after being crawled; enrichment never blocks.",719 },720 {721 title: "Deterministic Quebec scoring",722 description:723 "TLDs, toponym gazetteer, postal codes, area codes, known organizations, JSON-LD and language — no LLM in the hot path, and the open-web mode is one config flag away.",724 },725 {726 title: "Bilingual semantic ranking",727 description:728 "BM25 FR/EN with bilingual synonyms + Quebec scores + domain authority + freshness + locality boost, then embeddings and a reranker on top.",729 },730 {731 title: "Polite, transparent crawler",732 description:733 "Identified TrouveKABot with a public page, robots.txt and Crawl-delay honored, per-host politeness locks, SSRF guard, crawl-trap detection.",734 },735 {736 title: "Self-healing distributed crawl",737 description:738 "Nine workers on five nodes with no orchestrator — Postgres SKIP LOCKED + Redis locks, SSH tunnels between nodes, watchdogs, proven reboot survival.",739 },740 {741 title: "Real public metrics",742 description:743 "No simulated counters, by project rule: /status and /stats expose the live engine, refreshed every 10 seconds.",744 },745 ],746 stack: [747 { category: "Engine", items: ["Python", "OpenSearch 2.17", "PostgreSQL frontier", "Redis Streams", "selectolax"] },748 { category: "Semantics", items: ["Embedding service", "Reranker (dedicated node)", "100% index coverage"] },749 { category: "Frontend", items: ["Next.js proxy", "FastAPI API", "ka-ui"] },750 ],751 docUrl: "https://www.trouve-ka.com/doc/index.html",752 },753 {754 slug: "api-ka",755 headline: "The data layer of the ecosystem — collectors, API, and the KA Agent",756 subheadline:757 "Nine daily collectors persist every platform's data into unified PostgreSQL, exposed through a public FastAPI — plus the ecosystem's conversational agent and connector supervision.",758 overview: [759 "API·Ka is the central data platform of the Groupe Ka ecosystem. Every day, nine collectors (Lou·Ka, Immo·Ka, Food·Ka, Auto·Ka, Fabri·Ka, Resto·Ka, Sorti·Ka, Créa·Ka, Job·Ka) persist the platforms' data into a unified PostgreSQL base — fetch → validation → checksum → insert → backup → run journal, with 3× retry and exponential backoff — then expose it through a public FastAPI: paginated data, per-date history, statistics and PDF reports.",760 "It also hosts the KA Agent — the group's central AI assistant (Claude Haiku 4.5, SSE streaming, a tool loop of 24+ tools wired to the platforms' live public APIs) served as an embeddable widget to the ecosystem's 13 domains — and acts as the connector supervisor: roughly 3,270 connectors tracked with collection history, per-service health and alerts.",761 "Over a recent 7-day window: 63 of 63 collections succeeded, 4.16M records collected, 6,196 API calls served. Product API access requires authentication — a KA ID session or a personal kapi_ bearer token generated on groupe-ka.com — while monitoring, stats and the agent remain open. A daily backfill catches missed dates, and timestamped per-service backups are retained for 90 days.",762 ],763 stats: [764 { value: "9", label: "Daily collectors" },765 { value: "63/63", label: "Collections OK (7 days)" },766 { value: "4.16M", label: "Records / 7 days" },767 { value: "~3,270", label: "Connectors supervised" },768 { value: "24+", label: "KA Agent tools" },769 ],770 features: [771 {772 title: "Daily collection pipeline",773 description:774 "Nine parallel independent collectors at 02:00 with validation, checksums, 3× retry with backoff, run journal and automatic 7-day backfill.",775 },776 {777 title: "Public data API",778 description:779 "Paginated per-service data, latest and per-date snapshots, stats and run history — secured by KA ID session or kapi_ bearer token.",780 },781 {782 title: "KA Agent",783 description:784 "Claude-powered SSE chat with a growing tool loop (24 → 33 tools) over live platform data, served as an embeddable widget to all 13 domains.",785 },786 {787 title: "Connector supervision",788 description:789 "~3,270 connectors across the ecosystem tracked with per-service health, statuses (ok/degraded/broken/retired) and alerts.",790 },791 {792 title: "Ecosystem PDF reports",793 description:794 "Per-platform dashboards and a consolidated ecosystem report, plus custom report building from a block catalogue.",795 },796 {797 title: "Native-app auth exchange",798 description:799 "SSO endpoints for KA ID plus a token exchange for the iOS/Android apps (HS256, audience-scoped).",800 },801 ],802 stack: [803 { category: "Backend", items: ["Python 3.11+", "FastAPI + Uvicorn", "PostgreSQL", "SQLAlchemy 2 + Alembic", "APScheduler"] },804 { category: "AI", items: ["Anthropic SDK", "Claude Haiku 4.5", "SSE streaming", "fuzzy search cascade"] },805 { category: "Platform", items: ["PM2 (api / scheduler / ngrok)", "daily backups (90-day retention)", "pytest"] },806 ],807 docUrl: "https://www.api-ka.com/doc/",808 },809 {810 slug: "ka-stats",811 headline: "The observatory that makes the whole ecosystem explorable",812 subheadline:813 "A zero-dependency Node server aggregates the live dashboards of the public platforms and renders them with QCharts — including a custom-indicator studio over a 227-metric catalogue.",814 overview: [815 "Ka·Stats is the statistics observatory of the ecosystem: it aggregates, live, the standardized dashboards (ka-stats v2 contract) of the public platforms — Lou·Ka, Immo·Ka, Vrai-Prix, Auto·Ka, Job·Ka, Food·Ka, Resto·Ka, Fabri·Ka, Sorti·Ka, Créa·Ka, Trouve·Ka, API·Ka — and makes them explorable in one place: an ecosystem overview with its pulse and records, full per-platform dashboards, themed indicators, comparisons and rankings.",816 "The server is a zero-dependency Node process: static serving plus an aggregating proxy with a 10-minute memory+disk cache and stale-while-error behaviour — if a platform goes down, its last good copy keeps serving. The front end is a vanilla SPA rendering everything with QCharts, a homegrown SVG chart library following the ka-ui design system and dataviz rules: hairline grids, twin table views on every chart, validated categorical palette.",817 "Charts are interactive — brush zoom, clickable legends, type switchers, CSV/PNG exports — and the /studio page is a custom-indicator builder: a catalogue of 227 metrics flattened from the dashboards, transformations (index 100, % change, moving average, cumulative), two-metric combinations, and shareable URLs.",818 ],819 stats: [820 { value: "12+", label: "Platforms aggregated" },821 { value: "227", label: "Metrics in the studio catalogue" },822 { value: "0", label: "npm dependencies" },823 { value: "10 min", label: "Cache (stale-while-error)" },824 ],825 features: [826 {827 title: "Ecosystem overview",828 description:829 "The pulse of the ecosystem, a platform grid, live Quebec prices and records — millions of data points summarized on one page.",830 },831 {832 title: "Generic dashboard renderer",833 description:834 "Renders the full ka-stats v2 contract: KPIs with sparklines, gauges, multi-series charts, stacked areas, rings, histograms, geo, calendar and hourly heatmaps, sortable tables.",835 },836 {837 title: "Indicator studio",838 description:839 "Build custom indicators from 227 catalogued metrics with transformations and combinations, saved locally and shareable by URL.",840 },841 {842 title: "Cross-platform comparison",843 description:844 "Up to four platforms on one axis, indexed to base 100.",845 },846 {847 title: "QCharts SVG engine",848 description:849 "Homegrown vanilla-SVG charts with brush zoom, clickable legends, chart-type switching and CSV/PNG export — no charting library.",850 },851 {852 title: "Resilient aggregation",853 description:854 "Memory + disk cache with stale-while-error: a platform outage never blanks its dashboard.",855 },856 ],857 stack: [858 { category: "Server", items: ["Node (zero dependencies)", "10-min cache", "healthz"] },859 { category: "Frontend", items: ["Vanilla SPA", "History API router", "QCharts (SVG)", "ka-ui tokens"] },860 { category: "Platform", items: ["PM2 + ngrok", "SSR SEO metas", "JSON-LD"] },861 ],862 },863 {864 slug: "ka2",865 headline: "The light edition of the Quebec web knowledge-graph explorer",866 subheadline:867 "An AI-driven scraper + search bot mapping the Quebec web as a knowledge graph — entities, attributes and typed relations — at the economical tier: Haiku-controlled, 6 concurrent, ~800 pages/day.",868 overview: [869 "ka2 is an AI-driven scraper and search bot that maps the Quebec web as a knowledge graph: entities (companies, organizations, people, creators, agencies, brands…), their attributes and their typed relations. Groupe Ka operates three twin bots sharing the same engine at three tiers — ka2 is the light, economical edition (lime-green theme), controlled by Claude Haiku 4.5 with 6 concurrent missions and about 800 pages a day.",870 "Missions launched from the live dashboard drive a Claude agent that plans, searches and deep-dives through tools — search_web, map_site, scrape_page, deep_dive, crawl_queue. Fetching goes through Firecrawl with a Scrapfly anti-bot fallback, guarded by robots.txt, rate limits, fail-fast and a circuit breaker. A Haiku extractor turns each page's markdown into graph fragments — entities and typed relations — which pass through entity resolution with provenance before landing in SQLite (WAL).",871 "The result is browsable on the public dashboard at ka2.bot: a real-time board and a structured directory with an interactive global graph.",872 ],873 stats: [874 { value: "Haiku 4.5", label: "Controller model" },875 { value: "6", label: "Concurrent missions" },876 { value: "~800", label: "Pages / day" },877 { value: "Lime", label: "Theme" },878 ],879 features: [880 {881 title: "Agent-driven missions",882 description:883 "A Claude agent plans, searches and deep-dives autonomously, steering the crawl through a tool loop instead of fixed scripts.",884 },885 {886 title: "Knowledge-graph extraction",887 description:888 "A Haiku extractor converts scraped markdown into entities and typed relations, with entity resolution and per-fact provenance.",889 },890 {891 title: "Resilient fetching",892 description:893 "Firecrawl primary with Scrapfly anti-bot fallback, robots.txt respect, rate limiting, fail-fast and a circuit breaker.",894 },895 {896 title: "Live dashboard",897 description:898 "Real-time board plus a structured directory with an interactive global graph, public at ka2.bot.",899 },900 ],901 stack: [902 { category: "Engine", items: ["Python", "FastAPI", "Claude (agent + extractor)", "SQLite (WAL)"] },903 { category: "Fetching", items: ["Firecrawl", "Scrapfly fallback", "robots.txt + circuit breaker"] },904 { category: "Platform", items: ["ngrok → www.ka2.bot", "shared engine with ka4/ka6"] },905 ],906 },907 {908 slug: "ka4",909 headline: "The aggressive edition of the Quebec web knowledge-graph explorer",910 subheadline:911 "Same engine as ka2, higher tier: Sonnet-controlled, 10 concurrent missions, ~3,000 pages/day — mapping entities and typed relations across the Quebec web.",912 overview: [913 "ka4 is the aggressive edition of Groupe Ka's knowledge-graph explorer — one of three twin bots sharing the same engine. Controlled by Claude Sonnet 5 with 10 concurrent missions and about 3,000 pages a day (red theme), it maps the Quebec web as a knowledge graph: entities, attributes and typed relations, browsable live at ka4.bot.",914 "The pipeline is identical to its siblings: dashboard-launched missions drive a Claude agent through search, mapping, scraping and deep-dive tools; Firecrawl fetches with a Scrapfly anti-bot fallback under robots.txt, rate limits and a circuit breaker; a Haiku extractor produces graph fragments; entity resolution with provenance consolidates them into SQLite.",915 "The stronger controller model and higher concurrency make ka4 the middle tier — more ambitious mission planning and roughly four times ka2's throughput, at a fraction of ka6's volume.",916 ],917 stats: [918 { value: "Sonnet 5", label: "Controller model" },919 { value: "10", label: "Concurrent missions" },920 { value: "~3,000", label: "Pages / day" },921 { value: "Red", label: "Theme" },922 ],923 features: [924 {925 title: "Sonnet-driven planning",926 description:927 "A stronger controller model plans deeper missions and richer deep-dives than the light edition.",928 },929 {930 title: "Shared graph engine",931 description:932 "Same extraction, entity resolution and provenance pipeline as ka2 and ka6 — three tiers, one codebase.",933 },934 {935 title: "4× throughput",936 description:937 "Ten concurrent missions and ~3,000 pages a day position ka4 between the economical and flagship tiers.",938 },939 {940 title: "Live dashboard",941 description:942 "Real-time board and interactive entity graph, public at ka4.bot.",943 },944 ],945 stack: [946 { category: "Engine", items: ["Python", "FastAPI", "Claude Sonnet 5 (agent)", "Claude Haiku (extractor)", "SQLite (WAL)"] },947 { category: "Fetching", items: ["Firecrawl", "Scrapfly fallback", "rate limits + circuit breaker"] },948 { category: "Platform", items: ["ngrok → www.ka4.bot", "shared engine with ka2/ka6"] },949 ],950 },951 {952 slug: "ka6",953 headline: "The flagship Quebec web knowledge-graph explorer",954 subheadline:955 "The top tier of the three twin bots: Sonnet-controlled, 16 concurrent missions, ~9,000 pages/day — the most complete map of Quebec web entities and their relations.",956 overview: [957 "ka6 is the flagship of Groupe Ka's three twin knowledge-graph bots (violet theme). Controlled by Claude Sonnet 5 with 16 concurrent missions and about 9,000 pages a day, it runs the same engine as ka2 and ka4 at maximum throughput — mapping the Quebec web as a knowledge graph of entities (companies, organizations, people, creators, agencies, brands…), attributes and typed relations.",958 "Missions from the live dashboard drive a Claude agent through its tool loop — web search, site mapping, page scraping, deep dives, crawl queueing. Fetching runs Firecrawl-first with a Scrapfly anti-bot fallback, guarded by robots.txt, rate limits, fail-fast and a circuit breaker. A Haiku extractor turns pages into graph fragments; entity resolution with provenance consolidates everything into SQLite (WAL).",959 "As the flagship, ka6 also supervises connector health across ecosystem platforms (its findings feed the guardian workflows), and its dashboard at ka6.bot exposes the largest entity graph of the three bots.",960 ],961 stats: [962 { value: "Sonnet 5", label: "Controller model" },963 { value: "16", label: "Concurrent missions" },964 { value: "~9,000", label: "Pages / day" },965 { value: "Violet", label: "Theme" },966 ],967 features: [968 {969 title: "Maximum throughput",970 description:971 "Sixteen concurrent missions and ~9,000 pages a day — the deepest and fastest-growing entity graph of the three bots.",972 },973 {974 title: "Knowledge-graph engine",975 description:976 "Entities, attributes and typed relations with resolution and provenance — the shared engine at its highest setting.",977 },978 {979 title: "Ecosystem supervision",980 description:981 "The flagship's crawl capacity also monitors connector health across Groupe Ka platforms.",982 },983 {984 title: "Live dashboard",985 description:986 "Real-time board and interactive global graph, public at ka6.bot.",987 },988 ],989 stack: [990 { category: "Engine", items: ["Python", "FastAPI", "Claude Sonnet 5 (agent)", "Claude Haiku (extractor)", "SQLite (WAL)"] },991 { category: "Fetching", items: ["Firecrawl", "Scrapfly fallback", "rate limits + circuit breaker"] },992 { category: "Platform", items: ["ngrok → www.ka6.bot", "shared engine with ka2/ka4"] },993 ],994 },995];996997export function getKaAppDetail(slug: string): KaAppDetail | undefined {998 return kaAppDetails.find((d) => d.slug === slug);999}1000