Scout

wiki/dev-log.md

Scout - Development Log

2026-07-03 — Hosted Admin Metrics Scope

  • Added metric_scope to protected GET /v1/billing/admin/metrics.
  • Added metric_scope to scripts/scout-hosted-admin metrics --format table via the VPS helper.
  • Purpose: make production monitoring honest. Current hosted totals, funnel, and economics are recent-window metrics calculated from bounded rows, not lifetime aggregate accounting.
  • metric_scope reports:
  • scope name: recent_window;
  • row limits for accounts, signup events, usage events, and purchases;
  • returned row counts;
  • truncation flags;
  • explicit note that totals are incomplete by design.
  • Documentation updated in docs/product/hosted-admin-operations.md.
  • Verification:
  • RED failed because metric_scope was missing from the API response;
  • RED failed because the VPS metrics helper did not advertise scope/windowness;
  • focused GREEN checks passed for the API route and script help behavior.
  • Remaining blockers: full lifetime aggregate accounting remains future work; production self-service still needs Stripe and SMTP environment configuration.

2026-07-03 — Hosted Funnel And Economics Monitoring

  • Enhanced protected GET /v1/billing/admin/metrics.
  • Added derived funnel summary:
  • beta registration events;
  • delivered keys;
  • pending delivery;
  • failed delivery;
  • reissued keys;
  • active accounts;
  • beta trial checkouts;
  • paid purchases;
  • paid customers;
  • signup delivery rate;
  • paid-account conversion rate.
  • Added derived economics summary:
  • total revenue;
  • estimated package loaded cost;
  • estimated package gross profit;
  • estimated package gross margin;
  • standard/browser credits used;
  • standard_1000 break-even packages/month;
  • target gross margin.
  • Updated scripts/scout-hosted-admin metrics --format table so operator output includes metric, funnel, economics, and recent_counts sections.
  • Verification:
  • RED failed because /v1/billing/admin/metrics lacked funnel;
  • RED failed again because the VPS metrics helper did not advertise or print funnel/economics;
  • focused GREEN checks passed for the API route and script behavior.
  • Remaining blockers: production still needs SMTP credentials, Stripe secret, Stripe price IDs, webhook secret, VPS config install/restart, SMTP smoke, beta setup smoke, paid checkout smoke, webhook provisioning, and /v1/hosted/me verification.

2026-07-03 — Hosted Economics Admin Command

  • Added scripts/scout-hosted-admin economics.
  • Added scripts/scout-hosted-economics.
  • Purpose: make the current pay-as-you-go model inspectable from the operator terminal without reading docs or secrets.
  • The command prints:
  • $10 for 1,000 standard credits;
  • package rows for beta_trial, standard_1000, standard_3000, standard_15000, and browser_100;
  • gross margin;
  • break-even packages/month;
  • credit policy for scrape, crawl page, screenshot, browser render, and browser minute.
  • Production behavior: if the VPS host Python cannot import Scout dependencies, the command delegates into the running scout Docker container instead of failing silently.
  • Verification:
  • RED failed because scout-hosted-economics was missing and scout-hosted-admin economics returned unknown command;
  • production regression RED then reproduced the VPS host-Python dependency gap and required Docker delegation;
  • GREEN verification passed: focused admin-script checks passed after the fallback was added.
  • Remaining blockers: configure real SMTP delivery and Stripe credentials, install them on the VPS, then run email, beta setup, paid checkout, webhook, and hosted /v1/hosted/me smoke tests.

2026-07-03 — Beta Self-Service Realigned To Card-Backed Setup With Email Fallback

  • Updated the current beta onboarding contract: /beta is the self-service entrypoint for $0 card-backed beta setup when Stripe/webhook/SMTP readiness is true, and it falls back to queued email registration through /v1/hosted/beta-key while checkout is paused.
  • Added superseding ADR: wiki/decisions/2026-07-03-card-backed-beta-with-email-queue-fallback.md.
  • Updated repo docs and public website copy so /beta, /pricing, /quickstart, /v1/billing/stripe/status, and hosted admin docs tell the same story.
  • Verification:
  • TDD red failed because /beta lacked data-checkout-endpoint and still advertised email-only behavior;
  • focused green verification reported 61 passed;
  • Pyright reported 0 errors;
  • Ruff check and format check passed for touched Python/test surfaces.
  • Remaining blockers: install SMTP credentials, Stripe secret, Stripe price IDs, and webhook secret, then run live beta checkout, webhook provisioning, API-key email delivery, /v1/hosted/me, and paid checkout smoke tests.

2026-07-03 — Auditable Pricing Assumptions In Hosted Packages API

  • Added unit_economics_assumptions to GET /v1/billing/packages.
  • The endpoint now returns both calculated package economics and the underlying assumptions:
  • fixed monthly cost;
  • standard-credit cost;
  • browser-credit cost;
  • allocated support cost;
  • payment percent fee;
  • payment fixed fee;
  • target gross margin.
  • Updated website/assets/pricing.js so the pricing page renders assumption cards for standard-credit cost, payment fee, and fixed monthly cost from the live API payload.
  • Updated the repo and vault unit-economics docs so the website/API/vault point at the same code-backed model.
  • Verification:
  • TDD red failed with missing unit_economics_assumptions;
  • focused green verification returned 2 passed, 2 warnings;
  • Pyright returned 0 errors;
  • Ruff check and format checks passed for touched Python files.
  • Remaining blockers: real SMTP, real Stripe secret, real Stripe prices, webhook secret, VPS env install, restart, and live signup/checkout E2E.

2026-07-03 — Stripe Paid Package Price Bootstrap Helper

  • Added scripts/scout-stripe-bootstrap-prices.
  • Added wrapper command: scripts/scout-hosted-admin bootstrap-stripe-prices.
  • Purpose: remove manual Stripe dashboard mismatch risk by creating one-time Stripe prices from Scout's canonical hosted credit package model.
  • Public paid packages covered:
  • standard_1000 -> STRIPE_STANDARD_1000_PRICE_ID
  • standard_3000 -> STRIPE_STANDARD_3000_PRICE_ID
  • standard_15000 -> STRIPE_STANDARD_15000_PRICE_ID
  • Explicitly excluded:
  • beta_trial, because beta uses $0 Checkout setup mode rather than a paid price;
  • browser_100, because browser-credit economics are still private.
  • Safety behavior:
  • dry-run works without STRIPE_SECRET_KEY;
  • live creation requires --yes;
  • --write-env writes created price IDs back to ignored secrets/scout-production.env;
  • output refuses to print Stripe secret-looking values.
  • Verification:
  • python3 -m pytest tests/unit/scripts/test_stripe_price_bootstrap.py tests/unit/scripts/test_vps_admin_scripts.py -q returned 24 passed, 2 warnings;
  • python3 -m pyright tests/unit/scripts/test_stripe_price_bootstrap.py tests/unit/scripts/test_vps_admin_scripts.py returned 0 errors;
  • ruff check and ruff format --check passed for the touched Python tests;
  • scripts/scout-hosted-admin bootstrap-stripe-prices --dry-run --json returned the three expected paid packages and no secret values.
  • Remaining blockers: fill SMTP provider values, provide Stripe secret, run the bootstrap helper to create real Stripe prices, create/install webhook secret, configure VPS env, restart Scout, smoke SMTP delivery, drain pending beta signups, and run Stripe checkout/webhook/key-delivery E2E.

2026-07-03 — Hosted Admin Pending Beta Key Delivery Drain

  • Added service-key protected POST /v1/billing/admin/deliver-pending-beta-keys?limit=25.
  • Purpose: drain queued pending_delivery beta registrations after SMTP is configured and smoke-tested.
  • Behavior:
  • fails closed with 503 when hosted key delivery is not configured;
  • provisions pending testers only when delivery is enabled;
  • emails the one-time raw API key;
  • records admin_pending_beta_delivery signup events;
  • returns only non-secret email/status/tenant ID/key ID/count metadata.
  • Verification:
  • TDD red produced expected 404 failures for the missing endpoint;
  • green verification reported 53 passed, 2 warnings;
  • pyright reported 0 errors;
  • Ruff and format checks passed.
  • Deployment:
  • pushed and deployed commit a1ed9ec to scout.chowmes.com;
  • production health is green;
  • unauthenticated drain returns 403;
  • authenticated drain reaches the route and returns expected 503 Hosted API key delivery is not configured until SMTP settings exist.
  • Remaining blockers: SMTP key delivery config, Stripe Checkout config, Stripe webhook secret, and final paid package Stripe price IDs.

2026-07-03 — Hosted SMTP Delivery Smoke-Test Command

  • Added smoke-test support to hosted API-key delivery requests.
  • Smoke-test delivery uses the same SMTP delivery service but sends a clearly labeled smoke email:
  • no hosted account is created;
  • no credits are granted;
  • no real API key is issued;
  • no raw key or SMTP secret is printed.
  • Added scripts/scout-hosted-admin send-test-email and scripts/scout-vps-send-hosted-test-email.
  • The command is intended to be run after SMTP configuration and before enabling self-service beta testers.
  • This directly supports the production-readiness blocker "hosted API key email delivery not configured" by giving operators a repeatable post-configuration smoke test.
  • Deployed commit 7727814 to scout.chowmes.com.
  • Production smoke passed for deployment health and failed correctly for missing SMTP configuration: scripts/scout-hosted-admin send-test-email --email arijit.chowdhury@gmail.com --name Arijit returned Hosted API key delivery is not configured.

2026-07-03 — Hosted Signup Event Admin Listing

  • Added the hosted operator command scripts/scout-hosted-admin list-signups.
  • Added the VPS helper scripts/scout-vps-list-hosted-signups to query hosted_signup_events from /data/hosted_accounts.sqlite.
  • Supported table and JSON output, row limits, --status filters for delivered, failed, and duplicate, and --email filters for one signup.
  • Kept the script secret-safe: it does not select or print raw API keys or stored key hashes.
  • Updated hosted operations documentation so Arijit can inspect who requested beta keys, whether delivery succeeded, whether the request was duplicate, and why delivery failed.
  • This improves self-service measurement and monitoring; it does not remove the remaining production blockers around SMTP delivery and Stripe secrets.
  • Deployed commit 0983cc0 to scout.chowmes.com.
  • Production smoke passed:
  • /health returned OK;
  • Docker reported the scout container healthy;
  • scripts/scout-hosted-admin list-signups --format json --limit 5 returned the prior failed SMTP signup event and did not expose raw API keys or key hashes.

2026-06-30 — Hosted-First Quickstart And Compact Homepage Proof

  • Reduced the homepage proof block from a large black artifact billboard into a compact output card.
  • Reframed the copy from "Records plus proof" to "Clean records with evidence attached" so the value is clear without consuming most of the first viewport.
  • Reordered /quickstart for the public hosted domain:
  • Path 01 is now hosted beta API at https://scout.chowmes.com;
  • local install is Path 02;
  • Docker is Path 03;
  • localhost examples now appear only under local-machine paths.
  • Added a regression test that verifies the hosted domain appears before any 127.0.0.1 reference on the quickstart page.
  • Verification:
  • python3 -m pytest tests/unit/website/test_launch_website.py -q passed 15 tests;
  • python3 -m pyright scout/ passed with 0 errors;
  • ruff check scout/ tests/ scripts/ and ruff format --check scout/ tests/ scripts/ passed;
  • local FastAPI smoke verified homepage markers and hosted-before-localhost quickstart order;
  • Playwright desktop/mobile render checks had 0 console warnings/errors.

2026-06-29 — Service-First Surface And Old App UI Removal

  • Removed the broken static /app UI from the supported Scout product surface.
  • Deleted the old HTML frontend module and live-browser page module from the repo source.
  • Removed /api/config so the browser no longer has a config route that can leak local-app assumptions.
  • Kept Scout positioned as website + CLI + local HTTP API + hosted API + Docker-from-source + skill + artifacts.
  • Simplified the launch homepage:
  • reduced navigation to Overview, Demo, Features, Use cases, Pricing, Beta;
  • removed the oversized black Run Ledger block;
  • added compact "Records plus proof" framing;
  • emphasized real features, demo, use cases, and beta access over text-heavy operating-model sections.
  • Replaced stale UI-based live target testing with service-level live target tests through the run API and artifact evidence.
  • Verified locally:
  • focused tests: 42 passed;
  • full unit suite: 635 passed;
  • Pyright: 0 errors;
  • Ruff check/format: passed;
  • launch-readiness: private beta ready_with_limits, public launch ready, 0 blockers;
  • fresh local HTTP smoke: /health OK, homepage markers present, /app, /api/config, and /app/live-browser return 403.
  • Pushed commit d27b24e to GitHub branch codex/scout-platform-foundation.
  • Redeployed to the Hostinger VPS and verified https://scout.chowmes.com:
  • /health OK;
  • homepage markers present;
  • /app, /api/config, and /app/live-browser return 403.

