Spaces:
Running
Running
Commit History
13 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
20 days ago
-
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
21 days ago
-
Merge fix/dead-headline-measures into release/test-fixes-2026-10-21
a1d66aa -
fix(data): headline measures come out with data; a dead headline warns and ships
Three SE builds aborted 2026-10-20/21 at the post-load gate with "Headline measure(s) X are among them". Each has its own generator root cause: 1. Shoppers Drug Mart ffb4c1200490 — NET_RX_REVENUE_CAD all zero. In the loaded schema DRUG_INGREDIENT_COST_CAD == DISPENSING_FEE_CAD on all 10,000 rows. Rule 3a of the author prompt ties a cost to its price with share_of; the LLM wrote the cost as share_of the FEE with a band of 1.8..6.5 (a drug costs several times its fee — reproduced by an in-memory replay of the real author on this brief). The engine clamps a share fraction to 1.0, so the part became a copy of its whole and NET = GROSS - N*COST = 0, silently. harden() now normalises declared share_of bands: a multiple (bottom >= 1, top <= 10) drops the share_of and samples the measure at the whole's typical magnitude x the band; a percentage (top in (10, 100]) is read as /100; a band straddling 1 is capped at 1. All recorded in metadata['hardening']. 2. Shopp…fc0fa83 -
fix(slack): one 'Started' root per Agent Q build
_run_build posts the run's Started root (with the run id), then the controller's run_deployment_streaming called begin_run_thread() and posted a second top-level Started, orphaning the first: two messages per build, and replies/reactions only on the second. The MCP root now records owner='mcp' and the controller skips its own root when that thread is open. App-tab runs are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>492ae90
22 days ago
-
Merge fix/slack-no-warnings into release/test-2026-10-20
1785706 -
Merge release/rc-2026-10-14 into release/test-2026-10-20
# Conflicts: # liveboard_creator.py # mcp_server.py # sprint_2026_04.md # supabase_client.py # tests/test_iss22_login_precheck.py # tests/test_payload_capture_is_complete.py # tests/test_payload_reaches_the_database.py # thoughtspot_deployer.py # thoughtspot_errors.pyb868f6b -
fix(slack): stop posting build warnings; post login-precheck refusals
boone 2026-10-20: "remove all the verbiage about the warnings" from the deployment channel, and say when a build is refused at login. Warnings/findings no longer reach Slack: - surface_findings writes demo_findings only; its report keeps the same keys and always returns slack = (False, "warnings are not posted to Slack") (SLACK_SKIPPED) - skipped by design, not a failure. - slack_notifier: notify_build_findings / format_build_findings and their roll-up/priority helpers removed, plus the unused "Warning"-status notify_data_fallback_event. - Findings are still stored in demo_findings, on the run's result (warnings, findings, findings_persisted) and on its mcp_result row. - A blueprint abort's error used to reach Slack only inside the findings post; it now goes as a plain "Failed" post carrying just the error. Other Failed posts are unchanged (an error is not a warning). Login precheck refusals (ISS-22) now post one short message - who, which cluster, why - from a daemon t…4a3b140 -
Merge PR #3 (Jack Rayner, feat(slack): thread per-run notifications, react on completi) into test line
fccf1a8 -
fix(findings): Wave 1 of the findings triage — stop the noise, show the real failures
Three days of Slack (2026-10-12..15, 47 SE builds): ~600 of 662 warnings were `bound_not_inferable`, noise that buried the pile-ups, the mirrored column and the weak insights under "… and N more". Four deploy failures were unprovisioned ThoughtSpot users reported only as "authentication failed". Plan: dev_notes/PLAN_findings_triage_2026_10_15.md, section 4, Wave 1. A1 the post-load gate reads the blueprint's fmt / signed / kind per measure: DatasetColumn carries them, quality_gate.measure_formats collects them, chat_interface threads them (the MCP path runs the same controller), so an int count or a currency amount is non-negative, not "unclassified" A2 infer_bound returns a `signed` MeasureBound — unbounded by design, no gap, hard=False — for NET_/MARGIN/VARIANCE/FLOW names, declared-signed measures and difference formulas, instead of the same None as "no class matched"; every consumer checks .unbounded / .hard and does nothing A3 quality.findings.dedupe: a…c6a9e6a -
feat(slack): thread per-run notifications, react on completion, @-mention on failure
Reduce channel noise: for each run the first ("Started") deployment post is the thread root and every later update replies under it, so the channel shows one line per run. When the run finishes, the root gets a reaction — :white_check_mark: on success, :x: on failure — and on failure the people in SLACK_ALERT_USER_IDS are @-mentioned in the thread. - slack_notifier.py: thread-local run anchor; send_slack_message(root=) threads replies and returns the message ts; finish_run(ok) reacts once + mentions; begin_run_thread / reset_run_thread. No anchor (root never posted, or Slack unconfigured) = plain top-level messages, exactly as before. - chat_interface.py (Gradio deploy flow): "Started" posts as root; the terminal Complete/Failed events call finish_run. - mcp_server.py (_run_build): posts its own root + finish_run(result status), since the MCP path does not go through the Gradio root. - tests/test_slack_threading.py: root vs threaded, check/x once, failure mention, and the …96cdb31
28 days ago
-
Merge feature/custom-mcp-demo-flag into release/rc-2026-10-14
# Conflicts: # chat_interface.py # mcp_server.py # tests/test_payload_capture_is_complete.py # tests/test_payload_reaches_the_database.pybaae590 -
Merge feature/brand-theme-flag into release/rc-2026-10-14
# Conflicts: # mcp_server.py # tests/test_payload_capture_is_complete.py # tests/test_payload_reaches_the_database.pyffcd799 -
feat(mcp): opt-in custom MCP demo section (GitHub issues -> Spotter) via custom_mcp_demo
Ports Rob's App-tab "Custom MCP Demo — GitHub Issues → Spotter" Demo Pack section (worktree custom-mcp-spotter-demo-125da8, uncommitted, based on 4d97c9f) onto the MCP line by hand, and puts it behind a flag Agent Q sends. - build_demo_from_brief(custom_mcp_demo: bool | str = False), documented for Agent Q, threaded through _run_build like salesforce_opportunity_id. Read with the portal's yes/no reader: omitted/false/blank = off; an unreadable value stays off and adds a warning. Raw value on the intake row (via _call_payload), resolved bool in the session_logs run payload. - Controller gate ChatDemoInterface.custom_mcp_demo_enabled defaults False; only _run_build sets it, so the App/Chat tabs never generate the section and the Demo Pack is byte-for-byte unchanged when off (no LLM call). - On: the section is appended to the Demo Pack and recorded on deployment_completion; the build result, status() recent_builds and the mcp_result demo_history row carry it as custom_mcp…2094a0a -
feat(mcp): ISS-19 — build the demo in the prospect's brand colours
build_demo_from_brief gains apply_brand_theme (default OFF) and brand_theme ({"primary", "secondary", "palette"}). With the flag off — omitted, false, blank — the build is exactly today's: no extra work, identical TML, identical portal options (pinned by tests/test_brand_theme.py, incl. a byte-identical offline run of the real enhance_mcp_liveboard). On: demoprep_app/liveboards/brand_theme.py validates the colours at the MCP edge (bad input -> default palette + warnings, never a failed build), hands primary/accent to the chained portal through portal_options (pre-flighted against the portal's own derivation), and runs as the LAST colour pass of enhance_mcp_liveboard: native chart series/palettes, geo + heatmap gradients, KPI series, Muze tiles whose colours live in their own code (single-series bars drawn in the primary, bullet/dual-axis/pareto/bar-tick/KPI card, cell heatmap ramp) and note-tile accents. Muze charts coloured by a real second category use ThoughtSpot's host palette and…282a174 -
feat(mcp): schema_style — simple star (one fact) by default (ISS-16)
SEs asked that the agent build simple star schemas by default: left to choose, the blueprint author picked 2-3 facts for most briefs, and a tile grouping one fact's measure by an attribute only another fact reaches repeats the grand total on every row (Convene, run fbd4d0cc94f9). build_demo_from_brief takes schema_style: "simple" (default) = exactly one fact + 4-8 dimensions each joined to it; "complex" = the previous 1-3 facts. Omitted, empty or null resolves to simple (boone's rule); "complex" only by name; any other value refuses the call before a build slot is taken. The style picks prompt rule 2 (complex = the old rule verbatim) and adds schema_style_findings() to the authoring repair loop: a second fact is critical and never trimmed, so a simple build that keeps one fails loudly with a message naming schema_style='complex'; dimension count outside 4-8 warns; an unjoined dimension warns and is joined after the rounds. schema_style is required by build_demo/author_blueprint; App/…8dd2e0f
-
fix(data): a per-unit rate is not a part/whole ratio
Every derived `A / B` was read as "A is part of B", in two places: blueprint.harden() step 2 made A a share_of B, and the post-load gate checked A <= B and clamped A to B. For a per-unit rate that rewrites the numerator: Symbotic run 437d6c984e2c generated cases as a fraction of kWh (CASES_PER_KWH 0.78-1.00, 604 rows at exactly 1.00), the gate then "clamped" cases to kWh and recorded repair_failed. Since 7f3dd00 (Aug 26), 29 of 46 profiled per-unit columns shipped capped at 1.00 (e.g. AVG_SELLING_PRICE max $1.00, AVG_ORDER_VALUE 0.78-1.00). - measure_bounds.part_whole_pairs(): the one answer to "is A part of B", used by harden() and the gate. Evidence: a declared share_of (a part in the denominator vetoes), else the ratio's own bound is a proportion (A/B <= 1 is A <= B). No naming rule in quality_gate.py. - The gate receives the blueprint's share_of: DatasetColumn.share_of -> measure_shares(bundle) -> run_measure_quality_gate(shares=). - Same-unit ratios lift the quantity-unit…cbacde6
-
fix(gates): loud demo_findings persistence marker, fatal-set regression test, ISS-11 status
Brief items 3-4 (dev_notes/agent_brief_iss11_dimension_floor_2026_09_22.md): - log_demo_findings returns a receipt (attempted/written/persisted/reason/error) and prints one [FINDINGS-PERSIST] line either way; never a quiet zero. The review tables exist but RLS rejects the anon key's INSERT (42501) until an insert policy or writer key exists. - surface_findings writes demo_findings FIRST, then posts to Slack with "Recorded in demo_findings: yes / NO — <error>". - chat_interface stamps findings_persisted / findings_persist_error on the completion record and session_logs; mcp_server carries both in the tool result, _recent_builds and the demo_history mcp_result row. - _run_identity_for / _collect_run_findings are module-level so bare controller stubs work. - tests: fatal-set regression (every rule blueprint.py can emit, asserted against FATAL_RULES / WARNING_RULES, plus a source scan so a new rule cannot land without a policy line); persistence receipt, RLS failure path…8f26f6d -
Merge branch 'claude/release-prep-triage-cd6725' into claude/build-abort-policy-686f65
e6d566c -
feat(gates): warn and ship — severity on the rule, proportional data gate, geo/liveboard fallbacks, findings to Slack + demo_findings
Reviewer handoff 2026-09-22: 13 of 35 failed/partial runs since Aug 13 died on problems that were not unbuildable. A build now dies only when the demo is genuinely impossible to produce; everything else warns, is recorded as a Finding, and ships. - F DemoBlueprint.findings() / directive_findings() emit Findings with the severity decided by the rule; build_demo reads blocking() and raises BlueprintAborted (carries the records). _STRUCTURAL_KEYWORDS, _COSMETIC_MARKERS, _structural_problems deleted. - A dimension floor 3, warn at 2, abort at 0-1 (Symbotic SHIFT, Bronco PERIOD_TYPE) - B placeholder names never abort; _placeholder_values needs >=2 stamped members in one dimension (Spendflo DEPARTMENT=Product is clean) - C QUESTION_GENERATION_ATTEMPTS=3, then deploy_all ships model + schema with a no_liveboard warning finding, liveboard_creation_path='none', MCP 'partial' (boone confirmed 09-22) - D strip geo_config and re-import when ThoughtSpot rejects t…2f5718d
-
slack: deployment posts name who ran the demo; Model and TSE site links alongside Liveboard
boone 2026-09-21: every 'DemoPrep deployment' post now carries 'Run by' (display name + email from the users table, email fallback), 'Model' as a bare URL (was a bare GUID) and, once the portal is built, a 'Portal ready' follow-up with the TSE site URL — bare URLs, exactly as the Liveboard line has always worked, so they auto-link and stay copyable. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>b405f05 -
feat(mcp): stamp Space identity + code SHA on every run record
On 2026-09-14 "which Space served this run, on which commit" had to be inferred after the fact from mcp_intake result-key shapes and liveboard chart types. Nothing in demo_history or session_logs recorded it. New demoprep_app/deployment_identity.py: - space_id / space_host from the HF container env (SPACE_ID / SPACE_HOST), blank outside a Space. - code = 12-char SHA resolved once per process from the first source that answers: .build_sha (stamped by the Dockerfile at image build), git rev-parse HEAD (local/stdio), or the Hub API runtime.sha for SPACE_ID. code_source records which one answered. Best-effort throughout: never fails startup or a build. Stamped under the same four keys on the mcp_intake row (_call_payload, identity first so the argument-capture contract stays whole), the mcp_result row (log_mcp_result) and the session_logs 'run started' payload (_snapshot_run_payload — App runs get it too). ping and config_check return the same keys; the MCP ready banner prints …a41c582
-
fix(llm): the deploy step builds with the run's model, not the SE's saved App-tab default
_run_thoughtspot_deployment re-read the owner's raw default_llm from Supabase and preferred it over self.settings['model'] — the value the MCP server (or the App dropdown) had just set. So every MCP build ran whatever the SE last saved in the App tab: 20 users on claude-sonnet-4-6 (no longer a UI choice), 12 on a gpt-5.5 the Space cannot run (rescued only by a068df7), and the run payload said Opus while the stages ran something else. self.settings['model'] is already validated at load and set per run on both paths; use it. MCP builds now run the default (Opus 5) unless the SE picked a current UI model. Tests: tests/test_run_model_precedence.py (5). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>6d4730c
-
Measure bounds, and gates that warn instead of stopping
Cherry-pick of 1c3c868 onto ee5ebbc (what hf-mcp/main and hf-mcp-test/main both run). TEST tier only. Two modules had been built independently as the single source of truth and collided: measure_names.py (on prod) owns "is this column a rate?", and the incoming measure_bounds.py had grown its own name-token inference. The incoming quality_gate.py additionally carried private copies of is_rate_column / is_flag_column / rate_scale_bound — the fourth drift of exactly the defect measure_names exists to prevent. Resolved by delegation rather than by picking a conflict side: measure_names — every judgement made from a NAME. Gained the broader is_proportion_column (a strict SUPERSET of is_rate_column, which is consulted first so the narrow prod answer always wins), rate_scale_for_name (built on bounded_range_for_column, so the suffix -> scale table has one home), is_score_column, is_signed_nam…0d10bbf
-
WIP: liveboard render loop + Opus 5 enablement + multi-measure color fix
- tests/liveboard_render_check.py: PDF-text render check (TS server render is ground truth) - tests/liveboard_loop.py / liveboard_report.py: liveboard-only burn-in against real SE models, local catalog + REPORT.md - main_research: join Anthropic text blocks (Claude 5 emits a leading thinking block -> content[0].text was None) - llm_config: default claude-opus-5, Sonnet 5 fallback, 4.6 removed - golden_layout: never bind slice-with-color on charts with >=2 measures ("Cannot display the chart") - liveboard_creator: guard None response in question-gen debug print Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>bb4a763
-
fix(liveboard): KPI tiles average rates instead of summing them
madeline.goodman's Visma board displayed Net Revenue Retention as 3,312, Churn Rate as 116 and Rule of 40 as 165,111 — three of four KPIs summing a rate across 3,333 rows. larry.silverstein's Yodeck board had the same defect. Root cause was FOUR layers disagreeing, and three private naming heuristics that had drifted apart — which is why the defect survived earlier fixes. ONE SOURCE OF TRUTH: new demoprep_app/dataset/measure_names.py owns measure classification. quality_gate.py's local _BOUNDED_SUFFIXES / bounded_range_for_column / is_rate_column / is_flag_column are deleted and re-exported from it; a test asserts identity so a re-drift fails CI. thoughtspot_deployer, liveboard_creator and chat_interface all import the same module. Rule order matters and each rule exists because a real column name broke a simpler version: true rate/ratio/pct suffix beats money words; compound PRICE names (SPOT_RATE_PER_MILE, AVG_RATE_THIS_CARRIER_LANE) stay SUM and are never clamped; whole-word matc…d0d292d
-
fix(data): stop the generator silently writing zeros; gate repairs instead of vetoing
Five real SEs could not get a demo. Root cause was not the quality gate but what it was gating: the formula evaluator turned every error into the number 0.0 and wrote it to all rows. ISSUE A — silent-zero formula evaluation - New demoprep_app/dataset/formula.py: one definition of the measure-formula language (parse/validate/evaluate/compile-to-SQL) shared by blueprint, engine, validator and gate. FormulaEvaluationError names measure + formula + token. - The evaluator RAISES instead of returning 0.0. Whitelisted function support (ABS, ROUND, MIN, MAX, LEAST, GREATEST, COALESCE, IFNULL) — previously ANY function call hit a bare `except Exception: return 0.0` and produced a column of zeros. Unknown identifiers raise instead of resolving to 0. Divide-by-zero still yields 0 but records a deduplicated warning surfaced in build.warnings. - Removed the adjacent silent zero: row[m.name] = values.get(m.name, 0.0). - Formulas are now validated BEFORE Snowflake/ThoughtSpot work: every…7f3dd00
-
feat(logging): capture full run payload in session_logs on every run
Every run (App tab + Chat tab) now logs its complete payload to Supabase session_logs in meta.payload of the 'run started' events: - raw GO form inputs (controller._run_payload set in defined_go) - resolved company/use case/vertical/line/function/context - secret-redacted settings snapshot Attached in _create_run_loggers() (guaranteed even when a run dies before research) and again in run_research_streaming() once fully resolved. New sanitize_payload() in session_logger.py redacts key/secret/password/ token/credential/auth values and truncates >2000-char strings; 5 tests in tests/test_run_payload_logging.py. Chat-tab runs reset stale App-tab _run_source/_run_payload at initialization. Query guide in dev_notes/logging_channels.md (local docs, not tracked). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>04fcaca -
Merge remote-tracking branch 'hf-test/main' into develop
# Conflicts: # sprint_2026_04.md6bb7908 -
Merge branch 'claude/youthful-lederberg-e31760' into develop
# Conflicts: # chat_interface.pydc44f67 -
feat: post-load data-quality gate for zero/null measure columns
Profile every MEASURE column after each Snowflake load (both dataset-first and legacy paths) via INFORMATION_SCHEMA + per-table aggregates. Fail the run loudly, naming the columns, when any measure is entirely zero/null (recurring Yodeck/Triumph zero-measure defect). Mostly-zero and empty-table cases surface as warnings in the completion panel and session_logs meta. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>fa79ccd
-
perf(deploy): scope TS connection to demo DB + monthly-rotating database (250s -> <1s table imports)
Root cause of the ~250s-per-call table TML imports (found 2026-08-10, corrects the July "server-side, not reducible" conclusion): ThoughtSpot table import scans all external metadata VISIBLE TO THE CONNECTION. Our connections had no database property, so every import scanned ~507 Snowflake DBs. Measured on the same instance with the same trivial table: unscoped 246s, scoped to DEMOBUILD (1,003 schemas of demo debris) 33s, scoped to a fresh tiny DB 0.7s. Prod secloud showed identical ~250s unscoped — never instance-specific. - thoughtspot_deployer: create_connection_tml/create_connection_with_reconcile now REQUIRE a database and emit a `database` property in the connection TML. - snowflake_auth: get_demo_database() -> <SNOWFLAKE_DATABASE>_<YYYY_MM> (memoized per process); ensure_demo_database() creates it on connect. Session params + cdw_connector + env injection (supabase_client) all use the rotated DB so write and deploy paths agree. Admin setting stays the base name. - chat_…21ee86d
-
merge: unify MCP (async TML import + concurrency + mcp_server) into integration
- keep app README frontmatter (gradio) on trunk; MCP docker frontmatter stays on hf-mcp-deploy - build_demo.py: blueprint LLM cap/timeout reconciled to 16384 / 300s (superset of both sides) - adds mcp_server.py, tests/e2e_mcp.py, MCP deps; async-only TML import pathc3e3f8b
-
feat(mcp): real-time status via deploy progress bridge + return DDL early
- Progress bridge: _run_thoughtspot_deployment gains an optional on_progress hook chained onto its internal progress_callback; the MCP passes one that updates _set_progress, so status.current_build.detail/phase track LIVE (importing tables -> creating model -> creating liveboard) instead of freezing between the generator's sparse yields. [async] lines map to an "importing tables" phase. App/test callers pass no on_progress (default None) — unaffected. - DDL returned early: _run_build stashes ddl_text in _current_build the moment run_ddl_creation returns (~5 min in) and includes it in last_build, so a caller polling status() gets the schema well before the ~15-min TS deploy finishes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>cbd0efa
-
fix: honor TS Environment dropdown on every GO/message, not just first
The App GO handler (defined_go) and chat send_message only applied the selected TS environment when a NEW controller was created (if controller is None). On a reused session — e.g. the e2e runs all 8 demos on one login — the controller already exists, so the env pick was silently dropped and the deploy fell back to the default (default_ts_env='secloud - primary' / se-cloud). That's why switching the dropdown to 'sebe - se' had no effect and every test still hit se-cloud. Move the env application out of the controller-creation branch so the selected environment (URL + trusted-auth key) is applied on every GO/message. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>612db3c
-
Wire single blueprint pipeline; fix engine formula fidelity + insight direction
Replace the keyword-router generation path with one build_demo() pipeline: research -> LLM-authored DemoBlueprint -> deterministic BlueprintEngine -> validation -> derived DDL. No mode flag, no fallback. Engine fixes: - Compute derived measures from formatted (stored) base values so rows satisfy their formulas under the validator's re-check (no formula errors). - Never clamp derived values; a negative margin/inventory stays faithful. - Sign-aware sensitivity analysis maps an insight on a derived measure to the base that moves the metric the promised direction (ratios no longer invert; products scale by magnitude, not magnitude squared). Adds preflight + blueprint + McKesson regression tests and migration docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>3993fe3
-
Log deployed code version
mike boone8cea964 -
Improve backup liveboard path logging
mike boone5f0f576
-
Honor explicit custom dataset contracts
mike boonea6d4bca
-
Merge remote-tracking branch 'origin/develop' into develop
mike boone8997cc3 -
test: harden e2e quality diagnostics
mike boone8e5d114 -
Merge remote-tracking branch 'hf-test/main' into develop
mike boone# Conflicts: # thoughtspot_deployer.pydb6ab4f -
fix: harden dataset and ThoughtSpot deployment recovery
mike booneb210533 -
fix: wait for delayed ThoughtSpot table imports
mike boone7f49e13
-
fix: recover ThoughtSpot imports after gateway timeouts
mike boonea61ad4f
-
fix: add semantic-safe dataset preflight
mike boone6723ca6 -
fix: enforce demo-safe data and liveboard layout
mike boonec3f1d91 -
fix: improve run diagnostics and ts recovery
mike boonee758f65
-
fix: clarify dataset-first progress and import json scope
mike boone94f1813
-
Reapply "fix: temporarily force sonnet model failover"
mike booneThis reverts commit 3d955ee6f0ab66f2b42ccf8d65faa3646db9bcab.fa01ae7