wiki/dev-log.md
Scout - Development Log
2026-07-03 — Hosted Admin Metrics Scope
- Added
metric_scopeto protectedGET /v1/billing/admin/metrics. - Added
metric_scopetoscripts/scout-hosted-admin metrics --format tablevia 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_scopereports:- 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_scopewas 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
funnelsummary: - 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
economicssummary: - total revenue;
- estimated package loaded cost;
- estimated package gross profit;
- estimated package gross margin;
- standard/browser credits used;
standard_1000break-even packages/month;- target gross margin.
- Updated
scripts/scout-hosted-admin metrics --format tableso operator output includesmetric,funnel,economics, andrecent_countssections. - Verification:
- RED failed because
/v1/billing/admin/metricslackedfunnel; - 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/meverification.
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, andbrowser_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
scoutDocker container instead of failing silently. - Verification:
- RED failed because
scout-hosted-economicswas missing andscout-hosted-admin economicsreturned 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/mesmoke tests.
2026-07-03 — Beta Self-Service Realigned To Card-Backed Setup With Email Fallback
- Updated the current beta onboarding contract:
/betais the self-service entrypoint for$0card-backed beta setup when Stripe/webhook/SMTP readiness is true, and it falls back to queued email registration through/v1/hosted/beta-keywhile 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
/betalackeddata-checkout-endpointand 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_assumptionstoGET /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.jsso 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_IDstandard_3000->STRIPE_STANDARD_3000_PRICE_IDstandard_15000->STRIPE_STANDARD_15000_PRICE_ID- Explicitly excluded:
beta_trial, because beta uses$0Checkout 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-envwrites created price IDs back to ignoredsecrets/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 -qreturned24 passed, 2 warnings;python3 -m pyright tests/unit/scripts/test_stripe_price_bootstrap.py tests/unit/scripts/test_vps_admin_scripts.pyreturned0 errors;ruff checkandruff format --checkpassed for the touched Python tests;scripts/scout-hosted-admin bootstrap-stripe-prices --dry-run --jsonreturned 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_deliverybeta registrations after SMTP is configured and smoke-tested. - Behavior:
- fails closed with
503when 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_deliverysignup events; - returns only non-secret email/status/tenant ID/key ID/count metadata.
- Verification:
- TDD red produced expected
404failures 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
a1ed9ectoscout.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 configureduntil 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-emailandscripts/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
7727814toscout.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 ArijitreturnedHosted 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-signupsto queryhosted_signup_eventsfrom/data/hosted_accounts.sqlite. - Supported table and JSON output, row limits,
--statusfilters fordelivered,failed, andduplicate, and--emailfilters 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
0983cc0toscout.chowmes.com. - Production smoke passed:
/healthreturned OK;- Docker reported the
scoutcontainer healthy; scripts/scout-hosted-admin list-signups --format json --limit 5returned 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
/quickstartfor 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.1reference on the quickstart page. - Verification:
python3 -m pytest tests/unit/website/test_launch_website.py -qpassed 15 tests;python3 -m pyright scout/passed with 0 errors;ruff check scout/ tests/ scripts/andruff 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
/appUI from the supported Scout product surface. - Deleted the old HTML frontend module and live-browser page module from the repo source.
- Removed
/api/configso 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 launchready, 0 blockers; - fresh local HTTP smoke:
/healthOK, homepage markers present,/app,/api/config, and/app/live-browserreturn403. - Pushed commit
d27b24eto GitHub branchcodex/scout-platform-foundation. - Redeployed to the Hostinger VPS and verified
https://scout.chowmes.com: /healthOK;- homepage markers present;
/app,/api/config, and/app/live-browserreturn403.
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
8421to127.0.0.1only; - stopped compose from overriding
.envsecrets with defaultdev-key; - set hosted-only mode for public deployment.
- Verification passed:
/scout/healthpublic returns200;/scout/v1/hosted/mewithout Bearer returns401;/scout/v1/hosted/scrapewithout Bearer returns401;/scout/api/configreturns403;/scout/scrapewith the real local admin key returns403;- provisioned hosted Bearer key can call
/v1/hosted/meand/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
Sbrand 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-topso 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
$22one-time and$9/monthhosted 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 isblocked; 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
/appHow 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, andTyped Records.
2026-05-20 — Frontend Product Workbench Slice
- Added Scout's standalone frontend direction: a self-educating app at
/appwith 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_dirwins, otherwise runs are created under CLI--workdir,SCOUT_WORKDIR, or./scout-runs. - Added CLI behavior for high-level
scout runworkflows andscout productsto prompt for a working directory in interactive sessions. - Added HTTP behavior to derive timestamped output directories from
SCOUT_WORKDIRwhen request JSON omitsoutput_dir. - Standardized local secrets and machine-specific configuration on
.env.local, with.env.exampleas the public template. - Added TDD coverage for CLI workdir handling, HTTP derived output directories,
and
.env.localoverride 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/ -vpassed 141 tests;python3 -m pytest tests/ -vpassed 147 tests with 2 intentionally skipped live retail tests;python3 -m pyright scout/reported 0 errors;ruff check scout/ tests/andruff 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
JobSearchProfilewith seedjob_urls,must_have_terms, andreject_terms. - Extended
JobPostingRecordwith 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
objectIDgeneration. - 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-urlCLI 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 -vpassed 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-smokeproduced 1job_posting.v1record,objectID=job_eve_4245857009,ats_platform=greenhouse,match_score=100, and the full Scout artifact set. - Unit suite:
python3 -m pytest tests/unit/ -vpassed 152 tests. - Full suite:
python3 -m pytest tests/ -vpassed 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 andruff format --check scout/ tests/reported 90 files already formatted.
Next build slices:
- Live HTTP acquisition for public job URLs.
- Greenhouse board/API adapter.
- Ashby adapter or browser fallback for JavaScript shell pages.
- Workday and native careers canonicalization/search fallback.
- 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-foundationthrough commit3cc7b57. 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
/betaregistration 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
$0beta 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.