2026-06-29 — Hosted VPS SaaS API Recovery

  • Verified SSH to the Hostinger VPS is working again with the saved key.
  • Root cause of the SSH confusion: the VPS was reachable globally, but this Mac was temporarily refused before auth, consistent with fail2ban/provider protection after bad SSH probes. The saved key was not the problem.
  • Found the running Scout container on the VPS, but it was stale and exposed only localhost with no public Caddy route.
  • Added Caddy route: https://judge.contentengagement.info/scout/* -> 127.0.0.1:8421.
  • Redeployed Scout from the current repo source so /v1/hosted/* Bearer-key routes are available.
  • Fixed Docker deployment drift:
  • restored container name scout;
  • bound port 8421 to 127.0.0.1 only;
  • stopped compose from overriding .env secrets with default dev-key;
  • set hosted-only mode for public deployment.
  • Verification passed:
  • /scout/health public returns 200;
  • /scout/v1/hosted/me without Bearer returns 401;
  • /scout/v1/hosted/scrape without Bearer returns 401;
  • /scout/api/config returns 403;
  • /scout/scrape with the real local admin key returns 403;
  • provisioned hosted Bearer key can call /v1/hosted/me and /v1/hosted/scrape;
  • hosted scrape charged one standard credit and returned acquisition metadata.

Current private-beta base URL: https://judge.contentengagement.info/scout.

Important boundary: public consumers such as PRISM should use hosted Bearer keys on /v1/hosted/*, not local X-API-Key routes.

2026-06-29 — Website Logo And Scroll-Aware Nav Polish

  • Added a real Scout SVG mark and wordmark for the launch website.
  • Replaced the old block S brand treatment across static website pages.
  • Reduced homepage density by tightening header spacing, hero scale, section padding, card padding, and large vertical gaps by about 10%.
  • Reworked homepage navigation into section-aware anchors: Overview, Demo, Ledger, Modes, Evidence, Use cases, Pricing, and Beta.
  • Added IntersectionObserver scrollspy so the active nav item updates while scrolling and clicking.
  • Added scroll-padding-top / scroll-margin-top so sticky header does not cover anchored sections.
  • Verified with unit tests, route smoke, and Playwright desktop/mobile browser checks.

2026-06-29 — Unit Economics Pricing Gate

  • Arijit rejected $22 one-time and $9/month hosted pricing as arbitrary.
  • New decision: hosted pricing must be derived from unit economics before the website, checkout, or launch plan can claim a hosted price.
  • Current hypothesis: free local beta, invite-only hosted free allowance, then pay-as-you-go or prepaid credits; subscriptions only after usage telemetry supports them.
  • Cost model must include Hostinger/hosting, LLM calls, firewall/security, support, maintenance, payment fees, storage/retention, browser minutes, screenshots, retries, and target margin.
  • Repo source of truth: docs/product/unit-economics-and-pricing-model-2026-06-29.md.

2026-06-29 — Private Beta Launch Surface And Relationship Map

  • Repo checkpoint verified on GitHub branch codex/scout-platform-foundation; latest observed commit: 8aa8b09 Add beta developer guide page.
  • Current product surface: local package/CLI, FastAPI service, Docker service, hosted private-beta API, Claude/Codex skill backend, product exports, launch website, quickstart, guide, examples, pricing/status/legal pages, and beta handoff docs.
  • Launch truth: private beta is ready_with_limits; public launch is blocked; current public launch blockers require founder/legal/risk/payment decisions before further Codex execution.
  • Decision recorded: Scout is a controlled private-beta product with explicit limits, not a public launch.
  • Relationship map recorded: PRISM, Competitive Intelligence, Algolia Search Audit, product/catalog workflows, job hunter workflows, and Scout website consume Scout as acquisition/evidence infrastructure.

2026-05-21 — UI Regression Lesson Captured

  • Root cause: Scout's frontend validation treated a polished layout as progress even when some visible controls were placeholders, degraded fallbacks, or not covered by browser automation.
  • Decision recorded: every visible enabled UI control is now a product contract; it must work or be visibly disabled with a clear reason.
  • Regression guardrails added for native Browse behavior, disabled unimplemented navigation, Crawl Settings restoration, Developer Details, and fresh browser validation against the running /app.
  • Verification evidence from the corrective slice: focused E2E passed 6/6, frontend/app-run unit tests passed 10/10, pyright reported 0 errors, Ruff check/format passed, and the full suite passed 206 tests with 41 skipped.

Next: expand the UI control inventory into a broader acceptance gate before adding more app screens.

2026-05-21 — Architecture Home Frontend Slice

  • Upgraded /app How to use me into an architecture-first onboarding screen modeled after Generated Image 1.
  • Added clickable architecture stages for front doors, RunRequest, execution mode router, provider modes, normalized source evidence, vertical processors, typed records, and downstream consumers.
  • Added the cross-cutting concern rail: security, rate limiting, observability, retry, metrics, storage, and configuration.
  • Verified the detail panel updates for crawl4ai, browser fallback, and Typed Records.

2026-05-20 — Frontend Product Workbench Slice

  • Added Scout's standalone frontend direction: a self-educating app at /app with Run Console, Product Workbench, Algolia Preparation, Run Monitor, Evidence Browser, Records Explorer, and Settings.
  • Added backend support for frontend artifact lookup by run id.
  • Added Algolia preview/stub behavior that validates records and credentials without echoing or persisting API keys.
  • Generated a frontend concept board covering Command Center, Product Workbench, and Evidence Browser.
  • Documented that arbitrary third-party sites should not be embedded directly; Scout should display screenshots, DOM/HTML/markdown snapshots, citations, and blocked-page evidence.

2026-05-20 — Workdir And Local Config Slice

  • Added the Scout workdir contract: exact output_dir wins, otherwise runs are created under CLI --workdir, SCOUT_WORKDIR, or ./scout-runs.
  • Added CLI behavior for high-level scout run workflows and scout products to prompt for a working directory in interactive sessions.
  • Added HTTP behavior to derive timestamped output directories from SCOUT_WORKDIR when request JSON omits output_dir.
  • Standardized local secrets and machine-specific configuration on .env.local, with .env.example as the public template.
  • Added TDD coverage for CLI workdir handling, HTTP derived output directories, and .env.local override behavior.

2026-05-14 - product direction pivot

The Scout concept expanded from a self-hosted Crawl4AI crawler into a provider-agnostic web-to-record engine.

Key observations:

  • WebFetch/WebSearch can retrieve some pages that local Crawl4AI cannot, as seen with Estee Lauder.
  • Crawl4AI remains valuable for standalone CLI/API/Docker usage and deeper site traversal.
  • Scout's durable product value is not "fetch a page." Its value is converting messy web content into structured, reusable records with provenance.
  • Future use cases include products, company intelligence, investor intelligence, careers, job discovery, Algolia prospect research, documentation indexing, newsroom monitoring, social signal normalization, and location/store data.

Implication: Build Scout around provider interfaces and extraction schemas. Crawler behavior becomes one acquisition strategy, not the identity of the product.

2026-05-16 — Platform Architecture and Job Hunter V1 Documented

  • Captured the provider-agnostic Scout architecture as an accepted ADR.
  • Added a vault architecture page with the run orchestration, provider, evidence, processor, validation, artifact, and consumer layers.
  • Confirmed the current build direction: Scout remains both standalone (pip install, CLI, HTTP/Docker) and skill-compatible.
  • Codified that browser execution is a fallback channel, not the default acquisition path.
  • Documented Job Hunter V1 as profile loading plus target company record generation; live company discovery, ATS detection, job extraction, matching, and scheduling remain next build slices.
  • Verification from the code session: python3 -m pytest tests/unit/ -v passed 141 tests; python3 -m pytest tests/ -v passed 147 tests with 2 intentionally skipped live retail tests; python3 -m pyright scout/ reported 0 errors; ruff check scout/ tests/ and ruff format --check scout/ tests/ passed.

2026-05-19 — Job Hunter URL-Seeded V1 Build Completed

  • Implemented ATS/source detection for Greenhouse, Ashby, Workday, native careers, and unknown URLs.
  • Extended JobSearchProfile with seed job_urls, must_have_terms, and reject_terms.
  • Extended JobPostingRecord with match score, match reasons, reject reasons, source platform, raw source URL, and source confidence.
  • Added Greenhouse-style saved HTML extraction for title, company, location, description, salary range, apply URL, source platform, and stable objectID generation.
  • Added deterministic strict scoring for Director+ seniority, desired title overlap, role keywords, must-have terms, compensation threshold, and reject terms.
  • Added scout run jobs --job-url CLI support.
  • Wired URL-seeded Job Hunter runs for saved fixture:// evidence, standard source evidence artifacts, and blocked-page reporting for unsupported live URLs.
  • Added public sanitized Director CS scoring demo profile and fixture.
  • Privacy boundary remains intact: Arijit resume-derived matching profile stays in the vault, not the public repository.

Verification evidence:

  • Focused Job Hunter tests: python3 -m pytest tests/unit/core/use_cases/test_jobs_sources.py tests/unit/core/use_cases/test_jobs_contracts.py tests/unit/core/use_cases/test_jobs_extractors.py tests/unit/core/use_cases/test_jobs_scoring.py tests/unit/core/use_cases/test_jobs_runner.py tests/unit/cli/test_run_commands.py -v passed 20 tests.
  • CLI smoke: python3 -m scout.cli run jobs --profile examples/job-hunter/director-cs-profile.yaml --job-url fixture://tests/fixtures/jobs/greenhouse_eve_director_cs.html --output-dir /private/tmp/scout-job-url-smoke produced 1 job_posting.v1 record, objectID=job_eve_4245857009, ats_platform=greenhouse, match_score=100, and the full Scout artifact set.
  • Unit suite: python3 -m pytest tests/unit/ -v passed 152 tests.
  • Full suite: python3 -m pytest tests/ -v passed 158 tests with 2 intentionally skipped live retail tests. The first sandboxed run failed because Crawl4AI could not open its robots cache database; rerunning with approved filesystem access passed.
  • Type check: python3 -m pyright scout/ reported 0 errors.
  • Lint and format: ruff check scout/ tests/ passed and ruff format --check scout/ tests/ reported 90 files already formatted.

Next build slices:

  1. Live HTTP acquisition for public job URLs.
  2. Greenhouse board/API adapter.
  3. Ashby adapter or browser fallback for JavaScript shell pages.
  4. Workday and native careers canonicalization/search fallback.
  5. AI-company discovery and scheduled monitoring.

2026-05-20 — Scout Platform Foundation Build

Implemented the foundation of the full Scout intelligence platform plan: execution modes, provider ladder, high-level CLI/HTTP run surface, typed vertical records for company/careers/investor/news/research/products, updated skill playbook, repo docs, architecture docs, and vault ADRs. Browser verification and final validation remain the next gate before claiming the slice complete.

2026-05-20 — Browser Verification Pass

Internal browser verification completed across Adobe about/careers/investor, Ashby/Kong job, Lacoste product category, and Estée Lauder product page. Browser evidence worked for Adobe, Ashby, and partially for Lacoste; Estée Lauder remained blocked with Access Denied. This validates browser fallback as a secondary channel, not a default or guaranteed bypass.

2026-05-20 — Verification Gate

Verification completed for the platform foundation slice: focused tests passed (17/17), unit suite passed (164/164), full suite passed (170 passed, 2 skipped), pyright passed with zero errors, ruff check passed, ruff format check passed, CLI smoke passed for company/careers/investor/products/jobs profile mode, HTTP smoke passed for /health and /run/company. Live seed job URL smoke returned blocked evidence rather than records, which is expected until live acquisition/provider adapters are expanded.

2026-05-20 — Citation-Grade Source Evidence

Implemented citation-grade provenance for Scout. Added deterministic source_id, record-level citations[], source registry output in source_pages.json, missing_citations validation warnings, and source/citation coverage summaries in extraction_report.md. Updated repo docs and skill guidance to distinguish source registry from record citations.

2026-05-20 — Citation Verification Complete

Citation-grade source evidence verification completed: focused citation suite passed (19/19), unit suite passed (169/169), full suite passed (175 passed, 2 skipped), pyright passed with zero errors, ruff check passed, ruff format check passed. CLI smoke for company and jobs confirmed record citations point to source_pages.json; HTTP smoke for /run/company confirmed the same.

2026-05-20 — Balanced Target Matrix

Implemented a balanced validation target matrix for Scout with executable registry support. Primary targets now cover private B2B SaaS, private retail commerce, public companies, hard-site retail, and travel/airline scenarios: Algolia, Constructor, L.L.Bean, Patagonia, Adobe, Home Depot, Estée Lauder, and British Airways. Secondary targets are Nike, Amplience, Salesforce, and Intuit.

2026-05-21 — App-First Validation Checkpoint

Captured the app-first UX validation gate after the UI shell regressions. The approved direction is Run Setup -> Live Execution -> Results Review, with a single run workspace and right-side detail drawer instead of separate mock workbenches.

Updates recorded:

  • Workflow specs created under wiki/ux/workflows/ for products/Algolia, PRISM, company, investor, careers/jobs, news/blogs, research/docs, website quality, history/presets/targets, and data/integrations/settings/help.
  • Approved app-first mockup saved under raw/assets/.
  • Legacy top-level design files moved into wiki/sources/legacy/.
  • New ADR added: wiki/decisions/2026-05-21-app-first-validation-gate.md.
  • Repo validation plan now requires control inventory, deterministic E2E tests, live target tests, cleanup, truthful report, and fresh verification before GitHub checkpoint.

2026-05-22 — Browser Workbench Recovery Slice

Status: Done

What happened: Scout now has a real Playwright-backed scout-browser capture mode and a larger Browser Workbench surface in /app. The app captures screenshot, DOM, text, links, console errors, network failures, status code, and session metadata into the selected output directory. Active runs now remain reachable through navigation via an Active Run banner.

Key decisions: Added ADR wiki/decisions/2026-05-22-browser-workbench-session-modes.md. Scout distinguishes crawler sessions, Scout browser sessions, and future User browser sessions.

Tests written/updated: E2E coverage now verifies browser workbench visibility, active run persistence through navigation, and non-clipped rail labels. Unit coverage verifies Scout Browser evidence artifacts and User Browser bridge-required behavior. Live tests now use scout-browser for Estée Lauder hard-site validation.

Verification: python3 -m pytest tests/e2e/test_app_ui_exhaustive.py -q passed 14 tests. SCOUT_LIVE_TESTS=1 python3 -m pytest tests/live/test_app_live_targets.py -q passed 39 tests. python3 -m pytest tests/unit/ -q passed 196 tests. python3 -m pytest tests/ -q passed 216 tests with 41 skipped. python3 -m pyright scout/ reported 0 errors. Ruff check and format check passed.

Current limitation: Estée Lauder still blocks Scout's isolated browser session. Scout now preserves that as blocked evidence with screenshot/DOM/text/link artifacts. The next needed build is User Browser capture via Chrome CDP or a browser-extension bridge.

Next: Build User Browser Capture V1, then parse browser DOM/listing evidence into product.v1 records.

2026-06-12 — Phase A complete: live UI audit, fixes, one-pager, layout fix

  • Approved phased program (audit→fix→design→build): all 9 intelligence use cases to go live breadth-first; proper UI redesign; plan at ~/.claude/plans/i-am-building-scout-glittery-jellyfish.md.
  • Live Playwright audit of every UI control (report: repo docs/audit/2026-06-12/ui-audit.md, 14 screenshots). Zero console errors. Products mode confirmed real (Patagonia 10 records; Estée Lauder honestly blocked). All 9 intelligence use cases confirmed stubs emitting fabricated seed records — core rebuild scope.
  • Fixed (TDD, committed): mode help copy (4 modes), empty Download Records guard, use-case-adaptive records table, closed-drawer 360px grid gutter + whole-page scroll (workspace 524→884px at 1440w).
  • Shipped field-team one-pager: repo docs/one-pager/scout-one-pager.{md,html,pdf} (single A4, SE/AE/BDR sections).
  • Decision: Embedded Live Browser via CDP screencast (see decisions/2026-06-12-embedded-live-browser-direction.md).
  • Branch codex/scout-platform-foundation through commit 3cc7b57. Next: Phase B (ADRs, frontend-builder mockups, acquisition specs).

2026-06-27 — Scout 0.1.1 shared acquisition profile release

Status: Done

What happened: Scout was updated at the source as a shared acquisition primitive for Competitive Intelligence and future consumers. The exploratory /ci/scrape route was removed. The existing /scrape endpoint now supports opt-in acquisition metadata, raw and clean markdown separation, marker validation, explainable quality scoring, and collector recommendations.

Key decisions: Added ADR wiki/decisions/2026-06-27-shared-scrape-acquisition-profile.md. Scout must not create consumer-specific scrape endpoints; CI uses Scout through the shared /scrape contract.

Version: Scout bumped from 0.1.0 to 0.1.1. Runtime /health now reports Scout 0.1.1 and Crawl4AI 0.9.0.

Docs updated: README.md, CHANGELOG.md, and scout/skill/scout.md now document the shared acquisition profile, acquisition_metadata.v1, scout benchmark, and the no /ci/scrape boundary.

Verification: Default /scrape stayed backward-compatible. Opt-in /scrape returned acquisition metadata. POST /ci/scrape returned 404. scout benchmark https://example.com --output-dir /tmp/scout-release-011-benchmark --no-js --expected-marker "Example Domain" created benchmark.json, comparison.md, direct_http.txt, scout_raw.md, scout_clean.md, and samples/. Focused verification suite passed: 66 passed, 1 warning in 3.02s.

GitHub: Pushed branch codex/scout-0.1.1-acquisition to arijitchowdhury80/scout at commit 7681c04. Draft PR opened: https://github.com/arijitchowdhury80/scout/pull/1

Current limitation: Native Crawl4AI popup/overlay cleanup remains deferred because broad native cleanup showed unacceptable latency during live exploration.

Next: Return to Competitive Intelligence. Use Scout 0.1.1 in the CI collector router and run the six-source acquisition benchmark before assigning per-source defaults.

2026-06-29 — scout.chowmes.com launch and VPS hardening checkpoint

Status: Done

What happened: Scout's public private-beta surface moved to https://scout.chowmes.com. Caddy routes the new domain to the localhost-only Scout container. The root path serves the Scout launch website, and hosted API consumers use /v1/hosted/* with Bearer API keys.

Key decisions: Scout's hosted public surface is website plus hosted API. The legacy /app UI, Swagger /docs, and local/admin API routes stay blocked in hosted-only mode. Public website navigation now points to the API guide instead of blocked Swagger docs.

Security findings fixed: Initial VPS audit found Postgres and Redis published by Docker on 0.0.0.0:5432 and 0.0.0.0:6379. /opt/prism-platform/docker-compose.yml was changed so both services bind only to 127.0.0.1. External port checks now show 5432, 6379, and 8421 closed/filtered, with only 22, 80, and 443 open. A stale temporal.contentengagement.info Caddy host block was removed because the DNS name no longer resolves and was causing repeated certificate retries.

Verification: https://scout.chowmes.com/ returned the launch website with the corrected API guide navigation. /quickstart, /guide, /examples, /pricing, /status, /beta, /legal, /privacy, and /terms returned 200. /health returned 200. /v1/hosted/me without Bearer returned 401. /api/config, /app, and /docs returned 403. A provisioned hosted key successfully called /v1/hosted/me and /v1/hosted/scrape; scrape charged one standard credit and used crawl4ai.

Next: Add Tailscale or WireGuard for private admin access, then consider restricting SSH to VPN-only after a stable recovery path exists.

2026-06-29 — Hostinger provider firewall activated for Chowmes VPS

Status: Done

What happened: The Hostinger VPS firewall named Main was updated and activated for the Chowmes server that hosts scout.chowmes.com and prism.chowmes.com.

Provider firewall rules after change: Accept TCP 80 from any source, accept TCP 443 from any source, accept TCP 22 from any source, then drop all other inbound traffic. The stale UDP 41641 rule was removed because no service was listening on that UDP port.

Server firewall defense in depth: UFW remains active on the VPS with incoming denied by default. UFW allows 80/tcp and 443/tcp from anywhere, but restricts 22/tcp to Arijit's current Mac public IP 172.126.44.66. Docker services for Scout, Postgres, Redis, AC2 lab backend, and internal Hermes ports remain bound to 127.0.0.1.

Verification: After enabling the Hostinger firewall, SSH still connected, https://scout.chowmes.com/health returned 200, the website root returned 200, and /v1/hosted/me without a Bearer key returned 401. External port checks showed only 22, 80, and 443 reachable; 5432, 6379, 8421, 8642, 8787, 9119, and 9120 timed out.

Known follow-up: Tighten the Hostinger provider-level TCP 22 rule from Any to Arijit's current IP or, preferably, to a VPN/Tailscale address once a stable private admin path exists. The current risk is mitigated by UFW and key-only SSH, but provider-level SSH should eventually match the UFW allowlist.

2026-06-29 — Release hardening: Apache-2.0 local/core license

Status: Done

What happened: Scout's local/core package and source distribution were licensed under Apache-2.0. Hosted Scout access, paid service use, beta admission, support, enterprise terms, public registry publishing, and public self-serve hosted access remain separate decisions.

Repo evidence: Added root LICENSE, added license = "Apache-2.0" and license file metadata to pyproject.toml, updated README/legal/status website copy, updated launch-readiness docs, and added the completed founder decision record at docs/product/founder-decision-records/2026-06-29-apache-2-license.md.

Launch truth: Private beta remains ready_with_limits; public launch remains blocked with 9 blockers: 4 engineering, 3 founder decisions, 1 risk decision, and 1 external smoke.

Verification: python3 -m build rebuilt wheel/sdist; the license release gate passed with python3 scripts/license_release_gate_check.py --expected-license Apache-2.0 --dist-dir dist; unit tests passed (650 passed); Pyright passed with zero errors; Ruff check and Ruff format check passed.

2026-06-29 — scout.chowmes.com redeployed to release-hardening branch

Status: Done

What happened: The VPS deployment at https://scout.chowmes.com was synced from branch codex/scout-platform-foundation and rebuilt as the docker-scout image. The deployment includes the Apache-2.0 local/core license update, the 9-blocker launch status page, and the health endpoint patch that reports installed package metadata.

Production verification: /health returned {"status":"ok","crawl4ai_version":"0.9.0","scout_version":"0.1.0"}. /status now shows 9 public-launch blockers, Arijit: 4, Codex: 4, and no legal_implementation group. /legal now says Scout local/core is Apache-2.0. /v1/hosted/me without auth returned 401; /app and /docs returned 403 in hosted-only mode.

Deployment safety: The deployment preserved VPS .env, Docker data volume, and hosted runtime data. A predeploy source backup was saved at /opt/prism/backups/scout-predeploy-20260629-214231.tgz.

2026-07-03 — Self-service beta registration and Stripe credit packages

Status: In progress toward production readiness

What happened: Scout's hosted beta access model was updated away from shared passwords and manual-only key provisioning. The public beta page now uses name/email registration against /v1/hosted/beta-key, which provisions a hosted account, generates an API key, and relies on one-time email delivery. The pricing checkout now exposes both the $0 beta_trial Stripe setup-mode path and paid credit packages.

Key decisions: Added wiki/decisions/2026-07-03-self-service-beta-and-stripe-credit-packages.md. The accepted model is direct email-delivered beta keys plus Stripe checkout for payment-method verification and paid credit packs. No shared invite password is used.

Tests written/updated: Website tests now require beta registration without passwords, /v1/hosted/beta-key visibility, and beta_trial availability in pricing checkout. Hosted API tests continue to cover key delivery, rollback, duplicate email rejection, and raw-key non-disclosure.

Verification: Focused verification passed locally: python3 -m pytest tests/unit/website/test_launch_website.py tests/unit/api/test_hosted_scrape.py tests/unit/core/platform/test_key_delivery.py -q; Stripe/payment verification passed locally: python3 -m pytest tests/unit/core/platform/test_stripe_checkout.py tests/unit/api/test_billing_stripe_checkout.py tests/unit/api/test_billing_stripe_webhook.py tests/unit/core/platform/test_payment_provisioning.py -q; Pyright and Ruff checks passed.

Next: Deploy and smoke-test SMTP-backed /v1/hosted/beta-key on scout.chowmes.com; complete live Stripe test-mode checkout/webhook/key delivery smoke; approve final pricing economics before public paid launch.

2026-07-03 — Production beta readiness preflight

Status: Done

What happened: Deployed and verified the production container at commit d6fc212 on branch codex/scout-platform-foundation. Public routes /beta, /pricing, /account, /v1/billing/packages, and /v1/billing/stripe/status return successfully. The non-secret Stripe status endpoint currently reports checkout_configured=false, webhook_configured=false, key_delivery_configured=false, and ready_for_paid_key_delivery=false.

Decision/UX correction: Because key delivery is missing, the beta page now preflights /v1/billing/stripe/status and disables the registration CTA with a clear "registration is temporarily paused" message instead of allowing a user to submit into a known 503 path.

Current operations truth: No beta invite password exists. There is no email/password login. Admin/manual provisioning exists through scripts/scout-generate-api-key or scripts/scout-hosted-admin generate-api-key. Hosted tenants, API-key metadata, balances, usage, and purchases are stored in /data/hosted_accounts.sqlite in the Scout container.

Verification: Focused tests passed: python3 -m pytest tests/unit/website/test_launch_website.py::test_beta_signup_collects_name_and_email_without_password tests/unit/website/test_launch_website.py::test_docs_beta_access_is_self_service_email_delivery_without_password tests/unit/scripts/test_vps_admin_scripts.py -q reported 8 passed, 2 warnings. Production verification passed: /health returned 200, /beta contains hostedBetaSignup, /v1/billing/stripe/status, and the paused-registration copy, /pricing contains beta_trial and Stripe setup-mode copy, and /v1/billing/stripe/status reports all billing/key-delivery readiness flags as false.

Next: Configure SMTP delivery, smoke /beta with a real email delivery, configure Stripe test-mode price IDs/webhook, then run a full checkout-to-email-to-/account verification before calling hosted self-service ready.

2026-07-03 — Hosted admin usage monitoring

Status: Done

What happened: Added scripts/scout-hosted-admin list-usage and scripts/scout-hosted-admin list-usage --summary so the operator can inspect hosted credit usage from the VPS SQLite ledger without exposing raw API keys or stored key hashes.

What it shows: The ledger view shows email, tenant, key id, action, credit bucket, credits spent, balances after the event, and timestamp. Summary mode groups by action and credit type with event count, credits spent, and last-used timestamp.

Production smoke: scripts/scout-hosted-admin list-usage --summary --limit 10 returned production ledger totals: scrape standard usage and crawl_page standard usage from prior hosted load tests.

Verification: python3 -m pytest tests/unit/scripts/test_vps_admin_scripts.py -q passed with 7 passed; ruff check tests/unit/scripts/test_vps_admin_scripts.py passed; ruff format --check tests/unit/scripts/test_vps_admin_scripts.py reported the file already formatted.

2026-07-03 — Stripe setup-mode beta card collection hardening

Status: Done

What changed: Made the $0 hosted beta Checkout path explicit about card collection by adding payment_method_types[0]=card to Stripe setup-mode Checkout Session creation for the beta_trial package.

Why: The current hosted beta strategy has two controlled access paths: direct name/email beta key registration once SMTP delivery is configured, and Stripe setup-mode checkout for payment-method-backed beta testers. The Stripe path should verify the billing pipeline without charging the tester during the 30-day/100-credit trial.

Current production truth: scout.chowmes.com is running commit a5b225e, but production still reports checkout_configured=false, webhook_configured=false, and key_delivery_configured=false because Stripe and SMTP environment variables are not configured yet.

Verification: Focused tests passed: python3 -m pytest tests/unit/core/platform/test_stripe_checkout.py tests/unit/test_hosted_pricing_docs.py -q reported 7 passed; ruff check passed for the touched Python files; ruff format --check reported them already formatted.

2026-07-03 — Hosted beta Stripe setup deployed

Status: Done

What changed: Deployed Scout commit ea9b1d8 to scout.chowmes.com. The hosted beta Stripe checkout path now explicitly sends payment_method_types[0]=card for $0 beta setup-mode checkout. The beta registration page remains email-delivery-only and does not display raw API keys in the browser.

Production verification: VPS repo is at ea9b1d8; the Docker scout container is healthy; public /health returned 200; /beta returned 200 and contains hostedBetaSignup, registration is temporarily paused, and Scout emails the API key; /pricing returned 200 and contains beta_trial plus Stripe setup-mode checkout; /v1/billing/stripe/status returned checkout_configured=false, webhook_configured=false, key_delivery_configured=false, and ready_for_paid_key_delivery=false.

Remaining gate: Configure SMTP delivery and Stripe secrets/price IDs/webhook before self-service hosted beta or paid checkout can be called live end to end.

Correction note: A temporary GitHub commit that allowed raw beta keys to be shown in the browser when SMTP was missing was reverted by ea9b1d8. The accepted production behavior is still email-only key delivery for public beta registration; when SMTP is missing, /beta remains paused and /v1/hosted/beta-key returns a 503 rather than exposing a key in-browser.

2026-07-03 — Stripe Customer creation for hosted beta and credit packs

Status: Done

What changed: Scout now sends customer_creation=always when creating Stripe Checkout Sessions for both $0 setup-mode beta trials and paid credit-pack payment sessions. This ensures Stripe creates a Customer record during hosted beta/payment flows so Scout can keep customer/session references without storing card data.

Why: The hosted beta requirement is payment-method-backed access without charging beta testers. Stripe should own the payment method and customer object; Scout should store only tenant metadata, Stripe customer/session/setup/payment references, credit balances, and usage ledger entries.

Verification: Focused hosted/billing/website tests passed: python3 -m pytest tests/unit/core/platform/test_stripe_checkout.py tests/unit/api/test_billing_stripe_checkout.py tests/unit/api/test_billing_stripe_webhook.py tests/unit/core/platform/test_payment_provisioning.py tests/unit/api/test_hosted_scrape.py tests/unit/website/test_launch_website.py tests/unit/test_hosted_pricing_docs.py -q reported 68 passed; Ruff check passed; Ruff format check passed.

2026-07-03 — Hosted deploy and PRISM API key provisioning

Status: Done with open production blockers

What changed: Deployed Scout commit 291655f to scout.chowmes.com and verified the Docker scout container became healthy. Public /health returns 200 with Scout 0.1.0 and Crawl4AI 0.9.0.

Hosted readiness truth: /v1/billing/stripe/status still reports checkout_configured=false, webhook_configured=false, key_delivery_configured=false, and ready_for_paid_key_delivery=false. SMTP and Stripe secrets are not configured on the VPS yet, so /beta remains intentionally paused rather than exposing raw API keys in the browser.

Operator provisioning: Generated a live hosted_beta_pass key for prism@chowmes.com using scripts/scout-generate-api-key. The tenant is active, has 100 standard credits and 0 browser credits, and /v1/hosted/me validates the key without echoing the raw secret. The one-time key is stored only in a local ignored secrets/ file for operator handoff.

Next: Configure SMTP, verify email delivery, configure Stripe secret/webhook/price IDs, run checkout-to-email-to-usage smoke, then reopen public self-service beta key generation.

2026-07-03 — Hosted screenshot endpoint and async queue correction

Status: Done with production smoke

What changed: Added and deployed /v1/hosted/screenshot so hosted beta keys can call screenshot capture through Bearer auth with URL safety, credit preflight, rate limiting, and usage metering. The endpoint charges 3 standard credits on successful inline execution.

Production finding: The VPS had HOSTED_ASYNC_FIRST=true with HOSTED_JOB_QUEUE_WORKERS=0, which caused hosted screenshot requests to return 202 queued forever. This was a real SaaS reliability bug: accepted jobs had no worker to process them.

Fix: Set production HOSTED_ASYNC_FIRST=false while workers remain disabled, restarted Scout, and documented that async-first must never be enabled with zero workers.

Verification: Public https://scout.chowmes.com/v1/hosted/screenshot was called with the PRISM hosted beta key against https://example.com. It returned 200, success=true, screenshot base64 content, width=800, height=600, credits_charged=3, reduced PRISM standard credits from 100 to 97, and did not echo the raw API key.

2026-07-03 — Self-service beta key contract tightened

Status: Deployed to scout.chowmes.com

What changed: Removed the legacy public fallback that could show a raw hosted API key in the beta registration HTTP response when SMTP delivery was missing. /v1/hosted/beta-key now requires a configured delivery service, fails closed with 503 before account creation when delivery is missing, and the HostedBetaKeyResponse OpenAPI schema no longer includes raw_api_key.

Product contract: Public self-service signup is email-only key delivery. Operator CLI provisioning remains the only approved flow that prints a raw key once, for admin handoff to trusted consuming apps.

Verification: Focused hosted/account/billing/website tests passed: python3 -m pytest tests/unit/api/test_hosted_scrape.py tests/unit/website/test_launch_website.py tests/unit/scripts/test_vps_admin_scripts.py tests/unit/core/platform/test_account_sqlite_store.py tests/unit/core/platform/test_pricing.py tests/unit/core/platform/test_payment_provisioning.py tests/unit/core/platform/test_stripe_checkout.py tests/unit/api/test_billing_stripe_checkout.py tests/unit/api/test_billing_stripe_webhook.py -q reported 83 passed, 2 warnings. Ruff check and format check passed for the touched code and tests.

Next: Commit, push, deploy, then configure SMTP and Stripe secrets/price IDs/webhook before calling live self-service and paid checkout complete.

2026-07-03 — Hosted readiness checker and email-only self-service enforcement

Status: Done locally; deploy pending

What changed: Removed the response/API fallback path that could treat an environment flag as permission to show a hosted beta API key in the browser. Self-service /v1/hosted/beta-key is now email-delivery-only: if SMTP delivery is missing, the endpoint returns 503 before creating an account. The billing status route now reports beta_signup_enabled and ready_for_beta_key_delivery so the website and operators can distinguish configured signup from blocked signup.

Operator tooling: Added scripts/hosted_readiness_check.py, a non-secret preflight that checks /health, /v1/billing/packages, and /v1/billing/stripe/status. It supports --require-beta-signup and --require-paid-checkout so future deployments can fail clearly when SMTP or Stripe setup is incomplete.

Production truth: Running the checker against https://scout.chowmes.com currently reports health ready and packages ready, but beta signup and paid checkout blocked. The live blockers are hosted beta signup disabled, hosted API-key email delivery not configured, Stripe Checkout not configured, Stripe webhook secret not configured, and paid checkout/key delivery not ready.

Verification: Focused tests passed: python3 -m pytest tests/unit/api/test_hosted_scrape.py tests/unit/api/test_billing_stripe_checkout.py tests/unit/website/test_launch_website.py tests/unit/scripts/test_hosted_readiness_check.py -q reported 56 passed, 2 warnings. Ruff check and format check passed for the touched Python files and tests.

Next: Commit/push/deploy this slice, then configure SMTP and Stripe test-mode/live settings before reopening public self-service beta signup.

2026-07-03 — Hosted billing admin metrics API

Status: Done and deployed

What changed: Added service-key protected GET /v1/billing/admin/metrics so the hosted Scout service can report non-secret operator metrics without SSH-only SQLite inspection. The endpoint returns account totals, active and disabled tenant counts, remaining credit totals, usage event counts, standard and browser credits spent, purchase count, revenue cents, recent accounts, recent usage, and recent purchases.

Security boundary: The endpoint requires the service X-API-Key, remains available in hosted-only mode only with that key, and does not return raw hosted API keys, key hashes, Stripe secrets, SMTP secrets, or payment details.

Why it matters: This closes part of the measurement/monitoring gap for hosted beta operations. Operators can now inspect signup, usage, purchase, credit, and revenue posture through the service API instead of only through SSH helper scripts.

Verification: Focused tests passed: python3 -m pytest tests/unit/api/test_billing_admin_metrics.py tests/unit/api/test_auth.py -q reported 15 passed, 2 warnings. Ruff check passed for the touched auth, billing, account service/store, and tests.

Production verification: Deployed commit ac80f29 to scout.chowmes.com; Docker reported the scout container healthy. Public /health returned 200; /v1/billing/stripe/status returned the expected current blockers (checkout_configured=false, webhook_configured=false, key_delivery_configured=false); /v1/billing/admin/metrics rejected missing keys with 403; the same endpoint accepted the server service key and returned live metrics through both localhost and https://scout.chowmes.com, including 100 accounts, 442 usage events, and 0 purchases.

Next: Configure SMTP and Stripe checkout/webhook secrets before calling hosted self-service and paid checkout ready.

2026-07-03 — Direct email beta key registration surface

Status: Done locally; deploy pending

What changed: Repointed the public /beta page from Stripe-first beta checkout to direct beta tester API-key registration. The form now collects name/email, posts to POST /v1/hosted/beta-key, and relies on SMTP delivery to email the generated hosted API key. The page does not expose raw API keys, invite passwords, or Stripe secrets.

Readiness change: Added ready_for_beta_key_delivery to /v1/billing/stripe/status so the website and readiness checker can distinguish direct beta key delivery from paid/card-backed Stripe checkout. Updated scripts/hosted_readiness_check.py to use that flag for beta signup readiness.

Stripe boundary: Stripe Checkout remains in the codebase for paid credit packages and future card-backed beta validation, but direct beta key registration no longer depends on Stripe Checkout or webhook readiness.

Verification: Focused tests passed: python3 -m pytest tests/unit/website/test_launch_website.py tests/unit/api/test_billing_stripe_checkout.py tests/unit/api/test_auth.py tests/unit/scripts/test_hosted_readiness_check.py tests/unit/test_hosted_pricing_docs.py -q reported 58 passed, 2 warnings. Full unit suite passed: python3 -m pytest tests/unit/ -q reported 734 passed, 8 warnings. Ruff check, Ruff format check, and Pyright all passed for this work.

GitHub: Committed and pushed 0b1864e on codex/scout-saas-prod-ready.

Production verification: Deployed commit 0b1864e to scout.chowmes.com; Docker reported scout healthy. Public /health returned {"status":"ok","crawl4ai_version":"0.9.0","scout_version":"0.1.0"}. /v1/billing/stripe/status returned beta_signup_enabled=true, checkout_configured=false, webhook_configured=false, key_delivery_configured=false, ready_for_beta_key_delivery=false, ready_for_beta_checkout=false, and ready_for_paid_key_delivery=false. /beta contains the direct hostedKeyForm and /v1/hosted/beta-key endpoint and no longer contains /v1/billing/stripe/checkout-session. /assets/hosted-keygen.js returned 200. Posting a smoke tester to /v1/hosted/beta-key returned 503 with Hosted API key delivery is not configured., and a container-side account-store check confirmed smoke_tenant_exists=false.

Next: Configure real SMTP credentials and verify email delivery before beta testers can self-serve hosted keys. Stripe checkout/webhook/price IDs remain a separate blocker for paid credit packages and card-backed beta flows.

2026-07-03 — Stripe smoke package selection and hosted beta docs corrected

Status: Deployed to scout.chowmes.com

What changed: Updated scripts/stripe_test_mode_smoke.py so production operators can explicitly test either the paid standard_1000 package path or the card-backed $0 beta_trial setup path. The helper now sends package_id to /v1/billing/stripe/checkout-session, requires ready_for_paid_key_delivery for paid packages, and requires ready_for_beta_checkout for the beta setup package.

Docs correction: Fixed docs/distribution.md and website status copy so the launch posture is no longer contradictory:

  • direct /beta registration is name/email plus SMTP-delivered API key;
  • public direct signup never returns raw keys in the browser;
  • Stripe Checkout is the paid credit-package path and the optional card-backed $0 beta validation path;
  • SMTP is required for all self-service key delivery;
  • Stripe secret, price IDs, success/cancel URLs, and webhook secret are still required before paid checkout is ready.

VPS hygiene: Removed stale HOSTED_KEY_DELIVERY_ALLOW_RESPONSE_FALLBACK from the VPS .env and restarted Scout. The running container no longer has that env variable.

Verification: Red test failed first because run_smoke() did not accept package_id. After the patch, focused smoke/docs tests passed: python3 -m pytest tests/unit/test_stripe_test_mode_smoke.py tests/unit/test_hosted_pricing_docs.py tests/unit/test_launch_governance_docs.py tests/unit/website/test_launch_website.py -q reported 68 passed, 2 warnings. Full unit suite passed: python3 -m pytest tests/unit/ -q reported 735 passed, 8 warnings. Ruff check, Ruff format check, and Pyright all passed.

Production status after env cleanup: https://scout.chowmes.com/health returned OK. /v1/billing/stripe/status still reports checkout_configured=false, webhook_configured=false, key_delivery_configured=false, ready_for_beta_key_delivery=false, ready_for_beta_checkout=false, and ready_for_paid_key_delivery=false, which is expected until SMTP and Stripe secrets are installed.

GitHub and deploy: Committed and pushed 94e66ea on codex/scout-saas-prod-ready, then deployed that commit to the VPS. Docker reported the scout container healthy. Public /status contains the corrected direct-beta and paid-checkout readiness copy.

2026-07-03 — Paid checkout top-ups for existing hosted accounts

Status: Verified locally; deployment pending during the current checkpoint.

Problem found: Paid Stripe checkout provisioning created a new hosted account for every successful checkout. That meant an existing beta user buying credits with the same email would hit the duplicate-email guard instead of receiving a credit top-up.

What changed: Hosted payment provisioning now checks for an existing tenant by checkout email before creating a new account. If the tenant exists, Scout adds the purchased package credits to that tenant balance, records the checkout against the existing tenant/key, and returns success without a raw API key. First-time paid buyers still receive a one-time generated key through the normal payment provisioning path.

Email/key delivery boundary: Existing-account top-ups do not send another API-key email and never expose a raw key. Billing webhook delivery reports not_required for those top-ups. This keeps the rule intact: raw hosted API keys are only shown or emailed once at initial provisioning.

Docs updated: Added the top-up semantics to docs/distribution.md and docs/product/hosted-admin-operations.md so operators and future portal work know that paid checkout with an existing email is a credit top-up, not a second account.

Verification: Added regression coverage in tests/unit/core/platform/test_payment_provisioning.py and tests/unit/api/test_billing_stripe_webhook.py. Focused tests passed: python3 -m pytest tests/unit/core/platform/test_payment_provisioning.py tests/unit/api/test_billing_stripe_webhook.py -q reported 16 passed, 2 warnings. Full unit suite passed: python3 -m pytest tests/unit/ -q reported 737 passed, 8 warnings. Ruff check and Pyright passed. Ruff format initially caught scout/core/platform/account_service.py; after formatting, format check passed.

Remaining blocker: This does not configure real Stripe or SMTP secrets. Live paid checkout and live email key delivery still require production credentials and end-to-end Stripe test-mode verification.

Deployment: Committed and pushed bac6eba on codex/scout-saas-prod-ready, then deployed that commit to the VPS. Docker reported scout healthy at commit bac6eba. Public https://scout.chowmes.com/health returned OK. Public /v1/billing/stripe/status still correctly reports checkout_configured=false, webhook_configured=false, key_delivery_configured=false, ready_for_beta_key_delivery=false, ready_for_beta_checkout=false, and ready_for_paid_key_delivery=false.

2026-07-03 — Prevent repeated free beta-trial credit grants

Status: Verified locally; deployment pending during the current checkpoint.

Problem found: The paid top-up logic was correct for paid packages, but it also applied to the $0 beta_trial package. A repeat card-backed beta setup checkout for an existing hosted email could therefore add another 100 free standard credits.

Decision: Existing-account Stripe checkouts only add credits when the package has a positive price. Repeat $0 beta-trial checkouts are recorded against the existing tenant/key for auditability but do not change the hosted balance and do not trigger another raw API-key email.

Why it matters: This closes a metering leak before self-service payment is enabled. Beta testers can verify the card-backed checkout flow once, but the free trial cannot become an unlimited credit faucet through repeated setup sessions.

Verification: Added regression tests at the provisioning layer and webhook layer. The red test first showed the balance moving from 75 to 175 credits on a repeat beta-trial checkout. After the patch, focused billing tests passed: python3 -m pytest tests/unit/core/platform/test_payment_provisioning.py tests/unit/api/test_billing_stripe_webhook.py tests/unit/test_hosted_pricing_docs.py tests/unit/test_launch_governance_docs.py -q reported 50 passed, 2 warnings. Full local gate passed: python3 -m pytest tests/unit/ -q reported 739 passed, 8 warnings; Ruff check, Ruff format check, and Pyright also passed.

Deployment: Committed and pushed 3bf7bb1 on codex/scout-saas-prod-ready, then deployed it to the VPS. Docker reported scout healthy at commit 3bf7bb1. Public https://scout.chowmes.com/health returned OK. Public /v1/billing/packages returned the beta trial, standard paid packages, credit costs, and unit-economics data. Public /v1/billing/stripe/status still correctly reports checkout, webhook, and key delivery as not configured.

2026-07-03 — Readiness-gated checkout forms restored to website

What changed: /pricing now contains a real hosted-credit checkout form for $10, $25, and $100 credit packages. /beta now contains a separate optional $0 card-backed beta setup form while preserving the direct name/email beta API-key request form.

Safety boundary: Both Stripe forms call /v1/billing/stripe/checkout-session and check /v1/billing/stripe/status first. Paid checkout uses ready_for_paid_key_delivery; card-backed beta setup uses ready_for_beta_checkout. If Stripe/webhook/SMTP are not configured, the buttons are disabled and the page explains the readiness blocker. No Stripe, SMTP, API-key, or raw-key secrets are embedded in the website.

Verification: TDD red tests first failed because the forms were absent. After the patch, focused website tests passed: python3 -m pytest tests/unit/website/test_launch_website.py::test_launch_website_keeps_paid_checkout_paused_without_secrets tests/unit/website/test_launch_website.py::test_pricing_page_explains_credit_packages_and_unit_economics tests/unit/website/test_launch_website.py::test_beta_signup_collects_name_and_email_without_password -q reported 3 passed. Full local gate passed: python3 -m pytest tests/unit/ -q reported 739 passed, 8 warnings; Ruff check passed; Ruff format check passed after formatting the updated website test; Pyright reported 0 errors.

Deployment: Committed and pushed dd5dfe6 on codex/scout-saas-prod-ready, deployed it to scout.chowmes.com, and verified Docker health plus public /health, /pricing, /beta, and /v1/billing/stripe/status. Production now serves the new checkout form markers. Status still reports ready_for_beta_key_delivery=false, ready_for_beta_checkout=false, and ready_for_paid_key_delivery=false.

Remaining blocker: Live self-service still requires SMTP and Stripe production/test-mode secrets plus a real checkout-to-webhook-to-email smoke before calling hosted signup or paid checkout fully operational.

2026-07-03 — VPS hosted env configuration helper

What changed: Added scripts/scout-hosted-admin configure-production-env, backed by scripts/scout-vps-configure-hosted-env, so the operator can install SMTP and Stripe production/test-mode settings onto the ChowMes VPS from an ignored local file such as secrets/scout-production.env.

Safety boundary: The helper only accepts allowlisted hosted billing/key-delivery variables, writes /opt/prism/scout/.env, preserves unrelated existing env lines, sets file permissions to 0600, reports variable names only, and never prints secret values. --restart recreates the scout container so Docker reads the new env file.

Production truth checked: The current VPS has HOSTED_BETA_SIGNUP_ENABLED set, but SMTP host/from/username/password and all Stripe secret/price/webhook settings are missing. Public readiness currently reports health and packages ready, but beta key delivery and paid checkout are blocked.

Verification: TDD red tests first failed because the command/script did not exist. After implementation, python3 -m pytest tests/unit/scripts/test_vps_admin_scripts.py tests/unit/test_hosted_pricing_docs.py tests/unit/test_launch_governance_docs.py -q reported 40 passed. Full unit suite reported 740 passed, 8 warnings; Ruff format/check and Pyright passed.

Next: Provide SMTP and Stripe test-mode values in secrets/scout-production.env, run scripts/scout-hosted-admin configure-production-env --secrets-file secrets/scout-production.env --restart, then run hosted readiness plus Stripe checkout smoke.

Deployment: Committed and pushed bc58ff0 on codex/scout-saas-prod-ready, then fast-forwarded the VPS repo to that commit. The new helper is present on the VPS and scout Docker health remains healthy.

2026-07-03 — Beta key delivery email upgraded

What changed: The self-service beta API-key email now has the subject Your Scout beta tester API key is ready, greets the tester by name, explains the 100 standard credits/30-day limit, states that hosted beta is not unlimited crawling, includes the raw key once, shows tenant/key/reference metadata, includes curl quick test, account/balance, usage ledger, purchase history, docs, and pricing links, and warns users not to paste the key into frontend code, screenshots, tickets, or public repos.

Signature: The email is signed Arijit Chowdhury and Founder, Chowmes.

Verification: python3 -m pytest tests/unit/core/platform/test_key_delivery.py tests/unit/api/test_billing_stripe_webhook.py tests/unit/website/test_launch_website.py::test_beta_signup_collects_name_and_email_without_password -q reported 13 passed, 2 warnings.

Deployment: Committed and pushed 5b42a0b on codex/scout-saas-prod-ready, fast-forwarded the VPS repo to that commit, and rebuilt/restarted the scout container. Fresh production verification showed scout Docker health is healthy, public /health is OK, and /v1/billing/stripe/status still correctly reports checkout, webhook, and key delivery as not configured.

Remaining blocker: This slice is deployed, but hosted beta/paid launch is still not complete until real SMTP and Stripe checkout/webhook secrets are installed and a checkout/webhook/email-delivery smoke passes end to end.

2026-07-03 — Hosted beta signup telemetry ledger

What changed: Added a non-secret hosted signup event ledger so direct beta API-key registration attempts are measurable even when email delivery fails or a duplicate signup is rejected. Events record email, name, status, source, tenant/key identifiers when available, delivery status, failure reason, and timestamp. They never store raw API keys or key hashes.

Admin visibility: /v1/billing/admin/metrics now includes signup_events, signup_delivered, signup_failed, signup_duplicate, and recent_signup_events alongside account, usage, purchase, credit, and revenue metrics.

Verification: TDD red first failed because HostedSignupEvent did not exist. After implementation, focused signup/admin tests passed: python3 -m pytest tests/unit/api/test_billing_admin_metrics.py tests/unit/api/test_hosted_scrape.py::test_hosted_beta_key_generation_requires_email_only_and_creates_usable_key tests/unit/api/test_hosted_scrape.py::test_hosted_beta_key_generation_requires_configured_delivery_service tests/unit/api/test_hosted_scrape.py::test_hosted_beta_key_generation_rolls_back_when_delivery_fails tests/unit/api/test_hosted_scrape.py::test_hosted_beta_key_generation_rejects_duplicate_email -q reported 6 passed, 2 warnings.

Deployment: Committed and pushed 5a076d0 on codex/scout-saas-prod-ready, deployed it to scout.chowmes.com, and verified Docker health is healthy. Public /health is OK. Public readiness still correctly reports SMTP and Stripe blockers. A controlled production beta signup smoke with a synthetic email returned 503 because SMTP is not configured and then appeared in /v1/billing/admin/metrics as a failed direct_beta_key signup event.

2026-07-03 — Stripe Checkout route fails closed on partial readiness

What changed: Hardened /v1/billing/stripe/checkout-session so the API does not create Stripe Checkout Sessions unless the webhook secret and hosted API-key email delivery are configured. $0 beta_trial setup additionally requires hosted beta signup to be enabled. This prevents a partial production config from accepting payment or card setup before the webhook/key-delivery pipeline can provision access.

Verification: TDD red first proved the route returned 200 in unsafe partial states. After the guard, python3 -m pytest tests/unit/api/test_billing_stripe_checkout.py -q reported 11 passed, 2 warnings.

Deployment: Committed and pushed ecde8d3 on codex/scout-saas-prod-ready, deployed it to scout.chowmes.com, and verified Docker health is healthy. Public /health is OK. A production checkout smoke for standard_1000 now returns 503 with Stripe webhook secret is not configured, proving the hosted API fails closed before creating a checkout session in the current partial configuration.

2026-07-03 — Hosted access disable lifecycle

What changed: Added an operator-safe hosted access disable path. HostedAccountService can now disable a full tenant/account and all tenant keys, or disable one API key. SQLite persistence now supports tenant status updates in addition to key status updates.

Admin command: scripts/scout-hosted-admin disable-access wraps the VPS helper scripts/scout-vps-disable-hosted-access. It supports --email, --tenant-id, or --key-id, requires --yes, accepts an operator --reason, and prints only non-secret result fields.

Why it matters: Hosted beta key issuance needs a matching emergency shutoff. This closes the immediate leaked-key/abuse/offboarding operator gap without deleting account, usage, signup, or payment audit history.

Verification: Focused tests passed: python3 -m pytest tests/unit/core/platform/test_account_service.py tests/unit/core/platform/test_account_sqlite_store.py tests/unit/scripts/test_vps_admin_scripts.py -q reported 27 passed, 2 warnings.

Still pending: Full hosted production readiness remains blocked by missing SMTP key delivery configuration and missing Stripe checkout/webhook configuration. The disable command is an admin CLI flow; customer self-service key rotation/revocation is still future work.

2026-07-03 — Hosted readiness admin command

What changed: Added scripts/scout-hosted-admin readiness, which wraps scripts/hosted_readiness_check.py from the main hosted admin surface.

Why it matters: The production-readiness truth source is now discoverable next to key provisioning, signup logs, email smoke tests, env configuration, and access-disable operations. It checks health, billing packages, beta signup readiness, paid checkout readiness, and secret leakage through non-secret HTTP responses.

Usage: scripts/scout-hosted-admin readiness --require-beta-signup --require-paid-checkout or scripts/scout-hosted-admin readiness --json.

Still pending: Current live readiness still depends on external SMTP and Stripe values. This command improves operator verification but does not itself configure those services.

2026-07-03 — Hosted SMTP and Stripe config validator

What changed: Added scripts/scout-hosted-admin validate-config and the underlying scripts/scout-validate-hosted-config command. The validator checks a local ignored env file for the hosted beta SMTP and paid Stripe variables needed before production upload.

Guardrail: scripts/scout-vps-configure-hosted-env now calls the validator before writing /opt/prism/scout/.env on the VPS. Default mode is --require all, which requires beta email delivery plus all visible paid package Stripe price IDs, success/cancel URLs, and webhook secret. Operators can use --require beta only when intentionally enabling email beta key delivery before paid checkout.

Secret safety: The validator reports only variable names and missing keys. It intentionally does not print SMTP passwords, Stripe secret keys, webhook secrets, or hosted API keys.

Why it matters: The remaining production blockers are mostly external configuration. This makes the next SMTP/Stripe setup step deterministic and prevents partial config from being uploaded by accident.

2026-07-03 — Hosted config template writer

What changed: Added scripts/scout-hosted-admin write-config-template, wrapping scripts/scout-write-hosted-config-template. The command writes a non-secret secrets/scout-production.env starter file with the exact SMTP and Stripe variables needed for passwordless beta key delivery and paid checkout.

Safety behavior: It refuses to overwrite an existing file without --force, contains no real SMTP password, Stripe secret, webhook secret, or hosted API key, and uses the approved sender placeholder Arijit Chowdhury <scout@chowmes.com>.

Why it matters: The remaining production blockers require external SMTP and Stripe values. This command makes the next configuration step operationally repeatable instead of relying on manual env-file assembly from documentation.

2026-07-03 — Passwordless beta signup contract hardening

What changed: Hardened POST /v1/hosted/beta-key so public beta registration requires name and email, matching the website form. The API now rejects removed invite/password fields instead of silently accepting them.

Why it matters: Scout's hosted beta path should be straightforward: tester enters name and email, Scout records the signup, provisions one finite-credit account, and emails the one-time API key when SMTP is configured. There is intentionally no shared beta password gate.

Verification: TDD red proved missing name returned 200, OpenAPI only required email, and invite_password was ignored. After the fix, python3 -m pytest tests/unit/api/test_hosted_scrape.py -q reported 17 passed; full unit verification reported 761 passed; pyright reported 0 errors; Ruff and format checks passed.

Still pending: Production self-service signup remains blocked until real SMTP key delivery is configured on the hosted VPS. Paid checkout remains blocked until Stripe Checkout price IDs and webhook secret are configured and smoke-tested.

2026-07-03 — Public beta signup rate limiting

What changed: Added configurable request throttling to POST /v1/hosted/beta-key. The route now admits at most three signup attempts per apparent client address per hour by default, using HOSTED_BETA_SIGNUP_RATE_LIMIT_MAX_REQUESTS=3 and HOSTED_BETA_SIGNUP_RATE_LIMIT_WINDOW_SECONDS=3600.

Why it matters: The beta key form is public and unauthenticated. Throttling prevents a single client from repeatedly creating hosted accounts or triggering email delivery. The guard runs before account creation and before SMTP delivery.

Operations: The settings are now present in .env.example, the hosted production config template, the VPS env allowlist, distribution docs, and the hosted admin operations runbook.

Verification: TDD red proved the signup limiter dependency did not exist. After implementation, focused signup tests passed with 18 passed; script env tests passed; docs tests passed; full unit verification reported 763 passed; pyright reported 0 errors; Ruff and format checks passed.

Still pending: The limiter is in-process. It is appropriate for the current single-container VPS beta, but a future multi-instance hosted setup should move signup throttling to a shared store such as Redis or a proxy-level rate limit.

2026-07-03 — Pending beta registration capture

What changed: Hosted beta signup now records a pending_delivery signup event and returns 202 Accepted when beta registration is enabled but SMTP API-key delivery is not configured.

Why it matters: The public beta page no longer dead-ends testers with a generic failure while external email configuration is pending. Scout can now collect name/email interest in the hosted account database without creating an API key, without creating a tenant, and without exposing any raw key material.

Duplicate handling: Repeated pending requests for the same email return the same queued status and do not create duplicate signup events.

Website behavior: The beta registration form remains enabled when /v1/billing/stripe/status reports beta_signup_enabled=true but API-key delivery is not ready. The status text clearly says the request may be queued until hosted key delivery is configured.

Verification: TDD red proved the backend still returned 503 and the frontend had no queued-registration state. After implementation, the new backend tests passed, the website test passed, affected hosted/website suites reported 48 passed, pyright reported 0 errors, and Ruff passed.

Still pending: Real self-service key delivery still requires SMTP production configuration. This is an intake and observability improvement, not the final email-delivery configuration.

2026-07-03 — Pending beta signup delivery processor

What changed: Added an operator-safe processor for beta signup requests that were queued while SMTP delivery was not configured.

Core behavior: - HostedAccountService.pending_signup_requests() returns the newest pending_delivery event per email. - It excludes emails whose newest event is already delivered, failed, or duplicate. - It excludes emails that already have a hosted tenant. - /v1/billing/admin/metrics now includes signup_pending_delivery. - scripts/scout-hosted-admin process-pending-signups --dry-run lists queued requests without mutating hosted accounts. - scripts/scout-hosted-admin process-pending-signups --yes provisions beta accounts and sends API keys once SMTP is configured.

Safety decisions: - Real processing requires --yes; dry-run is explicit. - The processor refuses to provision if hosted SMTP key delivery is disabled. - If SMTP delivery fails after account creation, Scout deletes the account and records a failed signup event. - The script does not print raw API keys, key hashes, or SMTP passwords.

Verification: TDD red produced 6 expected failures for the missing service method, missing admin metric, missing script, and missing admin command. After implementation, the same focused suite reported 6 passed, 2 warnings.

Still pending: Production still needs real SMTP configuration and a smoke email before queued requests can be processed for real. Stripe remains external configuration work as well.

Deployment check: Commit a4e729b was pushed to GitHub and deployed to the VPS. The Scout container reported healthy; GET https://scout.chowmes.com/health returned status ok; /v1/billing/stripe/status still correctly reports SMTP/key delivery and Stripe checkout/webhook as not configured. Mac-side scripts/scout-hosted-admin process-pending-signups --dry-run --limit 5 returned one queued smoke signup and did not mutate accounts.

2026-07-03 — Hosted config and monitoring checkpoint

What changed: Generated the ignored local production config template at secrets/scout-production.env so SMTP and Stripe settings have a concrete fill/validate/install path.

Current production config truth: VPS /opt/prism/scout/.env has HOSTED_BETA_SIGNUP_ENABLED present. SMTP delivery settings, Stripe secret, Stripe paid package price IDs, and Stripe webhook secret are missing. The live readiness command reports: - Health: ready. - Packages: ready. - Beta signup: blocked because key delivery is not ready. - Paid checkout: blocked because Stripe checkout/webhook and key delivery are not ready.

Monitoring snapshot: - list-signups: one pending_delivery beta request, one older failed request. - list-usage --summary: real hosted usage exists for scrape, crawl_page, and screenshot. - list-purchases: no purchases yet. - process-pending-signups --dry-run: one queued beta signup, no mutation.

Next required inputs: SMTP provider details and Stripe test/live configuration: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, and price IDs for standard_1000, standard_3000, and standard_15000.

2026-07-03 — Hosted status copy corrected to match production truth

What changed: Corrected public /status copy and the hosted admin operations runbook so they match the implemented self-service behavior.

Previous stale claim: The page still said "Current blockers: 0" and "Direct hosted beta signup fails closed until SMTP key delivery is configured."

Current truth: HOSTED_BETA_SIGNUP_ENABLED=true is live. When SMTP key delivery is missing, /v1/hosted/beta-key records a pending_delivery signup request, returns 202, and creates no hosted account, no API key, and no credits. After SMTP is configured and smoke-tested, operators can use the protected pending-signup drain to provision and email keys.

Verification: - Regression test went red against stale copy, then green: tests/unit/website/test_hosted_status_copy.py -> 1 passed. - Website smoke: tests/unit/website/test_launch_website.py -> 29 passed, 2 warnings. - Billing/admin/signup suites: 53 passed, 2 warnings. - Pyright and Ruff passed for changed Python test files. - Production deployed at commit f73475a; /health is green and /status now shows "Current blockers: external configuration."

Still pending: Production still needs SMTP configuration, Stripe Checkout configuration, Stripe webhook secret, Stripe paid package price IDs, and a live Stripe test-mode checkout/webhook/key-delivery smoke before hosted self-service can be called production-ready.

2026-07-03 — Beta request status self-service

What changed: Added POST /v1/hosted/beta-key/status and a matching "Already registered?" form on /beta so testers can check whether their beta request is queued, delivered, failed, duplicate, account-backed, or not found.

Why it matters: Before this, a tester who submitted a request but did not receive an email had no self-service answer. This created support load and made queued/delivery states invisible to the customer side of the flow.

Safety decisions: - The lookup uses only email because the tester does not have an API key yet. - It returns no raw API key and no key hash. - It returns only non-secret state, IDs when an account exists, and guidance copy. - It shares the public signup rate limiter to reduce enumeration/abuse risk.

Verification: TDD red produced 5 expected failures for the missing route, schema, and page controls. After implementation, the same focused suite reported 5 passed, 2 warnings.

2026-07-03 — Hosted beta key recovery

What changed: Added POST /v1/hosted/beta-key/reissue and a "Lost your API key?" form on /beta.

Why it matters: Scout stores only hosted API-key hashes. A tester who loses their original emailed key cannot retrieve it, and before this slice they also could not self-serve a replacement.

Core behavior: - The tester enters only their email. - If the email has a hosted account and SMTP delivery is configured, Scout issues a replacement key, emails the raw key to that same inbox, and returns only non-secret metadata. - The previous key is disabled only after replacement email delivery succeeds. - Unknown emails receive a non-enumerating accepted message. - If SMTP delivery is not configured, the endpoint fails closed with 503 rather than creating a raw key that cannot be delivered.

Verification: TDD red produced 5 expected failures for the missing route, schema, and beta-page controls. After implementation, the focused suite reported 5 passed, 2 warnings; affected hosted/account/website suites reported 74 passed, 2 warnings.

Deployment check: Commit 8799958 was pushed to GitHub and deployed to the VPS. Production health is green. /beta contains hostedKeyReissueForm. POST /v1/hosted/beta-key/reissue currently returns 503 Hosted API key delivery is not configured, which is the expected fail-closed behavior until SMTP delivery is configured.

2026-07-03 — Hosted payment readiness diagnostics

What changed: Expanded GET /v1/billing/stripe/status with non-secret, operator-actionable diagnostics while preserving the existing readiness booleans.

Why it matters: The previous status contract told the website and operator tools that hosted checkout or key delivery was not ready, but not which setup steps were missing. That made /pricing and /status feel opaque and forced operators to infer the blocker from environment variables.

New response fields: - missing_configuration: machine-readable names such as stripe_checkout, stripe_webhook_secret, and hosted_key_delivery_smtp. - blocking_reasons: user/operator-readable reasons that the launch website can display when checkout is paused. - operator_next_actions: setup actions to complete without exposing secret values.

Website behavior: website/assets/pricing.js now prefers the API-provided readiness reasons and next actions over the old generic paused message.

Safety decisions: - The route remains unauthenticated and public, so diagnostics are capability names only. - It never returns Stripe secrets, webhook secret values, SMTP passwords, raw hosted API keys, or key hashes. - Existing booleans remain unchanged for current callers.

Verification: TDD red produced expected failures for missing diagnostic fields and the pricing script not consuming them. Focused green verification: tests/unit/api/test_billing_stripe_checkout.py reported 11 passed, 2 warnings; the targeted pricing website test reported 1 passed, 2 warnings.

Still pending: Production still needs actual SMTP key delivery configuration, Stripe Checkout configuration, and Stripe webhook secret configuration before beta checkout or paid checkout can be called ready.

2026-07-03 — Structured hosted credit policy

What changed: Added a structured credit_policy array to GET /v1/billing/packages while preserving the older credit_costs prose map.

Why it matters: Consuming apps, the pricing page, and future account surfaces should not have to parse text like "1 standard credit" to understand how Scout meters hosted usage. The billing package response now carries machine-readable rows for each metered action.

New policy fields: - action - credit_type - credits_per_unit - metered_unit - included_in_standard_1000 - customer_description

Website behavior: website/assets/pricing.js now prefers structured credit_policy cards and falls back to the old credit_costs map only if an older response is served.

Business-model impact: This makes the $10 / 1,000 standard credits candidate clearer: the package maps to about 1,000 scrapes, 1,000 returned crawl/map pages, or 333 screenshots. Browser actions are explicitly separate and not included in the first standard-credit package.

Still pending: This does not configure Stripe or SMTP. It tightens the metering and packaging contract that those flows will sell.

2026-07-03 — Stripe smoke helper correctness

What changed: Corrected the Stripe test-mode smoke helper so it can verify the real hosted checkout contract once Stripe and SMTP are configured.

Why it matters: The helper previously posted only email and package_id, but the hosted checkout route requires name, email, and package_id. That would have made the first real Stripe smoke fail with a validation error even if Stripe itself was correctly configured.

Core behavior: - scripts/stripe_test_mode_smoke.py now accepts --name. - Checkout smoke requests include name, email, and package_id. - HTTPS calls use a certifi-backed TLS context, matching the hosted readiness checker and avoiding local certificate-chain failures. - Docs examples now include the name field for both paid package and $0 beta trial smoke commands.

Verification: TDD red caught the missing name parameter and HTTPS TLS context. Focused green verification: python3 -m pytest tests/unit/test_stripe_test_mode_smoke.py tests/unit/scripts/test_vps_admin_scripts.py tests/unit/test_launch_governance_docs.py tests/unit/test_hosted_pricing_docs.py -q reported 61 passed. Pyright reported 0 errors; Ruff check and format check were clean.

Live check: Running the helper against https://scout.chowmes.com now reaches Scout's real readiness response and fails for the expected external configuration blockers: Stripe Checkout, Stripe webhook secret, and hosted SMTP key delivery are not configured.

Follow-up: The helper now prints package-specific readiness labels. For beta_trial, live failure output says Stripe beta checkout is not ready; for paid credit packages, it says Stripe paid-key delivery is not ready. Focused verification reported 9 passed, Pyright 0 errors, and Ruff clean.

2026-07-03 — Hosted production smoke gate

What changed: Added scripts/hosted_production_smoke.py and exposed it as scripts/scout-hosted-admin production-smoke.

Why it matters: The previous operator tools could show readiness blockers, but there was no single command that answered "is hosted Scout actually ready for beta signup and paid checkout?" The new gate returns one non-secret truth object with ok, health/package readiness, beta signup readiness, paid checkout readiness, Stripe smoke status, blockers, and next steps.

Behavior: - Always checks /health, /v1/billing/packages, and /v1/billing/stripe/status. - Stops before Stripe smoke when SMTP/Stripe readiness is already blocked. - Runs non-mutating Stripe smoke checks for both beta_trial and standard_1000 only when readiness flags are green. - Provides exact next operator commands for SMTP, Stripe price/bootstrap, webhook, and smoke testing. - Does not print Stripe secrets, webhook secrets, SMTP passwords, raw hosted API keys, or key hashes.

Live status recorded: https://scout.chowmes.com has green health and package metadata. It is still not production-ready because hosted API key email delivery, Stripe Checkout, Stripe webhook secret, card-backed beta checkout, and paid checkout/key delivery are not configured.

Verification: TDD red failed on the missing production smoke module. Focused green verification reported 24 passed. Pyright reported 0 errors; Ruff check and format check were clean. Live scripts/scout-hosted-admin production-smoke --json returned ok: false with the expected blockers and next commands.

Deployment follow-up: Commit 94de315 fixed direct execution on the VPS by adding a repo-root import path guard. The VPS checkout fast-forwarded to 94de315, and scripts/scout-hosted-admin production-smoke --json now runs successfully on the server, returning the expected hosted blockers instead of a Python import failure.

2026-07-03 — Public beta signup is Stripe setup first (superseded)

Superseded by wiki/decisions/2026-07-03-email-first-beta-registration-supersedes-stripe-first.md. Current deployed public beta registration is email-first through /v1/hosted/beta-key; Stripe remains paid checkout and future/secondary card-backed verification.

What changed: Updated the public beta website and documentation so hosted beta access starts through card-backed $0 Stripe setup, not a direct name/email API-key form.

Why it matters: Arijit's production-readiness goal says even beta testers should exercise the payment pipeline with a $0 setup flow, so Scout verifies Checkout, signed webhook provisioning, and email key delivery before the tester uses the hosted API. The previous /beta page still offered a direct "Email My Beta Key" path, which weakened that goal.

Current public contract: - /beta#beta-key uses POST /v1/billing/stripe/checkout-session with package beta_trial. - Stripe setup is $0 but collects the payment method and exercises the Checkout/webhook path. - The signed webhook provisions the hosted beta account and SMTP emails the one-time API key. - Raw hosted API keys are never shown in the browser. - /v1/hosted/beta-key remains as a backend compatibility/admin recovery path for pending delivery and operational tooling, but it is no longer the advertised public self-service CTA.

Verification: TDD red caught the old direct hostedKeyForm on /beta. Focused green verification reported 77 passed, 2 warnings; Pyright reported 0 errors; Ruff check and format check were clean.

Deployment: Commit 9a03462 was pushed to GitHub, pulled on the VPS, rebuilt into the docker-scout image, and the scout container was recreated. Production health returned ok. Live https://scout.chowmes.com/beta now has pricingCheckoutForm and /v1/billing/stripe/checkout-session, and no longer has hostedKeyForm or the Email My Beta Key button.

2026-07-03 — Beta readiness requires card-backed checkout readiness

What changed: Tightened the hosted readiness checker so beta signup readiness means ready_for_beta_checkout, not only ready_for_beta_key_delivery.

Why it matters: Public /beta is now card-backed $0 Stripe setup first. If SMTP is configured but Stripe Checkout or webhook signing is missing, Scout must still report beta signup as blocked. The old readiness checker would have called beta ready too early.

Behavior: - scripts/scout-hosted-admin readiness --require-beta-signup now fails unless the beta setup Checkout path is ready. - scripts/scout-hosted-admin production-smoke --json now reports card-backed beta checkout not ready when Stripe/webhook/SMTP are incomplete. - Paid checkout readiness remains tied to ready_for_paid_key_delivery.

Verification: TDD red proved the old checker returned beta-ready when only key delivery was ready. Focused green verification reported 17 passed; Pyright reported 0 errors; Ruff check and format check were clean. Live production smoke now reports card-backed beta checkout not ready.

2026-07-03 — Public copy corrected to match hosted readiness truth

What changed: Updated the Scout website status, pricing, terms, and legal copy so it no longer claims the beta is ready or says beta key generation does not require Stripe.

Why it matters: The hosted production smoke gate is the source of truth. Current live smoke says the service is online, but self-service onboarding is blocked by missing SMTP, Stripe Checkout, and Stripe webhook configuration. The public site should mirror that state rather than overpromise.

Current public message: - hosted API health and package metadata are online, - beta signup is configuration-blocked, - $0 Stripe Checkout is the intended beta setup path, - the beta key is emailed after signed webhook provisioning succeeds, - Scout is credit-metered and does not offer unlimited hosted crawling.

Verification: Focused website/pricing/readiness tests reported 40 passed. Live production-smoke --json still reports ok: false with SMTP and Stripe blockers, which is expected until production secrets are installed and smoke-tested.

2026-07-03 — Stripe setup-mode beta payload corrected

What changed: Updated the $0 beta Checkout payload so beta_trial uses Stripe Checkout mode=setup without sending customer_creation=always.

Why it matters: Beta testers should complete a card-backed setup flow, but that flow must use Stripe's setup-mode contract. customer_creation=always belongs on paid mode=payment Checkout sessions, where Scout still sends it with the package price line item.

Verification: A new transport-level regression test failed before the fix because setup-mode payloads contained customer_creation. Focused Stripe checkout/webhook/payment verification reported 40 passed; Pyright reported 0 errors; Ruff check and format check were clean.

2026-07-03 — Current deployed beta path corrected back to email-first

What changed: The Scout vault had conflicting beta onboarding records. Some later notes said public beta signup was Stripe setup first, but the current repo and live site are deployed with direct email registration: /beta contains hostedKeyForm, posts to /v1/hosted/beta-key, and does not contain pricingCheckoutForm or /v1/billing/stripe/checkout-session.

Current truth: The deployed public beta path is email-first registration. Stripe remains the paid checkout path and a future/secondary card-backed verification path. It is not the current public beta entry point.

Evidence: Production is healthy at Scout commit 858c7af Remove legacy direct beta key telemetry. https://scout.chowmes.com/v1/billing/stripe/status reports public_self_service_path=email_beta_registration, public_beta_key_endpoint=/v1/hosted/beta-key, beta_signup_enabled=true, checkout_configured=false, webhook_configured=false, and key_delivery_configured=false.

Verification: The cleanup commit was pushed and deployed. Focused cleanup verification reported 84 passed, 2 warnings, Pyright 0 errors, and Ruff clean. Live /health returns ok. Live /beta contains the email beta key form and does not contain the Stripe checkout form.

Still pending: SMTP key delivery must be configured and smoke-tested before email-first beta can deliver keys. Stripe secret, success/cancel URLs, paid package price IDs, webhook secret, and checkout/webhook smoke are still required before paid self-service can be called production-ready.

2026-07-03 — Hosted beta docs and production status copy aligned

What changed: Corrected active repo docs and the public /status page so they match the deployed email-first beta path. The status page now says hosted beta signup can register testers and queue API-key delivery, and that without SMTP requests enter a pending delivery queue without creating accounts, keys, or credits.

Files changed in repo: docs/product/public-hosted-launch-readiness-plan-2026-07-03.md, docs/product/website-copy-review-2026-06-28.md, and website/status.html.

Verification: Focused website/governance tests reported 60 passed, 2 warnings; hosted API/billing/readiness tests reported 55 passed, 2 warnings; Pyright reported 0 errors; Ruff check and format check were clean for touched Python surfaces. Production deploy to commit 7900997 is healthy, public /health returns ok, and public /status contains the pending-delivery copy while no longer claiming immediate beta account provisioning.

Still pending: Same external blockers remain: SMTP key delivery, Stripe Checkout, Stripe webhook secret, paid package price IDs, and live checkout / webhook / key-delivery smoke.

2026-07-03 — Docker license packaging blocker closed

What changed: Fixed the Docker distribution path so the production image copies the root LICENSE file alongside README.md, THIRD_PARTY_NOTICES.md, and pyproject.toml before pip install .. Also updated .dockerignore so LICENSE is not excluded from Docker build context, and tightened tests/unit/test_docker_distribution.py to prevent the regression.

Why it matters: Local readiness reported Public launch: ready, but the production container could report license-file-missing because the image did not include the license file. That made production readiness inconsistent with the repo.

Evidence: Repo commit eca3ee2 Include license in Docker distribution is pushed to origin/codex/scout-saas-prod-ready and deployed on https://scout.chowmes.com. Production /health returns ok; VPS git HEAD is eca3ee2; the scout Docker service is healthy. Running python -m scout.cli launch-readiness --require-hosted-saas inside the production container now reports Public launch: ready and Hosted SaaS: blocked with the five expected external SMTP/Stripe blockers.

Verification: The Docker regression test failed before the patch, then passed after the fix. Focused verification reported 99 passed, 8 warnings; Pyright reported 0 errors; Ruff check and format check were clean. A local docker build -f docker/Dockerfile -t scout:license-smoke . completed successfully, and the readiness command inside that image matched the production result.

Still pending: Hosted SaaS remains blocked until SMTP API-key email delivery, Stripe Checkout, Stripe webhook signing, beta email smoke, and paid checkout/key-delivery smoke are configured and verified.

2026-07-03 — Hosted SMTP config preflight aligned with production readiness

What changed: Tightened scripts/scout-validate-hosted-config so --require beta now requires HOSTED_KEY_DELIVERY_SMTP_USERNAME and HOSTED_KEY_DELIVERY_SMTP_PASSWORD, not only SMTP host/from/port. Updated admin script help text and docs/product/hosted-admin-operations.md to say production hosted key delivery requires authenticated SMTP configuration.

Why it matters: Production readiness already reported SMTP username and password as missing. Local preflight previously allowed a config that could pass locally but still fail the hosted SaaS gate. The operator path now fails earlier and with the same missing keys.

Verification: Added a regression test proving beta config without SMTP credentials fails. Focused verification reported tests/unit/scripts/test_vps_admin_scripts.py: 23 passed, tests/unit/scripts/test_hosted_readiness_check.py and tests/unit/scripts/test_hosted_production_smoke.py: 8 passed, and combined admin/governance verification reported 52 passed. Pyright reported 0 errors; Ruff check and format check were clean. Running scripts/scout-hosted-admin validate-config --secrets-file secrets/scout-production.env --require beta now reports missing SMTP host, username, and password.

Still pending: Actual SMTP provider values are not installed. Stripe secret, Stripe paid price IDs, webhook secret, beta email smoke, and paid checkout smoke remain open hosted SaaS blockers.

2026-07-03 — Beta Stripe return URLs split from paid pricing redirects

What changed: Added beta-specific Stripe return URL configuration: STRIPE_BETA_SUCCESS_URL and STRIPE_BETA_CANCEL_URL. beta_trial checkout now returns to /beta?checkout=... when those settings are present, while paid credit packages keep returning to /pricing?checkout=.... Updated the FastAPI settings binding, Stripe checkout service, env template, VPS hosted-env allowlist, hosted config validator, product docs, distribution docs, and tests.

Why it matters: Beta testers should not be dropped on the pricing page after the $0 card-backed setup flow. This keeps the self-service beta path coherent without breaking older deployments because beta URLs fall back to the generic Stripe URLs when omitted.

Verification: The regression tests failed before the script/docs patch, then passed after the fix. Focused verification reported tests/unit/scripts/test_vps_admin_scripts.py tests/unit/test_hosted_pricing_docs.py: 27 passed and tests/unit/core/platform/test_stripe_checkout.py tests/unit/api/test_billing_stripe_checkout.py tests/unit/scripts/test_hosted_readiness_check.py tests/unit/test_stripe_test_mode_smoke.py: 38 passed. Pyright reported 0 errors; Ruff check and format check were clean.

Still pending: Real Stripe and SMTP values are not configured in production. Production health is OK, but card-backed beta checkout, paid checkout, webhook delivery, hosted key email delivery, and live checkout smoke remain open.

2026-07-03 — Beta signup copy corrected to email-first with checkout hook

What changed: Updated the beta registration surface and billing status contract so the public path is clearly email-first: email_beta_registration_with_checkout_hook. The /beta page now says Register for Beta API Key and explains name/email registration plus email delivery. The Stripe beta checkout endpoint remains wired for future $0 card-backed setup, but it is not the primary public CTA while Stripe/SMTP are externally blocked.

Why it matters: The previous site copy made the blocked Stripe setup flow look like the live onboarding path. That was confusing for testers and for downstream apps trying to understand how to get a Scout API key. The corrected contract preserves the longer-term Stripe hook while making the currently usable self-service path explicit.

Verification: Added failing website/API tests for the stale checkout-first copy and status value, then patched code/docs. Focused verification reported 91 passed, 2 warnings; Pyright reported 0 errors; Ruff check and format check were clean. Repo commit ccd940b Make beta signup email-first was pushed and deployed. VPS remote HEAD is ccd940b, the scout container is healthy, https://scout.chowmes.com/health returns OK, and live /v1/billing/stripe/status returns public_self_service_path=email_beta_registration_with_checkout_hook.

Still pending: Production still needs SMTP credentials, Stripe secret, paid price IDs, webhook secret, and live SMTP/Stripe smoke tests before hosted SaaS onboarding and billing can be called production-complete.

2026-07-03 — Hosted readiness checker moved to email-first beta gate

What changed: Updated scripts/hosted_readiness_check.py so ready_for_beta_signup is based on ready_for_beta_key_delivery, not ready_for_beta_checkout. Updated distribution and admin docs to explain that beta signup readiness is email key delivery readiness; Stripe checkout remains separate for future $0 verification and paid credit packages.

Why it matters: Under the email-first beta contract, SMTP key delivery is the gate that proves beta testers can self-register and receive a key. The old checker would have kept reporting beta signup blocked even after SMTP was configured, simply because Stripe checkout was not ready.

Verification: TDD red test reproduced the stale behavior, then passed after the patch. Focused verification reported 54 passed, 2 warnings; Pyright reported 0 errors; Ruff check and format check were clean. Live readiness against https://scout.chowmes.com reports health/packages ready and beta blocked by hosted beta key delivery not ready, which matches the real missing SMTP configuration.

Still pending: Install SMTP credentials, smoke-test email delivery, process pending signups, configure Stripe secrets/price IDs/webhook, and run live Stripe checkout/webhook/key-delivery smoke.

2026-07-03 — Beta page now follows email registration gate

What changed: Updated /beta and website/assets/hosted-keygen.js so the public beta form checks ready_for_beta_key_delivery and submits the email-first /v1/hosted/beta-key path. Removed user-facing "card-backed beta checkout" and "fallback to email queue" language from the beta registration flow.

Why it matters: The backend and readiness checker had already moved to email-first beta key delivery, but the browser form was still wired around the Stripe checkout readiness flag. That meant the public UX could stay mentally and functionally attached to checkout even when the actual beta gate is SMTP key delivery.

Verification: Website regression tests failed first on the stale ready_for_beta_checkout contract. After the patch, tests/unit/website/test_launch_website.py reported 30 passed, and the focused website/billing/readiness/hosted-signup set reported 82 passed, 2 warnings. Ruff check and format check were clean for the touched Python test.

Still pending: SMTP credentials and smoke testing are still required before the email-first beta path can deliver live API keys. Stripe paid checkout and webhook smoke remain separate blockers.

2026-07-03 — Pricing and quickstart now match email-first beta

What changed: Updated the public pricing page, quickstart page, pricing JS, unit-economics doc, hosted admin operations doc, and public hosted launch plan so beta access starts with email-first registration. Paid Stripe Checkout is now described only as the separate hosted-credit purchase path and optional future verification hook.

Why it matters: The beta page and readiness checker had moved to ready_for_beta_key_delivery, but /pricing and /quickstart still told users beta setup used $0 Stripe Checkout with a queued email fallback. That created a split-brain launch story and made it unclear how a tester actually gets a Scout API key.

Verification: Website/docs tests failed first on the stale copy. After the patch, website/pricing docs verification reported 34 passed, 2 warnings, and the adjacent website/pricing/billing/readiness set reported 57 passed, 2 warnings. Ruff check and format check were clean.

Still pending: SMTP credentials and live delivery smoke are still required to make email-first beta key delivery operational. Stripe paid package checkout still needs secret, webhook, price IDs, and live smoke.

2026-07-03 — Hosted billing self-service portal endpoint

What changed: Added a Bearer-key protected Stripe Customer Portal path for hosted Scout accounts. /v1/billing/stripe/customer-portal-session now looks up the authenticated tenant's latest stored Stripe customer_id, creates a short-lived Customer Portal session, and returns only the non-secret portal URL. The hosted account summary now advertises the billing portal link, and the public /account page includes a "Manage billing in Stripe" action after a successful account lookup.

Why it matters: Scout already had paid checkout, purchase history, usage metering, and account lookup, but paid users had no self-service billing management path. This moves Scout closer to a normal hosted SaaS motion: customers can inspect credits and open Stripe billing management without emailing Arijit or exposing Stripe customer IDs in the browser.

Verification: TDD RED tests first failed on missing portal service and dependency symbols. After implementation, the focused portal/account/site test set reported 61 passed, 2 warnings; script/docs verification reported 57 passed; the full unit suite reported 789 passed, 8 warnings; Pyright reported 0 errors; Ruff check and format check were clean.

Still pending: Live Stripe credentials, webhook secret, price IDs, SMTP key delivery credentials, and real Stripe test-mode smoke are still required before the hosted paid flow is production-operational. The new portal endpoint is implemented and tested locally but cannot create live Stripe portal sessions until STRIPE_SECRET_KEY and STRIPE_PORTAL_RETURN_URL are configured on the VPS.

Follow-up in same checkpoint: Tightened /v1/billing/stripe/status so paid readiness now reports customer_portal_configured, public_customer_portal_endpoint, and STRIPE_PORTAL_RETURN_URL as a missing configuration when absent. This prevents the hosted status page/API from looking closer to paid self-service readiness than it really is.

2026-07-03 — Beta readiness now means card-backed setup readiness

What changed: Reversed the prior email-first launch stance to match the current production-readiness goal. /beta still records name/email requests through /v1/hosted/beta-key when checkout is not configured, but the live beta onboarding path now keys off ready_for_beta_checkout. When that flag is true, the beta form creates a $0 Stripe setup session through /v1/billing/stripe/checkout-session; the signed webhook provisions the finite-credit account and SMTP delivery emails the API key. The hosted readiness checker now blocks beta readiness when checkout/webhook/SMTP are not all ready.

Why it matters: Arijit wants hosted Scout to behave like a real SaaS, with self-service registration, measurement, metering, and a verified payment/setup pipeline. Email capture alone is useful as a fallback queue, but it does not prove the customer onboarding or billing pipeline. The distinction is now encoded in website copy, /v1/billing/stripe/status next actions, docs, and tests.

Verification: TDD tests first failed on the stale ready_for_beta_key_delivery public beta contract. After the patch, the focused website/billing/hosted-signup/readiness/docs set reported 88 passed, 2 warnings; the full unit suite reported 789 passed, 8 warnings; Pyright reported 0 errors; Ruff check and format check were clean.

Still pending: Live operation still requires production SMTP settings, Stripe secret, Stripe webhook secret, price IDs, STRIPE_PORTAL_RETURN_URL, and live Stripe/SMTP smoke tests. The code path is implemented and tested, but the hosted SaaS flow is not fully operational until those external configuration gates close.

2026-07-03 — Production docs aligned to card-backed beta setup

What changed: Updated the hosted pricing, distribution, and admin operations docs so they no longer describe beta onboarding as email-first/invite-controlled. The documented production path is now card-backed $0 beta_trial setup when Stripe Checkout, signed webhook, and SMTP key delivery are configured. Name/email capture through /v1/hosted/beta-key remains documented as a request queue/fallback while those live settings are missing.

Why it matters: The code and website had already moved to ready_for_beta_checkout, but stale docs still implied a weaker email-only or manually controlled launch posture. That created an operational mismatch for future agents, PRISM consumers, and anyone trying to understand how Scout keys are supposed to be issued.

Verification: Added failing doc tests first. They failed against the stale copy, then passed after the docs were corrected. Focused hosted billing/signup/admin/doc verification reported 89 passed, 2 warnings.

Still pending: Live production still needs real SMTP settings, Stripe secret, Stripe webhook secret, paid package Stripe price IDs, STRIPE_PORTAL_RETURN_URL, and Stripe/SMTP smoke tests before beta checkout and paid checkout are operational end to end.

2026-07-03 — Public beta request route no longer bypasses card setup

What changed: Changed POST /v1/hosted/beta-key from a public key-provisioning path into a request-capture path. It now records pending_delivery requests only and never provisions a tenant, emails a key, or creates a usable API key directly from the public route. Actual public self-service key issuance must come from the signed Stripe Checkout webhook after card-backed $0 beta setup, or from the protected admin delivery path for queued requests.

Why it matters: The website had been updated to prefer ready_for_beta_checkout, but the raw public endpoint could still be called directly to bypass the card-backed setup requirement when SMTP was configured. That would have undermined the SaaS onboarding and measurement pipeline. The route contract now matches the production-readiness goal.

Verification: Updated hosted API tests first and confirmed the red failures on the old behavior. After implementation, affected hosted/site/doc tests reported 63 passed, 2 warnings; full unit tests reported 789 passed, 8 warnings; Pyright reported 0 errors; Ruff check and format check were clean.

Still pending: Live beta checkout still cannot complete until SMTP and Stripe configuration are supplied on the VPS and smoke-tested.

Deployment evidence: Commit 72576b5 was pushed to GitHub and deployed to the VPS. The container had to be rebuilt with docker compose up -d --build because recreating without build left the old image code running. After rebuild, the VPS reported scout healthy on commit 72576b5. A live POST to https://scout.chowmes.com/v1/hosted/beta-key returned HTTP 202, delivery_status=pending_delivery, empty tenant_id, empty key_id, no raw key, and the updated warning: "Scout will email your API key after card-backed beta setup or operator delivery."

2026-07-03 — Hosted env restart now rebuilds Scout container

What changed: Updated scripts/scout-vps-configure-hosted-env --restart so the VPS restart path runs Docker Compose with --build --force-recreate before checking container health. Distribution and hosted-admin docs now call out that --restart rebuilds intentionally.

Why it matters: During the hosted beta-route deployment, recreating the container without --build left production serving an older image even though GitHub and the VPS working tree were on the new commit. This created false confidence and wasted time. The production configuration path now defends against that exact failure mode.

Verification: Added a failing unit assertion proving the old script did not rebuild, patched the script, then reran python3 -m pytest tests/unit/scripts/test_vps_admin_scripts.py -q with 25 passed. bash -n scripts/scout-vps-configure-hosted-env also passed.

Still pending: This does not close the external production blockers. Stripe secret, Stripe webhook secret, paid package price IDs, STRIPE_PORTAL_RETURN_URL, SMTP delivery settings, and live Stripe/SMTP smoke tests are still required before hosted beta checkout and paid checkout are fully operational.

2026-07-03 — API-key delivery emails now distinguish beta trial from paid packages

What changed: Added package metadata to hosted API-key delivery requests: package_id, standard_credits, browser_credits, and trial_days. The delivery email now renders beta-trial copy only for beta_trial; first-time paid package buyers receive paid hosted API-key copy with the purchased package ID and actual standard/browser credit counts. Stripe webhook key delivery now passes the canonical package metadata into the delivery layer.

Why it matters: The same SMTP delivery service handles both $0 beta setup and first-time paid package provisioning. Before this change, every key email used beta-trial subject/body copy, which would mislead a first-time paid buyer by saying they had a 100-credit beta trial. Self-service onboarding now has a more trustworthy commercial handoff.

Verification: Added a failing key-delivery test for standard_1000; it failed because the email still used Your Scout beta tester API key is ready. After the patch, tests/unit/core/platform/test_key_delivery.py reported 6 passed, and tests/unit/api/test_billing_stripe_webhook.py reported 9 passed.

Still pending: Live SMTP settings and Stripe settings are still required before any production email can actually be sent from scout.chowmes.com.

2026-07-03 — Paid credit packages now map to non-beta hosted plan limits

What changed: Added canonical package-to-plan mapping to scout.core.platform.pricing: beta_trial maps to hosted_beta_pass, standard_1000 and standard_3000 map to hosted_starter, and standard_15000 maps to hosted_pro. Stripe payment provisioning now uses the package's hosted plan when creating first-time paid accounts, and upgrades existing beta tenants when a paid package has higher limits. Existing top-ups never downgrade a tenant and still do not email a second raw API key.

Why it matters: Previously, a first-time paid buyer could receive 1,000 or 15,000 credits while the tenant still had beta-plan operational limits such as 25 max pages per run. That made the commercial package and runtime entitlement disagree. Paid packages now grant both the purchased credits and the intended hosted plan limits.

Verification: Added failing tests showing paid packages were still hosted_beta_pass. After implementation, pricing/payment provisioning tests reported 17 passed, and adjacent Stripe webhook/checkout/hosted account tests reported 58 passed.

Still pending: Live Stripe and SMTP environment values are still required before paid package checkout can run end to end on production.

2026-07-03 — Beta signup now provisions and emails API keys directly

What changed: Superseded the card-backed beta setup direction. Public beta registration now posts name/email to POST /v1/hosted/beta-key. When hosted beta signup and SMTP delivery are configured, Scout provisions a hosted_beta_pass tenant, generates the one-time API key, emails it to the tester, and records a delivered signup event. The browser response still never returns raw_api_key. If SMTP is not configured, Scout records a pending request and does not create an account/key/credits.

Why it matters: This matches the desired beta UX: testers register to get a beta API key without needing a shared invite password or a free Stripe checkout step. Stripe remains the paid hosted-credit checkout path.

Architecture decision: Added wiki/decisions/2026-07-03-direct-beta-email-delivery-supersedes-card-backed-beta.md. ready_for_beta_key_delivery is now the beta readiness signal. The older ready_for_beta_checkout wording is treated as legacy compatibility and should not drive website behavior.

Verification: Added/updated failing tests first, then implemented the route, website, readiness, and docs changes. Focused verification reported 88 passed, 2 warnings. Full unit verification reported 794 passed, 8 warnings; Pyright reported 0 errors; Ruff check/format passed after formatting the website test file.

Still pending: Production still needs SMTP environment values for live email delivery. Paid checkout still needs Stripe secret, webhook secret, portal return URL, and paid price IDs before the paid SaaS path is fully live.

2026-07-03 — Public beta signup smoke added to hosted admin tooling

What changed: Added scripts/hosted_beta_signup_smoke.py and exposed it through scripts/scout-hosted-admin beta-signup-smoke. The helper posts a real name/email beta registration to /v1/hosted/beta-key, checks /v1/hosted/beta-key/status, and reports only non-secret metadata: email, delivery status, tenant id, and key id. It refuses to pass if the beta signup remains pending and fails if any response contains raw-key or secret-looking material.

Why it matters: The hosted beta flow previously had readiness checks for configuration and a VPS SMTP test-email helper, but no single operator command proved the public self-service beta path end to end. Once SMTP is configured, operators can now verify that the website/API signup path really emails a key without exposing that key in terminal output.

Verification: Added failing tests first for the missing helper and missing admin wrapper command. After implementation, focused script/admin tests reported 38 passed, 2 warnings, Pyright reported 0 errors for the new helper, Ruff passed for the Python files, bash -n scripts/scout-hosted-admin passed, and the full unit suite reported 798 passed, 8 warnings.

Still pending: This smoke cannot pass on production until SMTP delivery is configured. Current live readiness still reports missing SMTP and Stripe settings.

2026-07-03 — Production smoke gate terminology corrected

What changed: Updated scripts/hosted_production_smoke.py so the beta gate is named and reported as beta key email delivery, not beta Stripe checkout. The smoke now runs Stripe checkout smoke only for the paid package path.

Why it matters: Scout's current public beta implementation is direct name/email registration with emailed API-key delivery. The production smoke output now matches that product decision and avoids sending operators down the wrong beta-checkout path.

Verification: Focused hosted smoke/readiness tests reported 12 passed. Full unit verification reported 798 passed, 8 warnings. Pyright and Ruff passed for the changed smoke script and test.

2026-07-03 — Hosted config validator now rejects obsolete beta Stripe price IDs

What changed: Updated scripts/scout-validate-hosted-config to warn/fail when STRIPE_BETA_PRICE_ID is present in a production secrets file. The current beta path is direct name/email registration with emailed API-key delivery; beta does not use a reusable Stripe price id.

Why it matters: The local ignored production env file still had a stale STRIPE_BETA_PRICE_ID placeholder. The validator now points operators at the real remaining blockers: SMTP delivery values, Stripe paid package price IDs, Stripe secret, portal return URL, and webhook secret.

Verification: Added a failing validator test first, then implemented the obsolete-key warning. Script/admin tests reported 38 passed; full unit verification reported 799 passed, 8 warnings; Ruff and Python compile checks passed for the changed files.

2026-07-03 — Beta page now supports email registration and $0 Stripe setup

What changed: /beta now exposes two self-service beta paths: direct name/email API-key registration and optional card-backed $0 Stripe setup-mode checkout. GET /v1/billing/stripe/status now advertises public_beta_checkout_endpoint=/v1/billing/stripe/checkout-session, and the production smoke gate separately tracks beta key delivery, beta Stripe setup, and paid checkout.

Why it matters: This reconciles the product goal: testers can register by email without an invite password, while the Stripe pipeline can still be verified for beta testers with a $0 card setup before paid packages go live.

Verification: Added failing API/website expectations first, implemented the beta checkout UI/status wiring, then updated readiness and smoke gates. Focused billing/website/readiness tests reported 58 passed; full unit verification reported 799 passed, 8 warnings; Pyright, Ruff, and node --check website/assets/hosted-keygen.js passed.

Still pending: Production still needs SMTP and Stripe environment values before either beta key email delivery or beta Stripe setup can pass live smoke.

2026-07-03 — Public beta copy aligned with passwordless self-service signup

What changed: Removed stale public-facing language that implied hosted beta was invite-only, manually provisioned, or showed a raw API key in the browser. The website and README now describe the actual hosted contract: users register with name/email, Scout records the request in the hosted database, Scout emails the one-time API key when SMTP is configured, and browser/API responses never display raw keys.

Why it matters: The production-readiness goal is self-service access, measurement, metering, and monitoring. Any old "invite password" or "manual operator provisioning" wording fights that goal and creates user confusion. The email-delivery path itself was rechecked: the beta key email includes the API key, credit limits, cURL test, account/usage links, safety instructions, and is signed by Arijit Chowdhury, Founder, Chowmes.

Verification: Added a failing website regression test first for stale invite/manual/key-display phrases. After the copy fix, the regression passed. Focused hosted website/pricing/API tests reported 37 passed, 2 warnings, and node --check website/assets/hosted-keygen.js plus node --check website/assets/pricing.js passed.

Still pending: Production still needs real SMTP settings and Stripe settings before self-service beta key delivery, $0 beta setup, and paid checkout can pass live smoke.

2026-07-03 — Stripe beta setup now creates a Stripe Customer

What changed: Updated the beta_trial Stripe Checkout payload so setup-mode sessions include customer_creation=always. This aligns the $0 card-backed beta flow with the product goal: beta testers can verify the Stripe pipeline and leave Scout with a Stripe Customer/payment-method setup record without being charged.

Why it matters: A $0 setup flow that collects a card but does not explicitly create a Customer weakens the future paid/portal path. The beta setup route now uses Checkout mode=setup, card payment method collection, customer email, package metadata, and customer creation. The signed webhook still provisions the hosted beta account and emails the one-time API key.

Verification: Added failing Stripe payload tests first. After the patch, the specific RED tests passed, the focused Stripe/payment/docs suite reported 49 passed, 2 warnings, Pyright reported 0 errors, Ruff passed, and Ruff format check passed for the changed files.

Still pending: Production cannot live-smoke this until real Stripe credentials, webhook secret, return URLs, and SMTP key delivery are configured.

2026-07-03 — Hosted readiness now preserves operator next actions

What changed: Updated scripts/hosted_readiness_check.py so it preserves and prints operator_next_actions from /v1/billing/stripe/status alongside missing environment variable names and readiness blockers.

Why it matters: The live Scout service is healthy, but beta key delivery, beta Stripe setup, and paid checkout remain blocked until production Stripe and SMTP values are configured. The readiness command now explains the exact operator categories to fix instead of only listing red flags.

Verification: Added a failing readiness-script test first. After the patch, tests/unit/scripts/test_hosted_readiness_check.py reported 5 passed, Ruff passed, and the production readiness command showed the current blockers plus operator next actions for Stripe Checkout, Stripe Customer Portal, Stripe webhook secret, and hosted API-key SMTP delivery.

2026-07-03 — Status page now reads live hosted readiness

What changed: Added a live readiness panel to /status backed by /v1/billing/stripe/status. The page now shows beta key delivery, $0 beta Stripe setup, paid checkout state, missing environment variable names, and operator next actions without exposing secrets.

Why it matters: Hosted Scout should not require terminal access to see why self-service signup or checkout is blocked. The public status surface now mirrors the same non-secret readiness truth as the operator script.

Verification: Added failing website regressions for the live panel and public status.js asset first. After implementation, tests/unit/website/test_hosted_status_copy.py plus nearby website route/status tests reported 5 passed, 2 warnings, node --check website/assets/status.js passed, Pyright passed for the static route and auth middleware, and Ruff passed for the changed files.

2026-07-03 — Current launch docs now match self-service beta access

What changed: Updated the current operating launch docs so they no longer describe hosted beta as invite-only, manually provisioned, or limited to approved testers. The current docs now match the implemented access model: /beta#beta-key posts name/email to /v1/hosted/beta-key, Scout records the signup event, SMTP delivery emails the one-time API key when configured, and the browser/API response never shows the raw key. The docs also now surface the current pricing candidate directly: $10 for 1,000 standard credits, estimated loaded cost $2.59, gross margin 74.1%, and break-even 17 packs/month under the current fixed-cost assumption.

Why it matters: The production-readiness charter is self-service, measurement, metering, and monitoring. Stale invite/manual wording would cause other projects like PRISM and external beta testers to follow the wrong onboarding path.

Verification: Added a failing regression first in tests/unit/test_hosted_pricing_docs.py requiring current launch docs to use self-service beta framing and reject old invite/password phrases. After the docs patch, the targeted test passed. Focused hosted signup, Stripe checkout, webhook, admin metrics, key delivery, pricing, website, status, readiness, JS, Pyright, Ruff, and format checks passed: 117 passed, 2 warnings; node --check passed for hosted website scripts; Pyright reported 0 errors; Ruff and Ruff format checks passed.

Still pending: Live production remains blocked until SMTP delivery and Stripe secrets/price IDs/webhook settings are configured on the VPS and then validated through real beta signup, $0 beta setup, and paid checkout smoke.

2026-07-03 — Public and current docs reject invite-only beta drift

What changed: Tightened the public website and current launch/evidence docs so they no longer say "invited beta testers," "approved testers," or "invite-only" for the current hosted beta. The public /beta page now says beta testers can optionally verify the payment pipeline with $0 Stripe setup, while the primary API-key registration path remains self-service name/email registration through /v1/hosted/beta-key. Current evidence, release, security, registry, and distribution docs now describe finite-credit, rate-limited, attributable self-service beta access instead of manual approval-only access.

Vault cleanup: Updated the latest beta decision record to clarify the current operating truth: direct email registration is primary, optional $0 card-backed setup is secondary when Stripe/webhook/SMTP are configured, and no shared invite password exists.

Verification: Added failing regressions first for the stale public/current copy. After patching, focused website, docs, hosted signup, billing, key delivery, pricing, readiness, JS, Pyright, Ruff, and format checks passed: 111 passed, 2 warnings; JS syntax checks passed; Pyright reported 0 errors; Ruff and Ruff format checks passed.

Still pending: Live production still needs SMTP and Stripe production/test configuration before real beta key email delivery, optional $0 beta setup, and paid checkout can pass end-to-end smoke.

2026-07-03 — Hosted setup report groups the remaining production work

What changed: Added scripts/scout-hosted-admin setup-report, backed by scripts/scout-hosted-setup-report, as a single non-secret operator command for the remaining hosted SaaS setup. The report groups readiness into beta_email_delivery, beta_stripe_setup, and paid_checkout, lists missing environment variable names, and prints the exact next commands for configuration and smoke testing. It refuses to print obvious Stripe secrets, SMTP passwords, hosted API keys, or key hashes.

Why it matters: The live hosted service is healthy, but production self-service is still blocked on external Stripe and SMTP configuration. The operator path now has one entrypoint that explains what is missing without requiring manual stitching across readiness checks, docs, and shell helpers.

Verification: Added failing admin-script tests first for the missing command, grouped capability output, admin wrapper, and no-secret-output guard. After implementation, python3 -m pytest tests/unit/scripts/test_vps_admin_scripts.py -q reported 29 passed.

Still pending: The report does not make beta signup or checkout live by itself. SMTP settings, Stripe secret, Stripe webhook secret, and public package price IDs still need to be configured on the VPS, followed by email delivery, beta signup, beta Stripe setup, and paid checkout smoke tests.

2026-07-03 — Beta API-key email uses actual package limits

What changed: Tightened the hosted beta API-key email so it uses the actual standard_credits, browser_credits, and trial_days values from the provisioning request instead of hardcoding 100 credits / 30 days. The email now also includes a first /v1/hosted/scrape cURL example, while still warning that the raw key is shown only in email, should not be pasted into frontend code or public artifacts, and is signed by Arijit Chowdhury, Founder, Chowmes.

Why it matters: The pricing and beta package model must be truthful in the moment the user receives their key. If the package economics change, the delivery email now follows the account/package data rather than stale copy.

Verification: Added failing delivery tests first for dynamic beta limits and the first hosted scrape example. After implementation, python3 -m pytest tests/unit/core/platform/test_key_delivery.py -q reported 7 passed, 2 warnings.

Still pending: Live email delivery still depends on production SMTP configuration on the VPS.

2026-07-03 — Account page shows per-event metering balance

What changed: Tightened the hosted account metering surface. The /v1/hosted/usage endpoint already returned action, credit type, credits charged, and balance-after fields; the public /account page now renders the credits charged and remaining balance after each recent usage event. The canonical beta package summary also now says "registered beta testers" instead of stale approved/manual beta wording.

Why it matters: Hosted Scout needs measurement and metering that a customer can inspect without an operator. A tester or consuming app can now paste a hosted API key into /account and see not only the current balance but how each recent call changed that balance.

Verification: Added failing API and website regressions first for balance-after customer metering. After implementation, focused API/website checks reported 6 passed, 2 warnings, and node --check website/assets/account.js passed.

Still pending: This improves visibility after a key exists. Live account creation and paid top-up still depend on SMTP/Stripe configuration.

2026-07-03 — Beta page shows readiness blockers and operator next actions

What changed: Tightened the public /beta signup script so it uses the same readiness detail contract as the pricing page. The page now reads blocking_reasons, operator_next_actions, and ready_for_beta_key_delivery from /v1/billing/stripe/status. Email beta registration can stay enabled to record tester requests, but it now says when SMTP key delivery is not configured. Card-backed $0 beta setup stays disabled and explains the exact Stripe/webhook/SMTP blockers instead of showing a vague "not ready" message.

Why it matters: Self-service beta access should be honest. A tester or operator looking at the beta page can now tell whether the problem is signup, SMTP delivery, Stripe Checkout, signed webhook delivery, or another readiness gate without exposing secret values.

Verification: Added failing website regressions first for the missing blocking_reasons, operator_next_actions, and ready_for_beta_key_delivery handling. After implementation, the focused beta tests reported 2 passed; broader website/pricing checks reported 36 passed, 2 warnings; node --check website/assets/hosted-keygen.js, Pyright, Ruff, and Ruff format all passed.

Still pending: Live production still needs SMTP and Stripe settings before real beta key delivery, optional $0 setup, and paid checkout can pass end-to-end smoke.

2026-07-03 — Hosted metrics admin command

What changed: Added scripts/scout-hosted-admin metrics, backed by scripts/scout-vps-hosted-metrics, so hosted operators can inspect the protected /v1/billing/admin/metrics endpoint from the Mac without hand-writing curl or SSH commands. The helper runs inside the Scout container, reads SCOUT_API_KEY from container environment, sends it only as a localhost X-API-Key header, and prints either a compact table or JSON metrics payload.

Why it matters: Measurement and monitoring need to be part of the hosted SaaS operating loop, not only hidden in SQLite or docs. The operator can now quickly inspect signup counts, pending delivery, failed delivery, account counts, credit usage, purchase count, and revenue totals through the same protected API used by the service.

Verification: Added failing admin-script regressions first for the missing metrics command and secret-safety guard. After implementation, python3 -m pytest tests/unit/scripts/test_vps_admin_scripts.py -q reported 30 passed.

Still pending: Metrics are available, but production onboarding still needs SMTP and Stripe settings before live signup delivery and checkout can be fully smoked.

2026-07-03 — Hosted overview command combines readiness and metrics

What changed: Added scripts/scout-hosted-admin overview, backed by scripts/scout-hosted-overview, as a single operator command for the live hosted Scout state. The command prints public readiness first, then protected admin metrics from the running container.

Why it matters: Operators no longer need to run readiness and metrics separately to understand the SaaS state. The current live overview shows both the blockers still preventing production onboarding and the measurable funnel impact: pending beta delivery count, failed signup count, usage events, credits used, purchases, and revenue.

Verification: Added failing admin-script regressions first for the missing overview command and no-secret guard. After implementation, python3 -m pytest tests/unit/scripts/test_vps_admin_scripts.py -q reported 31 passed; shell syntax, Pyright, Ruff, and Ruff format checks passed. Live scripts/scout-hosted-admin overview printed readiness blockers plus hosted metrics.

Still pending: The overview confirms the same external blockers: SMTP and Stripe must be configured before beta key delivery and paid checkout can pass end-to-end.

2026-07-03 — Hosted metrics helper reliability fix

What changed: Reworked scripts/scout-vps-hosted-metrics so the protected metrics call no longer depends on an SSH heredoc. The helper now executes Python inside the running scout container with python3 -c and SCOUT_ADMIN_METRICS_FORMAT, reads SCOUT_API_KEY only inside the container, and prints totals, funnel, economics, and recent row counts.

Why it matters: The production metrics endpoint was healthy and returned funnel/economics data, but the operator wrapper could exit without useful output because of heredoc/SSH quoting. That made the system look unfinished even when the API path worked. Production runbooks need commands that fail loudly and print the measurable state operators need.

Verification: Added a RED regression requiring the metrics helper to avoid SSH heredocs and use python3 -c. After patching, focused tests passed and scripts/scout-hosted-admin metrics --format table printed production totals, funnel, economics, and recent row counts from https://scout.chowmes.com.

Still pending: This fixes monitoring visibility only. SMTP delivery and Stripe Checkout/webhook settings remain required before self-service beta and paid purchase flows can pass end-to-end.

2026-07-03 — Card-backed beta becomes primary onboarding path

What changed: Reworked the public beta UX and operating docs so $0 card-backed beta setup is the recommended first path. The beta page now presents Stripe setup-mode checkout first, labelled as the recommended beta path, and keeps email-only registration as a fallback request queue when Stripe or SMTP is blocked.

Why it matters: The product goal is not only to hand out API keys; it is to prove the real hosted SaaS pipeline before paid launch. Card-backed beta setup exercises Stripe Checkout, payment-method collection, signed webhook provisioning, and SMTP API-key delivery while charging the tester $0. Email-only fallback is still useful for demand capture, but it is not the preferred production onboarding path.

Verification: Added a RED website regression requiring hostedBetaCheckoutForm to appear before hostedKeyForm, requiring Recommended beta path, Use this first when available, and Email-only fallback copy. After implementation, python3 -m pytest tests/unit/test_hosted_pricing_docs.py tests/unit/website/test_launch_website.py tests/unit/website/test_hosted_status_copy.py -q reported 39 passed, 2 warnings.

Still pending: The UX and docs now match the target flow, but live card-backed onboarding remains blocked until Stripe secret, price IDs, webhook secret, and SMTP delivery settings are configured on the VPS.

2026-07-03 — Billing status contract aligned to card-backed beta

What changed: Updated /v1/billing/stripe/status so public_self_service_path reports card_backed_beta_setup_with_email_fallback. Customer next actions now put the $0 Stripe setup-mode beta trial first and the email-only fallback second.

Why it matters: The public website and operating docs were corrected to make card-backed beta the primary onboarding path, but the API readiness contract still named the old email-first path. Status output is consumed by the website, operators, and future integrations, so it must reflect the actual product decision.

Verification: Added a RED expectation in tests/unit/api/test_billing_stripe_checkout.py for the new path name and action order. After implementation, python3 -m pytest tests/unit/api/test_billing_stripe_checkout.py tests/unit/test_hosted_pricing_docs.py tests/unit/website/test_launch_website.py tests/unit/website/test_hosted_status_copy.py -q reported 59 passed, 2 warnings; Pyright and Ruff checks passed.

Still pending: Live status still correctly reports blocked until Stripe and SMTP environment settings are configured.

2026-07-03 — Failed beta delivery retry path

What changed: Added a safe recovery path for failed beta API-key email deliveries. HostedAccountService.failed_signup_requests() now returns the newest retryable failed delivery per email while skipping emails that already have a hosted tenant. The protected API endpoint POST /v1/billing/admin/retry-failed-beta-keys provisions a fresh beta account, emails the one-time API key, records admin_failed_beta_delivery_retry, and returns only non-secret delivery metadata. Operators can run the same recovery from the Mac with scripts/scout-hosted-admin retry-failed-signups --dry-run and --yes.

Why it matters: Production beta signup cannot rely only on the happy path. The live metrics already showed failed signup events; after SMTP is configured, operators now have a tested way to recover those users without hand-editing SQLite, leaking raw keys, or creating duplicate hosted tenants.

Verification: Added failing service, API, and admin-script regressions first. The RED failures were missing failed_signup_requests, missing /v1/billing/admin/retry-failed-beta-keys, and missing scout-vps-retry-failed-beta-signups. After implementation, python3 -m pytest tests/unit/core/platform/test_account_service.py tests/unit/api/test_billing_admin_metrics.py tests/unit/scripts/test_vps_admin_scripts.py tests/unit/test_hosted_pricing_docs.py -q reported 54 passed, 2 warnings; Pyright, Ruff, and Ruff format checks passed.

Still pending: This closes retry mechanics, but live recovery cannot be exercised until SMTP settings are installed on the VPS. Stripe checkout and webhook settings remain the other production-beta blockers.

2026-07-03 — Stripe smoke promoted to hosted admin command

What changed: Added scripts/scout-hosted-admin stripe-smoke, wrapping the existing scripts/stripe_test_mode_smoke.py helper from the primary operator command surface. The helper now has executable permissions and can check readiness for beta_trial or paid packages, with optional --create-checkout to create a real Stripe Checkout Session after Stripe and SMTP are configured.

Why it matters: Production readiness should not require remembering a lower-level Python filename. Operators now use one admin command family for config validation, setup reports, price bootstrap, hosted readiness, beta email smoke, Stripe smoke, metrics, and recovery commands.

Verification: Added failing admin-script regressions first: the smoke helper was not executable and scout-hosted-admin did not expose stripe-smoke. After implementation, focused admin/docs checks reported 37 passed; Pyright, Ruff, and Ruff format checks passed. Live scripts/scout-hosted-admin stripe-smoke --base-url https://scout.chowmes.com --package-id beta_trial failed cleanly with missing flags: checkout_configured, webhook_configured, key_delivery_configured, and ready_for_beta_checkout.

Still pending: The smoke command is ready, but it cannot pass live until SMTP delivery, Stripe secret, Stripe price IDs, and webhook secret are configured on the VPS.

2026-07-03 — Self-service beta signup open by default

What changed: Hosted beta registration now defaults to self-service open. Settings.hosted_beta_signup_enabled defaults to true, and the setup/report scripts no longer require operators to set HOSTED_BETA_SIGNUP_ENABLED=true. The environment variable remains only as a kill switch: HOSTED_BETA_SIGNUP_ENABLED=false pauses new beta signup without disabling existing Bearer keys. The public status diagnostics now stop treating beta signup as missing by default, while explicit false still blocks beta key generation and checkout setup.

Why it matters: The product decision is that beta testers should be able to enter name/email and receive an API key by email. They should not depend on a shared password, a hidden invite flag, or Arijit manually enabling signup before normal beta onboarding works. This moves Scout closer to a normal hosted SaaS flow: register, provision account, deliver key, meter usage.

Verification: Added RED tests for default-open beta key generation and Stripe status semantics. The first RED run failed with 503 for /v1/hosted/beta-key and beta_signup_enabled=false in Stripe status. After implementation, the focused behavior suite reported 5 passed; the broader impacted suite reported 132 passed, 2 warnings; Pyright reported 0 errors; Ruff and script syntax checks passed.

Still pending: SMTP delivery is still required for real live API-key email. Stripe Checkout, webhook, price IDs, and customer portal settings are still required for card-backed beta and paid self-service. Until those secrets are configured on the VPS, the software path exists but live paid/beta onboarding is not production-complete.

Live deployment: Commit d88776a was pushed to origin/codex/scout-saas-prod-ready and deployed to the VPS. The Docker Scout container reported healthy; https://scout.chowmes.com/health returned OK; /v1/billing/stripe/status returned beta_signup_enabled=true. A live beta registration smoke using a scout-live-smoke+...@chowmes.com address returned success=true, delivery_status=pending_delivery, and did not expose a raw scout_live_ key in the HTTP response.

2026-07-03 — Hosted pay-as-you-go pricing posture aligned

What changed: The launch governance docs, pricing docs, and unit tests now agree on the current commercial posture: local Scout remains free; hosted Scout uses finite, metered credits; beta registration is self-service by name/email; and the approved current beta paid packages are $10 / 1,000, $25 / 3,000, and $100 / 15,000 standard credits. Browser-heavy work remains separate and paid self-service remains blocked until Stripe and SMTP live smoke pass.

Unit economics recorded: The code-backed default model currently estimates the $10 / 1,000 standard-credit package at $2.59 loaded cost, 74.1% gross margin, and 17 packs/month break-even against a $120/month fixed-cost assumption. These are beta-pricing assumptions, not proof of production-scale profitability.

Verification: The focused governance/pricing/API suite reported 70 passed, 2 warnings. The broader impacted suite reported 106 passed, 2 warnings. The full unit suite reported 819 passed, 8 warnings. Pyright reported 0 errors; Ruff check and Ruff format check passed for the touched Python files.

Still pending: Real production SaaS remains unfinished until SMTP delivery, Stripe secret, Stripe package price IDs, Stripe webhook secret, beta key email smoke, and paid checkout smoke are configured and verified on the VPS.