Spaces:
Running
Running
Commit History
6 days ago
-
Merge branch 'claude/dashboard-migration-tse-5669ab' into deploy/mcp Running
0f64d64 -
fix(migrator): declare defusedxml for the Space image; agent doc names the test-Space connector
inspect_dashboard on the test Space returned "No module named 'defusedxml'": the parser's XML library was only present locally as a transitive dependency of notebook tooling and was never in requirements.txt, which is what the Dockerfile installs. Pinned to the version the tests run on. docs: DP Migrator is a dedicated AgentSpot agent wired to the TEST MCP Space (prod does not have the tools yet); sprint ISS-31 records the 2026-11-09 diagnosis and the release options. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>fd1dba7
11 days ago
-
refactor(reporting): name the DEMO_RUN timestamp DEMO_RUN_TIME
The column holds the request time of the latest demo run for the opportunity, so name it for that (boone, 2026-11-04). Renamed in Snowflake the same day. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>ca234c2 -
feat(reporting): DEMO_RUN keeps one row per Salesforce opportunity
The business right-joins its go-to-market data to DEMO_RUN on SALESFORCE_OPPORTUNITY_ID. Every rerun of a demo added another row for the same opportunity, which double-counts the deal (92 opportunities, 322 extra rows on 2026-11-04). The write-through now looks the opportunity up first. If DEMO_RUN already has a row for it, that row is updated to the new run (run id, SE, prospect name, UPDATED_AT = the run's request time, never an older run over a newer one) instead of a second row being inserted. A new opportunity, or a run with no opportunity id, still gets its own row, stamped with UPDATED_AT. DEMO_RESULTS keeps one row per run, keyed by SOURCE_INTAKE_ID, so each rerun's times, status and links survive while several runs share one DEMO_RUN row. Needs the two columns added in Snowflake on 2026-11-04 (DEMO_RUN.UPDATED_AT, DEMO_RESULTS.SOURCE_INTAKE_ID; both filled for every existing row). The hand-run loader got the same rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com…b4f167d
12 days ago
-
chore(portal): re-vendor the TSE template at tse_demos 22312aa (PR #14)
Mani asked for PR #14 on Agent Q staging for a check. Upstream afba4e3 -> 22312aa (e8c51fc, 652c52e, 07c6df4), 9 files, all inside .claude/skills/rebrand-thoughtspot-portal/. MERGED, not copied. Our vendored copy carries in-place edits since the 10-06 re-vendor, so upstream's diff was 3-way merged file by file (base = afba4e3, ours = test tip 58f67a3, theirs = 22312aa). HAND-MERGED (our edits overlap upstream's): scripts/apply-spec.mjs - our clientIdent split (display name in prose, identifier-safe token in code) template-tse/src/config.ts - our Northwind_VIDEO_URL='' and Northwind_UPGRADE_URL=CONTENT.website template-tse/src/styles/globals.css - our --sl-on-primary fallback TAKEN WHOLESALE (we had no edits): App.tsx, flags.ts, lib/thoughtspot.ts, tabs/Analytics.tsx, tabs/Spotter.tsx, tabs/Overview.tsx (new) UNTOUCHED, as the brief requires: chatbot.ts, AskNorthwind.tsx, SignIn…d645d6c -
merge: test Space tip 2093856e2b into develop (pushed to the Space directly)
58f67a3 -
Merge pull request #5 from boone10/feat/t-cancelled-task-status
Unverified signaturefeat(tracker): a "cancelled" task status, closed like "done" without …380d2e2 -
feat(tracker): a "cancelled" task status, closed like "done" without claiming the work was done
- schema.sql: the status check constraint is replaced (drop if exists, add) so the file stays re-runnable; the open-tasks partial index and the task_board stale flag exclude both closed statuses. - store.py: CLOSED = ("done", "cancelled"); update_task sets closed_at for either and clears it on reopen; list_tasks and open_task_by_source hide both unless include_done or the status is asked for by name. - Liveboard TML: every query that excluded done now excludes cancelled too; the model's Status description lists it. - Tool docstrings and the agent write-up (a CANCEL step beside CLOSE). - Tests: cancelled closes, hides, never goes stale, reopens; a cancelled automatic task no longer blocks a new one; the schema says what the code says. The fake client gains supabase-py's `not_` negation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>c1d7132
17 days ago
-
feat(migrator): DP Migrator beta — rebuild a prospect's Tableau dashboard (or a picture of it) as the demo
Ketan's "built-in legacy migrator" and Nick's ask (2026-10-28): the SE sends the prospect's website plus a .twb/.twbx or a dashboard screenshot; the demo's data speaks the dashboard's measure and dimension names and the liveboard copies its sheets (chart types, titles, arrangement; a dual axis as a combo chart) instead of the golden layout. DP Web unchanged. - demoprep_app/migration/: MirrorSpec contract, source-grammar -> ThoughtSpot chart-type mapping, deterministic Tableau .twb parser (defusedxml; paths, hosts and users stripped; blends, relationships, parameters, table calcs and LOD noted), one-vision-call picture reader, the blueprint statement that binds the vocabulary, one liveboard question per sheet in the model's column names, and the argument loader (.twbx -> its .twb only; the payload log keeps kind, size and hash, never content). - liveboards/mirror_layout.py + enhance_mcp_liveboard(layout_strategy="mirror"): retype/retitle from the source before classificat…2093856
18 days ago
-
Merge feature/brand-from-homepage into the test line (ISS-30: browser-default link colours are not brand colours)
8528a7c -
merge: hotfix/dp-web-visible-text into the test line
DP Web visible-text hotfix 2039eea (on prod since 2026-10-27) carried back so the next test -> prod release keeps it: assistant without the template FAQ, company name as given, landing copy normalised, Regular Case keeps acronyms, bundle scan. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>aeed677 -
docs(hotfix): Larry's C2FO site rebuilt in place (revision 2) and verified live
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>d3c8e02
19 days ago
-
docs(hotfix): record the 2026-10-27 prod push, ping confirmation and merge-back previews
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>404bdd2 -
fix(portal): DP Web sites read as the prospect's — name as given, neutral assistant, home copy that renders, acronyms kept
Four generator defects from the 2026-10-27 audit (276 sites, 183 boards), prod line. 1. Assistant (template-tse/src/lib/chatbot.ts): the template's Northwind sales- engagement FAQ shipped on every site renamed to the prospect ("Rhythm is C2Fo's AI engine", links to developers.c2fo.com, /pricing). Rewritten: with no LLM key, data questions go to Spotter and everything else gets one neutral line from company + use case + the real website. No *_DOCS table, no invented video or pricing paths. 2. Name (portal/builder.py, apply-spec.mjs): camel_token() ("C2FO" -> "C2Fo", "BNY Pershing" -> "BnyPershing") was written into the title, assistant name, logo label and nav on 175 sites. The spec now carries `client` = display_name(company) for everything visible and `clientIdent` = camel_token(company) for component and file names only. 3. Home page (mcp_server._landing_content): tagline/cta/string stats were passed through verbatim and rendered as nothing. Now normali…2039eea -
merge: test Space tip 877abd816c into develop (pushed to the Space directly)
3fe8cb3 -
feat(reporting): production runs reach Snowflake DEMO_RUN/DEMO_RESULTS the moment a build completes
The DemoPrep reporting liveboard reads DEMOPREP_REPORTING.REPORTING (DEMO_RUN, DEMO_RESULTS, V_DEMO_RUN), which until now was filled only by the hand-run loader dev_notes/reporting_load_runs.py.txt. Nobody ran it Oct 22-26 and five days of SE builds were missing. A production run - a real Salesforce opportunity id (15/18 alphanumerics, never a TEST-/REPLAY-/XXTEST marker) with environment prod - is now written the moment its build completes; every other run stays Supabase-only for the loader, as before. - demoprep_app/reporting/writer.py: the loader's single-run logic, importable. Same rules verbatim (SFID, TEST_MARKER, INTERNAL, owner skips, IS_TEST_RUN sticky, COALESCE on the opportunity id, err_bucket/cluster/space_of, derived model URL), LOAD_LEDGER keyed by SOURCE_INTAKE_ID so the loader updates instead of duplicating, one transaction, fully-qualified statements, never raises. - supabase_client: fetch_mcp_intake_row (the intake row with its id + created_at); mcp_result_…877abd8
24 days ago
-
fix(brand): the browser's default link colour is not a brand colour (ISS-30)
boone 2026-10-22, after a Walmart demo. walmart.com leaves its nav links unstyled, so the capture read them as #0000EE and the brand read took that as a series colour. Measured on Chromium 149: an unstyled link computes to #0000EE on a light page and #9E9EFF on a page that opts into a dark colour scheme; a visited link reports the unvisited colour to getComputedStyle, so visited purple never reaches a capture. Those two colours are now skipped in TEXT readings only (button text, h1, h2, nav link). A background or a brand custom property in that exact blue was set by the site and still counts. Verified on live captures: walmart.com now reads #0053E2 / #004F9A / #001E60 with the nav link dropped; industry.traveloregon.com is unchanged (its styled nav colour is still read). Tests: 4 new in tests/test_brand_capture.py, the Walmart fixture taken from the real capture; brand suites 136 pass; full suite 1911 pass, the same 3 pre-existing failures as the test tip. Not pushed. Co-Authored-B…a060847 -
docs(settings): dpSettingsDB agent spec; sprint entry wording after the rebase
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>0bcf580 -
feat(mcp): dpSettingsDB tools — an SE's settings read and changed in Supabase through the MCP server
boone (2026-10-22): a new AgentSpot agent, dpSettingsDB, shows and changes a Sales Engineer's DemoPrep settings in the database, with dropdown-constrained choices. AgentSpot has no database connector (60 application connectors, Snowflake the only database) and its Apps write back only to Jira, Slack and Salesforce, so the DemoPrep MCP server, already connected to Supabase and already registered in AgentSpot, is the agent's path to the settings. - demoprep_app/settings/catalog.py: the editable fields with kind, default and (for dropdowns) the exact options; keys are SETTINGS_SCHEMA storage keys, so a write is live in the App tab and in builds with nothing else in between; the dead fields (temperature, batch size, per-user snowflake, ...) are absent - demoprep_app/settings/store.py: validated, all-or-nothing read/write on user_settings (category 'defaults'); unknown keys and off-list values are refused naming the options; stale stored values are reported as problems - mcp_serv…cc072ec -
docs(settings): AgentSpot DP Settings agent document; the sender is that agent, not Agent Q
Paste-ready agent instructions, the settings document, the one tool it calls today (config_check), the phase-2 get_settings / save_settings scope, examples and connector setup. Wording in the inventory, flag registry, example document and sprint entry corrected: any caller of build_demo_from_brief passes the document; Agent Q is not the owner of it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>57c47f4 -
docs(sprint): settings document on test-mcp 0d02061, verified
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>fc3bfa4 -
fix(pipeline): read pytest's quiet summary; a token without Checks reads as no checks
Both seen on the first deploy through the pipeline (2026-10-22, test-mcp = 3108c38): - `pytest -q` ends with a bare "3 failed, 2049 passed in 40s" line; the run recorded "pytest exit 1" because the parser wanted the ===== border. - The sync's first pass answered 403 on the pull request list (the token was created without the Pull requests permission: boone's to fix). A token with Pull requests but not Checks would still have failed the whole sync on the check-runs call; that now reads as "none" for that PR. Docs: the exact token permissions in docs/development_process.md; the sprint doc records the first deploy and what is left. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>4637f97 -
docs: the TSE site is DP Web — agent is the DP Web Editor; tool names stay, docstrings teach the term
boone (2026-10-22): everything is branded DP; the site formerly called the portal / TSE site is DP Web. The MCP tool identifiers (build_portal, describe_portal, update_portal, list_portals) are live on production and in use, so they stay as code; the agent instructions and tool docstrings say that a portal is a DP Web site. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>9b0fd1e -
feat(liveboard): describe_liveboard / update_liveboard / undo_liveboard_change — remove or rename tiles by TML
The Portal Editor agent correctly refused to remove a KPI because the KPI lives in the liveboard, not the site. boone: "we can just edit the TML" — which every build already does. These tools do exactly that, as the board's owner, with the rules boone set on 2026-10-22: a title that matches two tiles is a conflict the agent asks about, never a guess; a row that lost a tile is re-packed; v1 is remove and rename, move comes later. - demoprep_app/liveboards/edit.py: pure functions over the TML dict. describe (tiles by tab, kind, group), find by id or exact title, remove via the existing remove_visualizations_from_liveboard_tml plus re-pack (survivors shift left and widen when the row divides the 12-wide grid; emptied rows close up; a group that lost its last tile loses its frame, which the helper left dangling), rename. Every reference is resolved before anything is applied, so a partly wrong request leaves the board as it was. - mcp_server.py: the three tools. Target from a …23c6a10
25 days ago
-
docs(research): ThoughtSpot MCP landscape Oct 2026 — SpotterCode, SpotterViz dashboard tools (verified live), model builder, Spotter Analyst APIs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>b98196e -
docs: portal update tools are on prod via the 20 Oct release; the existing connector exposes them
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>3c321f0
24 days ago
-
merge: fix/pipeline-folds-space-commits-and-prod-poller-skip into develop (bootstrap, by hand)
The second and last hand merge: the sync that lets the pickup run take pull requests from the queue is not on the test Space until this deploy. Brings the Space's own commits (settings document, Data Adjuster LLM fix) into develop, the pipeline fixes, and the prod poller skip. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>3108c38 -
fix(pipeline): the lock file lives beside the worktree, not inside it
git refuses to create a worktree in a directory that already holds anything, and the first real run had created the directory for its own lock file. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>f1d74d1 -
merge: test Space tip 0d02061 (settings document, Data Adjuster LLM fix) into the pipeline fix branch
Both were pushed straight to the test Space by other sessions after develop was reset to b918bd8, so develop lacked them and the pickup run's Space push would have been refused. The run refused to merge them itself because both sides had appended to sprint_2026_04.md; resolved here by keeping both sections and one trailer. Once this branch is in develop, the Space push is a fast-forward. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>545c9c5 -
fix(pipeline): fold in commits pushed straight to the Space; a token without repos never stops the server
Two things the first real pickup run met on 2026-10-22: - The test Space was ahead of develop by two commits another session had pushed to it directly (settings document, Data Adjuster LLM fix). The push would have been refused as a non-fast-forward. The run now merges the Space's own commits into the integration branch first (--no-ff, a conflict is reported, not forced), so nothing on the Space is lost and the push is a fast-forward. Recorded on the deployment note. - GITHUB_TOKEN landed on prod too, with no TRACKER_REPOS. The server used to raise at startup on that half config, which would have taken prod down at the next promotion. The poller is now skipped with a loud log line; the sync runs only on the Space that has TRACKER_REPOS (test). Also: the job and the CLI load the nearest .env when run from a worktree; the launchd job runs the pipeline worktree's own copy of the script, so it always runs the integration branch whatever boone's checkout is on; the third p…02321f4 -
feat(mcp): settings document on build_demo_from_brief replaces per-run Supabase settings reads
A separate TSE app owns an SE's DemoPrep settings and Agent Q hands them to the build as one JSON document (schema 1.0, the `settings` keyword argument). When present, the build takes model, data size, column naming style, object prefix, liveboard name, tag, share-with and geo scope from it and reads nothing from the SE's Supabase settings: the controller skips its startup read and the three mid-run re-reads are guarded. Explicit owner_email / ts_url still win; a blank ts_url falls back to the document's URL, then its environment label through the TS_ENV table. A bad document is refused before a slot is taken, naming the key. - demoprep_app/settings/payload.py: the one parser and apply step (the data-size presets live here now) - chat_interface: ChatDemoInterface(settings_from_supabase=...), _settings_source - run record carries settings_source and settings_schema_version - docs: settings inventory with decisions and the phase-2 Supabase scope, the example document, the brief for …0d02061 -
Merge pull request #4 from boone10/feature/tracker
Unverified signatureTeam tracker and pickup pipeline: tasks beside pull requests, approval policy, four-times-a-day deploy to test4229a7b -
fix(adjuster): route Data Adjuster LLM parsing through MultiLLMResearcher
SmartDataAdjuster._call_llm() went through prompt_logger.logged_completion(), which imported litellm — a package that is not in requirements.txt — so every call raised ImportError. match_request_to_viz() swallowed it, meaning the LLM parser never ran and only the regex parser ever decided. - smart_data_adjuster.py: build the shared MultiLLMResearcher client via the app's provider mapping (injectable `researcher=`), log every call on the session PromptLogger, raise DataAdjusterParseError on malformed replies, and let transport errors propagate. The swallowed-exception path is gone. - prompt_logger.py: delete the dead litellm wrapper logged_completion (the adjuster was its only caller) and fix the stale module docstring. - tests/test_smart_data_adjuster_llm.py: 13 unit tests with the LLM stubbed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>aae5297 -
docs(sprint): develop reset to the test tip, RLS off applied, dry run clean; the bootstrap step
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>1677729 -
chore(tracker): RLS off for now with the policies ready beside it; files-to-run rule in CLAUDE.md
Supabase enabled row-level security on the new tracker tables; with no policies the app's key read nothing and every write was refused (found when boone ran schema.sql on 2026-10-22: five people rows visible to the service key, none to the app's). boone: off for now, sprint item to do it properly. - schema.sql: disables RLS on the six tables ("OFF for now"), pointing at rls_policies.sql. - rls_policies.sql: the fix, ready to apply — RLS on, explicit anon policies per table (read everything; write tasks, notes, pull requests, runs, deployments; people only from the SQL editor; no deletes), the view as security_invoker. Sprint item logged. - .gitignore: every tracker .sql is source. - CLAUDE.md: "Handing boone a file to run or paste — ALWAYS": file pane, file card, ~/Downloads, code block when short; never a bare or worktree path. - sprint: schema run recorded; the RLS item; the develop push not yet done. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>26377ab -
chore(pipeline): the pickup run, worker and tracker CLI are executable
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>81be5c5 -
Merge remote-tracking branch 'hf-mcp-test/main' into feature/tracker
122171d -
feat(pipeline): the pickup run, the agent worker, and the process they implement
Every change on a branch off develop, a PR in, approved on arrival for Mike and Jack and by one of them for everyone else, picked up four times a day and pushed to the test Space. Everything that writes to GitHub or Hugging Face runs on boone's Mac under his own credentials; the server only reads. - scripts/pipeline_run.py: queue -> merges in its own pipeline/ worktree (detached, --no-ff, a conflict skips with a note) -> unit suite with the known-failures allowlist -> push origin -> three-minute idle gate on the Space -> push hf-mcp-test -> ping confirms the sha -> deployments row and "on test-mcp" notes. Never prod, never a red suite, never a non-fast- forward. --dry-run reports against the real tracker. - scripts/launchd/com.demoprep.pipeline.plist: 7:30 / 11:30 / 15:30 / 19:30 local time. scripts/pipeline_known_failures.txt: the pre-existing failures. - scripts/agent_worker.sh + agent_worker_prompt.md + tracker_cli.py: the agent's turn — top task, agent/t<id>-<slug> o…62f3e9a -
feat(tracker): approval policy, pipeline state, findings intake — the server half of the pickup pipeline
Checkpoint on the way to the four-times-a-day pickup run. The MCP server still only READS GitHub; everything that writes (merge, push origin, push test) will run on boone's Mac under his own credentials. - schema.sql: tracker_people gains is_agent / can_approve / auto_merge (Mike and Jack approve; the agent is a person row with no GitHub login; Jack's login jackrayner-ts); tasks gain `source`; pull_requests gain base_branch, head_sha, agent_opened, approval, approved_by/at, checks, mergeable, merge_sha, merged_by_pipeline; new pipeline_runs and deployments tables; task_board gains source, pr_approval, owner_is_agent. - github_sync.py: the approval policy (auto for an approver's own PR unless the branch starts with agent/; approved / changes_requested from an approver's latest review; a tracker approval survives a sync; a merged PR keeps its history); per-PR mergeable_state and check-run summary; t<id> accepted in any branch segment (fix/t42-..., agent/t42-...). - sto…9cc42ea
25 days ago
-
fix(data): a 0-1 rate declared "float" is reconciled to pct, so it keeps 4dp
The column fix (c0c880f) was only half of it. Re-running the baseline on that build showed rates STILL at scale 2 with 3-19 distinct values, because the measures were never fmt="pct" in the first place — the LLM declared them "float", and fmt drives precision at BOTH later points: _format_value: fmt in ("currency","float") -> round(value, 2) _sql_type: anything not pct -> NUMBER(16,2) So the value was already truncated before any column saw it. Teaching the column alone could never have fixed it. harden() now reconciles the declaration against the bound registry: a measure whose inferred bound is a 0-1 "rate" or "score" is set fmt="pct", and both layers follow from that one decision. The fix is recorded in `fixes` so the build says what it changed and why, rather than silently rewriting a declaration. Only mis-declared RATES move. An int stays int, a pct stays pct, and currency is untouched — cents remain the right precision for money. tests/test_rate_colu…b918bd8 -
fix(portal): the chained build pre-fills the SE's email on the sign-in forms
Release note 6 — "SE email pre-filled on both login forms" — is disproven on the release tip. Measured across all five 2026-10-21 test builds: the owner's address appears ZERO times in every portal bundle. patch_login_default_user() is correct and does patch both Login.tsx and SignInDialog.tsx. Nothing was calling it on the path that matters. login_default_user is set in _builder_kwargs(), which serves the STANDALONE build_portal tool. The CHAINED build inside build_demo_from_brief — the path Agent Q actually calls — builds its own kwargs at _run_build() and passed as_user but not login_default_user. So a portal built from a brief has always shipped with an empty username box and the SE types their address by hand, which is the exact thing that patch exists to prevent. One argument covers both forms, because the patch handles both files. Verified by the bundles: before this, mike.boone@thoughtspot.com occurs 0 times in R1-R5. A build after it must show it at least once. Co-Authore…3975270 -
fix(data): a 0-1 rate column holds the 4 decimals the engine gave it
Release note 10 — "No more metrics showing the same number across an attribute (Larry)" — is disproven by the baseline build on the release tip. STA_10210722_3XL_sch, no flags, production default: OEE_RATE NUMBER(16,2) 10,000 rows, THREE distinct values 0.94 -> 5112 rows, 0.95 -> 3132, 0.96 -> 1756 spread by FACILITY 0.74%, PRODUCT_LINE 0.50%, SUPPLIER 0.71%, SHIFT 0.72% Every bar on every breakout sits on ~0.945. That is Larry's complaint, and it is NOT the ISS-12 ratio-cancellation bug: the generator produced good values and the COLUMN threw them away. engine.py contradicted itself. _format_value() already keeps 4 decimals for a rate on a 0-1 scale: if fmt == "pct": return round(value, 4 if pct_max <= 1.0 else 2) _sql_type() handed every non-int measure NUMBER(16,2), so Snowflake rounded 0.9447 to 0.94 on insert. The tighter the band the worse it got — SCRAP_RATE (0.01-0.07) held 7 distinct values across 10,000 rows. _sql_type now uses the SAME r…c0c880f -
docs(sprint): ISS-30 branding on prod as d6ebaa0 (2026-10-21)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>59e1421 -
feat(deploy): index attribute values at both the table and the model layer
Every generated column has carried index_type DONT_INDEX since the first commit — at the table layer and again at the model layer, five hard-coded sites, no recorded reason (the Aug-10 import slowness was the unscoped connection scanning ~507 databases, not indexing). The effect on a demo: a prospect typing a venue, rep or tier into search gets "Invalid value token", and Spotter has no values to match a word against. Measured on CON_10201951_KZ8: flipping the tables to DEFAULT let "One Liberty Plaza" resolve on the table within a minute, while the model kept rejecting it until its own columns were flipped too. The two layers have to agree, so the answer lives in one place — index_type_for() — and every site asks it: attribute values are indexed; keys, ids and codes are join plumbing nobody types; dates go through the date parser; measure values are never indexed. Tests pin the rule through the real TML builders at both layers and fail if a hard-coded index type ever comes back. Co-Au…bd91a6a -
Merge release/test-homepage-2026-10-21 into test line
5073d4e -
Merge feature/check-homepage-tool into test line
d69ea53 -
feat(mcp): check_homepage tool — can DemoPrep get the prospect's home page by itself?
Agent Q calls it before build_demo_from_brief. It runs the build's own home-page step (sources.capture_home_page, no screenshot): the live page with capture.py's rules, then only when blocked the Internet Archive copy with the same lookup and blank-page check. No generation step. Returns ok / source (live | wayback (YYYY-MM-DD) | none) / needs_screenshot / reason / message_for_se; needs_screenshot only when neither works, and a bad URL is ok:false with a reason. Never raises. - async tool, work in a thread: does not block the event loop, takes no build slot nor the clone runner's Chromium slots (own limit of 2) - bounded at 45 s; an overrun says so and asks for a screenshot - a usable capture is kept 30 min and a build of the same URL reuses a copy of it (recall_capture) instead of loading the site again - no fake UA, stealth, proxies or anti-bot services: a block is reported - docs/agent_q_flags.md: tools table + change log Real checks (local Chromium): firework.com live 13.7 s,…0cf1463 -
docs: Agent Q home page — current (live → Wayback → template) and v2 (check_homepage first, ask for a screenshot)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>f01cb89 -
Merge feature/home-page-screenshot-wayback into test line
25ab291 -
feat(portal): home page from the SE's screenshot, Internet Archive fallback
On 2026-10-21 all three real builds on test (shoppersdrugmart.ca, nationsbenefits.com, stanleyblackanddecker.com) hit an HTTP 403 bot wall and every portal opened on the template login. New input `homepage_screenshot` (https image URL or base64 data URI; png/jpeg/webp, <=10 MB) on build_demo_from_brief, build_portal and update_portal, declared as a real tool parameter and documented for Agent Q. login_clone/sources.py::capture_home_page picks the picture of the page: 1. the screenshot: sliced into 1440x900 screens, colours read from pixels (feed the generator's brand block and ISS-30), no logo 2. the live site, as before 3. only when that is blocked: the Internet Archive (public availability API, else the public CDX index), `if_` form so no toolbar; the newest copy, then one older copy of real size 4. the template login, with every reason: "site blocked (HTTP 403), no screenshot sent, no archived copy" home_page.source = screenshot | live | wayback (YYYY-M…17c9782