Docs

Changelog

RSS

All notable changes to the Amdahl Platform API are recorded here. The format follows Keep a Changelog: each entry groups its changes under the sections that apply (Breaking, Added, Changed, Deprecated, Removed, Fixed, Security) and omits the ones it does not use. Breaking comes first and flags anything that needs action on your side. Dates are the day the change landed on the stable path.

Last updated 2026-07-09

Filter
Added
  • data_access_rule:// read resource (data_access_rule://list, data_access_rule://<id>; REST GET /data-access-rules). Look up the verified data-access rules the platform maintains for the warehouse — field substitutions, surface-grain caveats, and aggregation patterns — so an agent queries your data correctly. Filter with ?surface=, ?kind=, or ?signature=.
  • New guided walkthrough prompt (system/guide_me) for MCP clients. Ask "what can this do?" or "guide me" and Amdahl runs a friendly, jargon-free, numbered-menu interview — it offers plain-English goals (meeting prep, customer voice, deal lookup, proof, research, dashboards, recurring reports), you pick a number, and it does the work and answers in plain language. Built for non-technical users who would rather pick from a menu than know which tool to call.
  • Default GTM living documents now schedule themselves for your workspace. Once a workspace has synced go-to-market data, Amdahl automatically schedules a starter bundle of recurring living documents — GTM health, pipeline health, voice-of-customer, win/loss, and a weekly priority briefing, plus deal-qualification, account-tier, and ICP reports once a CRM is connected — so useful reports start arriving with no setup. Workspaces that have already configured their own workflows are left untouched.
Changed
  • Win / Loss and GTM Health Report accuracy on high-volume workspaces. The won-vs-lost MEDDPICC differentiators, the score-calibration curve, and the per-competitor win rates in these living documents are now computed over your _entire_ closed-deal history in a single pass, instead of a recent sample. Workspaces that close thousands of deals per window — where these figures were previously computed on a truncated slice — now get complete, unbiased numbers.
  • New queryable fields on the `data` tool. deal_qualification now exposes realized_is_won / realized_is_closed (a company's realized deal outcome), and competitor_mentions now exposes competitor_class (rival vs. own-product / benchmark / model-vendor) plus the account's realized deal outcome. You can now compute score calibration and per-rival win rates in a single query, without bridging across tables, and the competitor win-rate read is backtestable with as_of.
  • data.query now accepts Common Table Expressions (WITH … AS (…)) and subqueries (in FROM and WHERE). Previously these were rejected; your workspace's tenant scoping is applied to every part of the query, so nested reads stay scoped automatically.
  • MCP-connected assistants now translate Amdahl's internal terms into plain business language when talking to you — "conversations" instead of "interactions", "topics" instead of "clusters", "a workflow" instead of "a blueprint" — and no longer surface SQL, tool names, or field names unless you ask how something works. The server instructions carry a built-in glossary so this holds across every client.
  • data.query now also accepts set-operations (UNION / UNION ALL / INTERSECT / EXCEPT). Previously these were rejected; each branch of the query is scoped to your workspace independently and the row limit applies to the combined result, so you can union or intersect results in a single query.
  • data.explore with sample values is now much faster on a cold call: the per-column distinct-value lookups collapse into a single scan of your data instead of one query per column (the first explore of a session no longer stalls for tens of seconds).
  • data.cluster_detail now accepts a durable lineage_id (surfaced on every data.cluster_search result) as an alternative to cluster_id. A theme's cluster_id changes each time topics are recomputed, so a saved handle could go stale; the lineage_id is stable across recomputes and is resolved server-side to the theme's current id, so a drill-in handle you saved earlier keeps working.
Fixed
  • The grounding discipline behind every living GTM doc now encodes the deal-outcome surface rules directly: deal counts / revenue / win rate come from your CRM deal records, conversation-corpus outcome rates are labeled as such and never conflated with them, won+lost can exceed closed (an account can be both), numbers are stated exactly (no rounding), currency is formatted, and quotes stay in blockquotes. Applies across all ~18 living-doc generators, not just VoC and ICP.
  • The GTM Diagnostic's "where deals are lost" stage-leak analysis now works. The query behind it was silently rejected before it ever ran, so on every workspace the report saw an empty result and fell back to reporting cycle-time only (reading the blank as "no stage history"). It now computes the stage each lost deal died in, so the diagnostic can point at where in the funnel deals actually leak.
  • agents.run_blueprint now resolves a tenant blueprint by its identity.slug, not only by its UUID. Running a blueprint you authored by its slug used to return not_found; it now resolves the same way every other blueprint surface does.
  • Win / Loss Report no longer claims a 90-day window it never applied. The win-loss-report workflow declared a lookback_days input but none of its queries filtered on it, so a run headlined _all-time_ closed-deal totals under a "90-Day Close Period" title — the figures were real, the scope was not. The report now states its true basis, all closed deals to date, opens with a line giving the closed won/lost counts and noting that the MEDDPICC differentiators and per-rival win rates are computed over the closed-and-scored subset, and is barred from describing itself as covering any rolling window. The lookback_days input is removed: only the deals cut has a close date at all — the won/lost outcome reaches the qualification and competitor surfaces as a flag with no date — so windowing part of the report would have put a 90-day headline next to all-time win rates. Passing the old input is ignored rather than rejected, so existing schedules keep running. The document still refreshes monthly; its version history is the time series.
  • Champion & EB Voice Digest now actually covers the window it reports. The workflow declared a lookback_days input but none of its queries filtered on it, so the digest quoted stakeholders from your entire conversation history under a heading that implied a recent period. It now genuinely reads the last 60 days of champion and economic-buyer utterances, opens with a coverage line stating how many utterances and accounts fall inside the window out of your all-time totals, and says so plainly when nobody spoke in the window instead of padding the digest. The objection themes come from the theme index, which has no time filter, so they remain all-time and are now labeled as such. The lookback_days input is removed — the window is fixed at 60 days; passing the old input is ignored rather than rejected, so existing schedules keep running. Fork the workflow to change the window.
  • GTM Health Report no longer implies a lookback period it never applied. The workflow declared a lookback_days input (default 180) that no query filtered or weighted by. The report now states its true basis — all of your conversation and CRM data to date — and is barred from describing itself, or any finding, as covering a rolling window, a quarter, or "recent" deals. Its cuts genuinely cannot be windowed: the stage-transition analysis would silently mis-identify where deals die, the account funnel view would lose every open deal, and the score-calibration and competitor win-rate cuts carry a won/lost flag with no close date. Windowing only the rest would have put a windowed headline beside all-time win rates. The lookback_days input is removed; passing it is ignored rather than rejected. The report still refreshes on a cadence, and its version history is the time series.
  • The Champion & EB Voice Digest now carries its window in the title. The digest reads the last 60 days, but because it edits the prior version in place rather than rewriting it, a refresh could leave the old heading standing and mention the window only in a subtitle beneath it. The 60-day window is now written into the document's own title on every refresh.
  • The GTM Health Report's score header is back on the first line of the document. When the report's title was pinned, two instructions ended up competing for the first line, and the machine-readable score block that powers the Home card score got pushed below the heading. The card kept working, but the document no longer matched its own contract. The score block now reliably leads the document, with the title immediately beneath it.
Security
  • MCP OAuth: the scopes an OAuth-connected app receives are now clamped to the standard customer-agent capability set at authorization time. A requested scope beyond that ceiling (for example a wildcard *:*) is dropped rather than granted, so an OAuth token can never carry more access than the OAuth flow is meant to issue. Apps that request the advertised scopes are unaffected.
Added
  • Pages catalog: LineChart accepts yMin + yMax to pin the y-axis range, so a tight series can fit its scale to the data (no forced zero baseline) and show its variance.
  • Pages catalog: new Tabs component (labelled panels the viewer switches between — each tab carries an inline catalog subtree) and Carousel component (rotate sibling charts one slide at a time), plus QuoteList.expandable + QuoteList.detailFields for a per-quote read-in-place detail dialog with richer attribution.
  • Workspace README — a one-read orientation map of your workspace. Read workspace_readme://current over MCP (or GET /workspace/readme over REST) to get the workspace's pages, knowledge documents, agent workflows, and callable operation namespaces as name-plus-summary rows, together with a rendered markdown digest. Assembled live on every read, so it is never stale; sections your key lacks scope for are omitted with a reason instead of failing the call.
  • Salesloft connector. Connect a Salesloft workspace with an API key to sync emails, calls, conversations, transcripts, and meetings into your workspace.
  • Every Pages chart now accepts a height preset (sm | md | lg) and an ordered colors token list (chart-1..chart-5, positive, negative, neutral) so agents can size charts and paint series/slices deliberately — tokens resolve to theme variables, so white or raw hex are unrepresentable. RadarChart additionally accepts max to pin the radial scale (e.g. max: 5 for a /5 rubric fills the polygon), and FunnelChart no longer overruns its card border.
Changed
  • Living documents generated from an uploaded doc (knowledge_base.make_living) now author a deterministic, grounded refresh workflow: each regenerated version computes its figures directly from your data and verifies every number, so a living doc no longer states a figure that isn't backed by the underlying data.
  • Backtest-generated knowledge-base versions are now stamped with the as-of date they reflect. A cumulative backtest sweep of a living document produces a properly dated version history, and each slice builds on the prior one (knowledge_base.upload defaults version_as_of to the run's backtest cut; an explicit value still wins, and live runs are unchanged).
  • Competitive Divergence Map workflow (v2) now tracks divergence over time. Every run captures a structured divergence snapshot — counts by kind (internal-only / market-only / magnitude / polarity), themes marked new / persisting / resolved vs the prior run, and render health — in three places: the workflow run's outputs (blueprint_run://<id>), a machine-readable header on the living doc (so the knowledge-base version history is a parseable series), and an accumulating "Divergence over time" chart on an auto-upserted dashboard page. The run also factors in more data: per-rival market research (bounded by the new max_rivals input), your positioning docs from the knowledge base, and the Industry sweep corpus — and the category market read is force-refreshed so a scheduled run never records a cached brief as a fresh snapshot.
  • The Account Tier Intelligence and ICP Signal Report living documents are now generated by the deterministic step-executor — every figure (close-likelihood scores, engagement momentum, champion strength, win rates by vertical) is computed from your data in SQL/transform cells and number-verified, so the document can no longer state a value that isn't backed by the underlying data. Account tiering (Expand / Nurture / Watch / Triage) is computed deterministically from the real signals rather than narrated by the model.
  • Fixed a blueprint-runner bug where a workflow's transform step could not read a workflow input via the canonical $inputs.X reference, which could cause a defaulted threshold to be treated as unset.
  • The Deal Qualification Report living document is now generated by the deterministic step-executor: every figure (coverage-band distribution, per-dimension MEDDPICC/SPICED coverage percentages, binding constraints) is a verified data cell, the thinnest-coverage deals are named with real company names (bridged from the interactions surface), and dimension coverage is reported as a clear percentage of scored companies rather than an ambiguous count.
  • The Win / Loss Report living document is now generated by the deterministic step-executor. The two cross-surface analyses it previously asked the model to compute by hand — the won-vs-lost MEDDPICC coverage spread and the per-competitor win rate — are now pre-computed as verified transform cells, so the report states real, grounded win/loss differentiators and win rates (each gated to ≥8 accounts for reliability) instead of derived figures.
  • The Pipeline Health Report living document is now generated by the deterministic step-executor: the open-pipeline total is a verified totals query (rather than the model summing stage rows in its head), the at-risk / long-shot deals are named with real company names, and every stage figure is a grounded cell the number gate verifies.
  • The Win / Loss Report now handles a thin closed-won sample honestly: when there are too few scored closed deals to compute reliable MEDDPICC win/loss differentiators, the report says so and focuses on the qualitative loss themes instead of reporting shaky percentages, and it no longer derives win-rate or share percentages from the raw deal counts.
  • Living-doc workflows now share a canonical data-surfaces map (where each GTM data surface lives, its grain, purpose, scale, and join key) plus the query patterns that keep a computed figure correct under the query row cap — so a generated or hand-authored workflow aggregates in SQL over the full population instead of silently truncating a per-row query.
  • Added a truncation guard to the deterministic workflow executor: a data.query whose result exceeds its LIMIT (detected by a peek) is flagged, so a workflow can no longer state a real-but-wrong number computed over a silently-truncated sample (deliberate top-N queries opt in via allow_truncation).
  • The Account Tier, Win / Loss, Deal Qualification, and Pipeline Health living documents now compute their cross-surface figures over the FULL population instead of a silently-truncated sample: metrics that need every company (win/loss MEDDPICC differentiators, account tiering, named thin/at-risk deals) use an id-list bridge that aggregates in SQL over the exact set, so — for example — a tenant's win/loss report now reflects all of its won accounts rather than an arbitrary slice.
  • The living-doc query truncation guard is now enforced (not just observed): a workflow step whose query returns more rows than its limit fails the run instead of silently producing a document over a truncated sample. When a generated living doc hits this, the self-tuning generator now recognizes it as a truncation failure and revises the recipe to aggregate over the full data (via SQL aggregation or a bounded lookup) — so a generated doc self-heals to correct figures rather than shipping partial ones.
Fixed
  • Turning a knowledge base document into a living document now reliably produces a runnable refresh workflow. The generated recipe is constrained to the tools and step types the living-doc engine actually executes, and a malformed draft returns a clear validation error instead of failing the request.
  • Living GTM docs (Voice-of-Customer, ICP Signal) now report won/closed counts, win rate, and revenue from your CRM deal records, cleanly separated from the conversation-corpus outcome view — no more conflicting "won accounts" figures between sections. Currency is dollar-formatted, quoted customer figures are no longer mis-flagged, and the reports no longer state industry/segment splits that aren't in the data.
  • Living GTM docs now state every figure exactly as computed — the narrative no longer rounds or approximates a number (e.g. "~5,600" for 5,904), so the prose always matches the underlying data.
Fixed
  • The divergence map now renders on the `search` action too. A prior fix pinned the synthesis model path for the enrichment briefs but missed the plain search action, so search could still route its internal-vs-market synthesis to a slower back-end that timed out and returned an empty divergence map. All external-search synthesis paths now use the same fast, dedicated model, so the fused internal-vs-market view renders consistently on search as well as the company/person/topic enrichments.
Added
  • knowledge_base.promote and knowledge_base.dismiss. Approve a proposed living-doc version (promote it to the current, cited version) or dismiss it, from the console or REST.
  • Living-doc subscribers. Read and replace the members/roles notified when a document has a new version to review (GET .../knowledge-base/:id/subscribers, PATCH .../knowledge_base/documents/:id/subscribers).
  • Saved views. Personal named filter presets for the Living Knowledge list: knowledge_base.list_saved_views / create_saved_view / update_saved_view / delete_saved_view.
  • Documents now carry an owner and an audience role, and surface whether a proposed version is awaiting review.
  • Two new `data.query` surfaces: `competitor_mentions` and `deal_score_weights`. competitor_mentions (one row per company + competitor) lets you build an internal win-rate-by-competitor read straight from your conversation corpus — no external search — bridging to deal outcomes on company_id. deal_score_weights exposes the learned deal-score model: which signals predict close-likelihood for your tenant (a factor→weight map) and how well it performs (holdout vs baseline AUC). Both are discoverable via data://schema and honor data-scope — competitor_mentions is company-scoped like the deal-grain surfaces, and deal_score_weights is a business-level admin/GTM read.
  • POST /agent-blueprints/:id/activate — activate or deactivate a workspace workflow (body { enabled?: boolean }, default true; creates the activation row when enabling one that was never activated). Powers the Living Knowledge "Activate" affordance on a living document whose producing workflow is off.
  • Living Knowledge documents now carry source_run_status (the producing workflow's most-recent run status) and workflow_active (whether that workflow is enabled), so the list can badge "Last run failed" and filter "Runs failing".
  • Two new Page components: `CopyButton` and `Dialog`. CopyButton copies a value (a literal or a bound cell, e.g. a recommended message) straight to the clipboard on click — the one-click "grab and paste" affordance. Dialog adds a trigger button that opens a modal rendering its child components, so a page can tuck supporting detail (quotes, a table, a chart) behind a click-in instead of showing everything at once. Both are client-side only — they run in the browser and invoke no server operation.
  • Industry: dropped the market-themes and divergence-map reads (industry://themes / industry://divergence). Added a raw Industry Signals read (industry.list_signals / industry_signal://list, REST GET /industry/signals) over the collected corpus - the source documents the sweep landed, filterable by domain, source, angle, sweep, and collected/published date, with a free-text search over title and body, and paginated. industry.refresh and the industry_run:// run-history reads are unchanged.
  • Sync a single knowledge-base document to Notion on demand, and open it in Notion. If your workspace has Notion Knowledge Sync connected, you can now push one document to Notion immediately — instead of waiting for the automatic sync or the hourly reconcile — and read its live mirror state: whether it has a Notion page yet, a direct open-in-Notion link, and whether the mirror is behind the current version. New endpoints POST /notion-sync/documents/:document_group_id/sync and GET /notion-sync/documents/:document_group_id (plus the notion_sync://documents/<document_group_id> read resource for MCP).
  • New `industry.get_signal` operation — read one collected market-signal document in full. The industry signals list now returns a short preview (snippet) per document to keep the feed fast; fetch a single document's complete text on demand by id via industry.get_signal (industry_signal://<id> on MCP, GET /industry/signals/:id on REST), so the detail view shows the whole article instead of a truncated blurb.
  • Two new `data.query` surfaces: `deal_stage_history` and `ref_deal_stages`. Query your CRM deal stage-transition history and the stage dimension directly, so you can answer where deals actually die (the stage a lost deal sat in right before it closed) and how long they spend in each stage — questions the current-stage deals snapshot can't. deal_stage_history is one row per stage change (deal_id, the raw CRM deal_stage id, changed_at); ref_deal_stages maps each raw stage id to its human label, funnel position, and won/lost/open class. Read data://schema for the columns and example queries.
  • New starter workflow: Market Intelligence Digest. A weekly living document built from your Industry signals — the market-signal documents the platform sweeps from the web, news, and SEC filings. It surveys the collected feed, drills into the documents most relevant to your business (and named competitors) in full, and writes an executive read + what's-moving + competitor-watch digest that auto-promotes each run. Fork it from the starter workflows and enable its weekly schedule (Monday 08:00), or run it on demand. See the new Industry signals guide (Using Amdahl, under "See what it found") for the full workflow, the API, and how agents read the feed.
  • Remove a single document from Notion — and keep it removed. If your workspace has Notion Knowledge Sync connected, you can now remove one knowledge-base document from Notion without turning off the whole sync: it trashes that document's Notion page and mutes the document so no automatic sync, hourly reconcile, or backfill re-mirrors it (the fix for a _living_ document that would otherwise come back on its next update). Re-syncing the document brings it back — Remove and Sync are a clean toggle. New endpoint POST /notion-sync/documents/:document_group_id/unsync.
Changed
  • Faster external search. Market/topic research (search + enrich_topic) now spends less time ranking and synthesizing results: the relevance-ranking pass is capped to the strongest candidates per source, the source fan-out closes out sooner, and the summary step works from a tighter set of citations — trimming response time while keeping the same broad source coverage.
  • External search responds faster. The relevance-ranking step in market/topic research (search + enrich_topic) now works from a leaner pool of top candidates per source, cutting the time spent scoring results. Source coverage is unchanged — every source still contributes — so you get the same breadth of citations, sooner.
  • External search responses now include per-stage timing. A search result carries an optional _timing breakdown (query enrichment, source fan-out, ranking, relevance gate, and synthesis — with synthesis further split into clustering and each summary pane). It's additive and safe to ignore, but lets you see exactly where a call spends its time when diagnosing latency.
  • Every Amdahl workflow now works goal-first and recursively. All shipped workflows — plus any you fork from them, and any generated from an uploaded document via "make it living" — now share one investigation method: anchor on the goal, tie claims to a measurable outcome vs a baseline, and treat a finding as a lead (drill into what causes it and how to act on it) rather than filling a fixed template. The discipline is centralized in one place, so it keeps improving across every workflow at once.
  • GTM Health Report is now outcome-first and adaptive. The standing GTM health report was rebuilt to reverse-engineer the questions that matter for _your_ business and test each against a real outcome — win rate, cycle velocity, deal size — instead of leaning on conversation-theme summaries. It now computes the funnel and where it leaks by stage, the drivers that actually predict a win (stakeholder breadth, champion presence, and more), an internal competitive read, and message performance — all from your own calls, emails, and CRM, with named accounts and verbatim quotes behind every finding. Competitive position and messaging no longer come back "not computable" and there is no external dependency to fail on; every dimension is derived from your corpus.
  • Living Knowledge provenance. A living document's source_workflow now carries the producing workflow's name and blueprint_id, so the "Fed by <workflow>" label can name and deep-link the workflow instead of showing a generic "an Amdahl workflow" label.
  • Living Knowledge ownership. Backfilled the accountable owner on documents created before the owner field existed (using the workflow's activating user, else the uploader), so the Owner field is populated rather than empty.
  • GTM Health Report now reports stage velocity (median time-in-stage, won vs lost, and the stage where deals stall) and win rate _by competitor_ (grouped by rival type, with any win-rate inversion called out) — not just a rival mention list. It no longer emits "TBD" for time-in-stage; when a workspace lacks stage-transition history it says so and falls back to the overall won-vs-lost cycle spread.
  • Pipeline Health Report now flags stalled stages using the median age of open deals per stage.
  • GTM Health Report now reliably includes stage velocity (time-in-stage, won vs lost) and win rate by competitor — these are now required outputs of the diagnostic rather than optional, so they appear on every run where the data supports them (with an honest coverage-gate fallback when it doesn't).
  • Living-doc workflows authored by the "make it living" generator are now data-field-aware: the generator knows the tenant's high-value CRM signals (champion / economic-buyer flags, close-likelihood + binding-constraint scores, per-stage dwell time, and competitor win-rate) and composes queries that use them — so a generated living doc produces the sharp cuts, not a generic theme summary.
  • GTM Health Report now always includes a stage-velocity cut (median time-in-stage, won vs lost, and the stage where deals stall) and a win-rate-by-competitor table — computed as deterministic steps so they appear on every run, not just when the agent happens to author them.
  • Living documents that are analytical diagnostics now fully regenerate their numbers each run instead of minimal-editing the prior version, so newly added analysis sections take effect immediately (a full_regen_each_run blueprint setting).
  • Several Living GTM Doc reports now read high-value CRM signals they previously ignored, so they produce sharper analysis:
  • Win/Loss Report — won-deal MEDDPICC differentiators (which qualification dimensions separate wins from losses) and win rate by named competitor.
  • Deal Qualification Report — the most systematically undercovered MEDDPICC dimensions, computed directly rather than guessed.
  • Account Tier Intelligence — tiers now weigh stakeholder quality (champion / economic-buyer presence, champion score) and 30-day engagement momentum, not just raw activity volume.
  • Weekly GTM Digest — flags stalled pipeline stages by median deal age.
  • Competitive Divergence Map — names the actual recurring rivals (not just a competition-present count).
  • ICP Signal Report — leads with the firmographics of _won_ accounts (who actually buys) and flags ICP drift vs the overall funnel.
  • Persona Voice Deep-Dive — the role mix now surfaces champion / economic-buyer counts per role level.
  • The natural-language SQL helper (data.ask) learned two new analysis plays: per-stage dwell/velocity (from the interactions temporal-stage surface) and win-rate-by-competitor (bridging competitor mentions to deal outcomes).
  • Living documents now self-heal. If a scheduled or on-demand living-doc run is cut short before it writes its document (e.g. a transient rate limit on a large workspace), the platform now automatically re-runs it (bounded) instead of silently leaving the document stale — and a retried run is nudged to work more economically so it finishes within budget.
  • External search is faster and its divergence map now always renders. The result-ranking step switched from an LLM scoring pass to embedding similarity, cutting a large chunk of latency off every search / enrich_topic call. That freed budget goes to the fusion synthesis: the internal-vs-market divergence map (the tenant-only signal a plain web search can't produce) previously timed out and came back empty on most calls — it now completes and ships populated.
  • Content Calendar links straight to your drafts. The Content Calendar workflow's page now opens the full drafts from your Knowledge Base — the drafts living document stays the single source of truth, and a "Read the drafts" panel on the page links out to it, so the schedule and the full copy never drift apart. The knowledge_base.upload API now also returns a console_url deep link to the uploaded document, so an automation can point back at exactly what it just saved.
  • External search's divergence map now reliably renders (and the call stays safely under the timeout). Follow-up to the previous rerank change: the internal-vs-market divergence map — the tenant-only signal a plain web search can't produce — was still coming back empty because the synthesis panes generated more text than they had time to finish. Their output budgets were trimmed so each pane completes, and the overall time budget was tightened so a call can no longer run up against the 60-second ceiling and return nothing.
  • Living GTM documents now tie themes to outcomes, not just volume. Five of the standing GTM living documents got sharper by grounding what they surface in won-vs-lost deal outcomes instead of raw frequency:
  • VoC Cluster Report now leads with the themes that show up in _won_ deals and ranks by win-correlation (with a loss-correlated risk section), instead of ranking by how often a theme comes up.
  • GTM Proof & ROI Library now leads with competitive-displacement wins — accounts you won _and_ where a rival was named — as the strongest reusable proof.
  • Champion & EB Voice Digest now includes a dedicated objections & pushback section mined from what senior stakeholders actually push back on.
  • Cross-Persona Divergence Brief now calls out which persona layers, when engaged, predict wins — so multi-voice content leads with the framing that closes.
  • GTM Health Report now quantifies the top jobs-to-be-done as coverage on won vs lost deals ("pain quantified on 41% of won deals vs 6% of lost"), instead of a free-text ranking. Each keeps the same honesty discipline — a rate is only stated once a bucket has enough closed deals; below that it reports raw counts and marks the signal thin.
  • Read your Content Calendar drafts right on the page. The Content Calendar workflow's page now bakes each piece's full draft into the calendar itself: click any day to open a dialog and read that day's pieces in full (multiple per day supported), with a link to open the canonical, versioned copy in your Knowledge Base. The separate "Read the drafts" button is gone — the content reads in place. The Calendar and Board page components (authored via the pages tool) gained two optional props for this: contentField (the row column holding a piece's full markdown body) and docUrlField (a per-row deep link to the living doc); when set, each item becomes clickable and opens the read-in-place dialog.
  • The GTM Priority Briefing now ranks by grounded confidence, not a guess. When the weekly briefing scores each priority by impact × confidence × urgency ÷ effort, the _confidence_ term is now set from real signals: each source document's own stated confidence (the GTM Health Report's score header, per-finding high/medium/low, and "thin/directional/not measured" honesty markers), whether two or more documents independently corroborate the insight, and the knowledge-base retrieval match score. A loud-but-thin signal can no longer outrank a quiet-but-corroborated one, and every priority shows why its confidence was set the way it was.
Fixed
  • Issues inbox filtering. GET /console/issues?category=... now accepts the app-internal issue categories (e.g. proposed_kb_version) alongside the pipeline quality-event categories, so filtering the inbox by one returns results instead of a 400 invalid_category. This unblocks the Living Knowledge "needs review" count.
  • Living Knowledge workflow activation now reflects execution reality. The workflow_active field on documents and the POST /agent-blueprints/:id/activate toggle read/write blueprint_schedules.enabled — the cron scheduler's source of truth — instead of the workspace_workflows curation badge. Previously the flag under-reported which workflows actually run, and "Activate" moved a badge without starting or stopping any scheduled run.
  • The Content Calendar page's "Read the drafts" link now points at your real Knowledge Base doc. The deep link back to the full drafts is attached on the same path the scheduled workflow actually runs through, so the page links to your living document instead of a guessed URL. The knowledge_base tool (both the API operation and the MCP coarse tool) now returns a console_url for the uploaded document, so any automation can link back to what it just saved.
  • External search's fused brief (market summary, customer voice, and the internal-vs-market divergence map) now actually renders. The synthesis step was opening streaming connections that never completed in the production environment, so every search / enrich_topic call fell back to an empty brief. The synthesis calls were switched to a non-streaming request that completes reliably, so the market summary, your customer-voice pane, and the divergence map come back populated.
  • External search's divergence map renders more reliably. Follow-up to the non-streaming synthesis fix: the fusion panes now complete, but under concurrent load one pane occasionally ran a hair past its time budget, so the full brief (market summary + customer voice + divergence map) came back complete only intermittently. Their time budgets were given a small amount of headroom and their prompts trimmed slightly so each pane starts and finishes sooner — making the complete brief, including the internal-vs-market divergence map, render consistently.
  • External search's divergence map now renders reliably on every call. The final fix in the fusion-synthesis chain: the internal-vs-market divergence map (the tenant-only signal a plain web search can't produce) was completing only intermittently because all three synthesis panes generated at once and competed for throughput. The panes now run two-at-a-time — the divergence map gets a dedicated slot while the two summary panes share the other — so the divergence map finishes and comes back populated consistently.
  • Documents, pages, and artifacts produced by a workflow run are now attributed to the person who triggered the run. Previously anything a headless/scheduled workflow authored was credited to the workspace owner (the identity the runner acts under), so a report someone else kicked off showed the owner as its author. Outputs now carry the actual triggering user as their creator, while owner attribution is preserved when a run has no human trigger.
  • The Content Calendar workflow can now be forked into your workspace. Forking it previously failed validation because its tool allowlist named an internal coarse-tool action (context.entries_list) instead of the canonical operation id (context_entry.list); the entry is corrected, so POST /agent-blueprints/fork (and the blueprints fork action) now succeed. Behaviour of existing runs is unchanged. A new starter-forkability test pins every shipped starter's tool allowlist against the operation registry so no starter can ship unforkable again.
  • The market-intelligence divergence map now renders reliably on every search. External search and the company/person/topic enrichment briefs synthesize their internal-vs-market "divergence map" — the view that fuses your own CRM and call corpus against the public web — on a fixed, dedicated model path. Previously that synthesis could be silently routed to a slower back-end that couldn't answer within the call's time budget, so the divergence map came back empty. It now runs on the fast path every time, so the fused view (the part generic web search can't produce) shows up consistently.
  • The "open the living doc" link on a Knowledge Base upload response now resolves to the document instead of 404ing. The console_url attached to a knowledge_base.upload result (on both the operation and the MCP coarse tool) was built from the document's document_group_id, but the workspace KB detail route resolves a document id — so the link opened "Document not found". It now uses the freshly-written version's document id, so a living-doc → page workflow (e.g. the Content Calendar) links straight to the current version of its full drafts.
  • Five more workflow starters are now forkable. Following the content-calendar fix, the plan-and-draft-window, GTM diagnostic, positioning scorecard, Substack thought-leader newsletter, and content-calendar-routine starters each listed a tool in their allowlist that was not a registered operation (e.g. web_search, data.explore, and internal run-lifecycle controls), so forking them into your workspace failed the allowlist validator. Their allowlists now name only canonical operations, and a guard test (which was previously a no-op) now actually checks every starter, so each one can be forked.
  • "Your workflows" now lists every workflow that's actually running. A scheduled workflow only appeared under "Your workflows" if it had been switched on through the in-app activation toggle. Workflows put on a schedule another way — for example a recurring living-document report — kept running on their cron but were shown under "Library" as if they were still just an un-adopted template. The Workflows page now decides what's active directly from the schedules that fire, so anything running for your workspace shows up under "Your workflows".
Added
  • `data.query` on the theme clusters surface now supports `as_of` backtests. A SQL read like SELECT label, velocity FROM clusters … with an as_of date now resolves the cluster generation that was live on that date (via the warehouse clusters_as_of table-function) instead of being refused — so a blueprint that reads themes with raw SQL backtests cleanly. The append-only theme_lineage history surface still requires as_of reads to go through data.cluster_search / data.cluster_detail.
  • Living GTM Docs — 18 workflows + matching pages. Eighteen new Amdahl-shipped workflows generate versioned, human-promoted living documents in your knowledge base on a cadence — VoC cluster report, champion/EB voice digest, pipeline health, deal qualification, win/loss, ICP signal, account tiering, positioning scorecard, persona voice deep-dives, cross-persona divergence, competitive divergence map, ecosystem map, topic research briefs, GACCS content briefs, AEO health, the weekly GTM digest, the GTM proof & ROI library, and the meta GTM priority briefing. Each ships with a live page template (browse via page_template://list / author with pages.create_from_template) so the same intelligence is available as a live console dashboard, not just a narrative.
  • Pages can read clusters and the knowledge base. Page declared queries now support cluster_search and kb_search sources (in addition to sql and artifacts), so a page can surface conversation themes and reference-library matches live.
Fixed
  • External search now draws on every source it advertises, and returns faster. Market/topic research (search + enrich_topic) now fans out across the full set of registered sources — including the developer and review platforms (GitHub, Hacker News, dev.to, Medium, Stack Overflow, G2, Capterra, TrustRadius, Product Hunt) alongside web, Substack, and YouTube — so those citations actually show up in results. The same change removes a bottleneck in the relevance step that was roughly doubling response time on these calls.
  • Theme-based Living GTM Docs now backtest correctly. The Voice-of-Customer, Weekly GTM Digest, and GTM Priority Briefing living documents read your conversation themes through the point-in-time theme index, so running one as an as-of backtest reconstructs the themes that were live on that date instead of failing on the theme step. Their scheduled (live) runs are unchanged.
Added
  • New industry intelligence surface. A daily sweep gathers what the wider market is discussing (web, news, and SEC filings) and maps it against what your own customers raise on calls. Read it via the new industry.get_divergence (the four-axis market-vs-customer divergence map) and industry.list_themes (the clustered market themes) operations, or trigger a fresh sweep on demand with industry.refresh.
  • Substack and YouTube are now searched in external research. Founder newsletters, talks, and demos are strong go-to-market signal, so external_search (the search and enrich_topic actions) now covers Substack and YouTube alongside web, news, LinkedIn, and Crunchbase.
  • More platforms in topic and market search. Topic and market searches now also pull from Medium, Hacker News, dev.to, GitHub, Stack Overflow, G2, Capterra, TrustRadius, and Product Hunt (alongside the existing Substack and YouTube sources), giving broader coverage of practitioner writing, developer discussion, and buyer-intent review sites. New platforms are added through a single registry, so the source set will keep growing without changes to how you search.
  • agent_blueprint.list entries now include forked_from_amdahl — true when a workflow was forked from an Amdahl starter (via "Use template"), so you can tell an Amdahl-derived workflow from one you built from scratch.
  • Trigger and watch an industry sweep over MCP. The new industry tool's refresh action kicks off a "What's Going On In The Industry" sweep on demand instead of waiting for the daily run, and returns a run_id. Poll the new industry_run://list + industry_run://<id> reads to watch the run to completion and read its per-stage step log; read industry://themes / industry://divergence for the clustered market themes and the market-vs-customer divergence map.
Changed
  • External search is faster and no longer times out on long calls. Broad web and news results now run on the faster search backend (when configured), removing the slow source that previously gated every fan-out. The per-call deadline_ms is also clamped so the full pipeline (search + synthesis) stays under the tool-call ceiling — a large deadline_ms no longer causes the whole call to time out and return nothing; slow sources just surface as incomplete instead.
  • External search synthesis is faster and less likely to time out. The market/internal synthesis step now works over a tighter, top-ranked set of sources, so the brief comes back sooner — particularly on broad topics where the wider source mix previously pushed synthesis past its budget.
Removed
  • Reddit and X/Twitter removed from external research. Neither has a serviceable data provider, so external_search no longer searches them; the enrich_person action no longer attempts to resolve an X handle.
Fixed
  • External search no longer drops sources under load. When many searches run at once (e.g. competitor/market research alongside the industry sweep), requests are now smoothly rate-limited and automatically retried instead of failing, so a burst costs a little extra latency rather than missing results.
  • Embedded Pages now load on any site. A live Page embed (the <iframe> snippet from a Page's Embed button) fetches its data cross-origin, which was being blocked unless the embed was hosted on an Amdahl domain. The public page-embed API now permits cross-origin requests from any origin, so a pasted embed renders wherever you put it.
  • Fixed the embed signing-secret screen. Creating a signing secret showed a blank value and the secrets list showed an undefined prefix, due to a mismatch between the API responses and the console. Both now return the correct shape, so the one-time secret and the prefix display correctly.
  • `data.query` MCP calls now capture the question that triggered them. Previously, a data query (raw SQL) call could silently drop the verbatim user message even when your client supplied it, because that action logs through its own path rather than the shared one. The resources, social, pages, notifications, industry, and blueprints tools now also accept the same optional context so a client populating it gets full coverage across every tool, not just data / context / knowledge_base / external_search.
Added
  • Run and schedule Workflows directly from MCP. The blueprints coarse tool gains a run action (a one-shot headless run) alongside create_schedule for recurring cron runs, gated by the new blueprints:execute scope on the customer-agent key bundle. A workspace MCP key can now launch and schedule its own Workflows without any broader delegation grant.
  • Author a Page from a template over MCP. The pages coarse tool gains a create_from_template action that materializes a vetted, Amdahl-shipped page template by template_slug; browse the available templates via the page_template://list resource first.
  • Read drafted content pieces back over MCP. A new content_piece:// read scheme (content_piece://list + content_piece://<id>, gated by artifacts:read) surfaces the content pieces a content-calendar Workflow drafted, so an agent can review a run's output without leaving MCP.
  • agent_blueprint.list now returns is_active and source on every entry, so you can tell which workflows are active in a workspace and whether each is an Amdahl-managed default (source: "amdahl") or your own (source: "custom").
  • New workspaces start with the GTM Health Report workflow active by default.
Fixed
  • External search now returns social results again. Reddit, X/Twitter, LinkedIn, and Crunchbase sources are served via web search, so external_search (search and the enrich_* actions) surfaces social signal instead of coming back empty.
Added
  • Action page component + the pages.invoke_action operation, so a Page can now do something, not just display: an Action button invokes a write/compute operation (e.g. artifacts.update, agents.run_blueprint) as the clicking viewer. A button can only invoke an op the page declares, and the viewer must independently hold that op's scope — so a Page can never become a way to call an operation a viewer couldn't call directly.
  • pages.create_from_template operation. Author a new workspace page from a vetted Amdahl page template (a catalog-only spec) by slug — so the in-app copilot can stand up a page (e.g. a content-calendar page) and, paired with a workflow schedule, set it to auto-update on a recurring cadence.
  • { $row: 'field' } Action input. A page Action button can now act on the row the viewer clicked — its declared inputs resolve from the clicked row, so per-row buttons (move this piece, archive this row) no longer need a hard-coded id.
  • Page Action buttons can now invoke `workflow` operations (e.g. agents.run_blueprint), not just write/compute ops — so a Page button can kick off a workflow run, not only edit a row. The rule is now simply: a button may invoke any op that _does_ something (write / compute / workflow); a read stays the page's display channel. The same boundary holds — the op must be declared on the page and the clicking viewer must independently hold its scope (so a "Run workflow" button needs workflows:delegate).
  • Page Action buttons can also target external providers via an external:<id> address — a pluggable seam for actions that reach out (post to a channel, push to a CMS, fire a webhook), gated by the provider's required scope. A reference external:echo provider ships so the path is live; real providers are added behind it.
  • The Content Calendar page template gained two buttons — "New piece" (creates a placeholder content_piece) and "Run routine" (fires the new `content-calendar-routine` workflow on demand) — plus that workflow itself, a scheduled (weekly, off by default) routine that plans and drafts the upcoming window. Enable its schedule to keep the calendar full hands-off.
Fixed
  • Page embed signing secrets now load and manage correctly from Settings -> Embedding in the console. Listing, creating, and revoking a workspace's page-embed signing secrets works again (the surface previously failed with a "business_id is required" error).
Added
  • Calendar and Board page components, plus an artifacts query source, so a Page can render your workspace content (e.g. content pieces) as a live calendar or kanban board over the Postgres artifact store — not just the warehouse sql source.
  • A ready-made Content Calendar page template (content-calendar) that pairs the two views over your content_piece artifacts. Fetch it via pages.get_template and author a Page from it.
  • Positioning experiments. Read how your positioning claims perform — what buyers echo back versus what actually wins deals — across three new surfaces. Query the data directly: data.query now addresses two positioning surfaces, positioning_claims (your claim inventory: text, label, category, status) and positioning (per-claim performance: leading buyer-reception lift and matched-control lagging win-rate lift), discoverable via data://schema. Run the new Positioning Scorecard workflow for the labeled "what we say vs what lands vs what wins" read, including the inversion where the story you lean on most is the one that loses. Or author a live Positioning Experiments page from the new template (claim inventory, confidence-tier breakdown, and a reception-vs-outcome chart). The win-rate signal is a matched-control estimate (a correlation, not proof) — the surfaces are built to read claim _ordering_ over absolute numbers and flag a low-coverage signal as directional.
Changed
  • Positioning experiments now separate measured messaging from candidate positioning. Every claim carries a source: mined_llm claims are pulled from what your team actually says on calls (their lift is real messaging performance), while seed claims are hand-authored candidate positioning the engine matches by meaning (their lift is a "would this land" test, not a performance review). The Positioning Scorecard workflow and the Positioning Experiments page now keep the two in clearly separate sections and never present a seeded claim's numbers as measured performance, and the data.query schema guidance teaches the distinction so the assistant interprets it correctly in chat too.
Added
  • Connection data summaries. Each connected source now exposes a glanceable, per-connector snapshot of its own synced data - counts and totals (deals and pipeline value, meetings, messages, tickets, pages), the most recent items, and a weekly activity sparkline - at GET /connections/:id/summary and the connection://<id>/summary MCP resource. Computed live from your synced data, it shows what is unique to each connector type.
Changed
  • Relationship intelligence now lives directly on the data surface. Questions like "who is the champion or economic buyer on this deal", "what did a specific stakeholder actually say", "who do we keep losing to", and "which accounts are evaluating a competitor" are answered with data query / explore over the stakeholder columns folded onto the interactions surface (is_champion, is_economic_buyer, champion_score, role_level) plus the deal_qualification champion / economic-buyer / competition dimensions — taught in the schema explorer and the GTM routing guidance so the agent reaches for them automatically.
  • The data tool's schema catalog now advertises the native record_type column (call / email / meeting) for filtering interactions by category. Category-filter prompts and examples use it instead of the older interaction_type remap, so questions like "emails about pricing" or "calls per company" produce clearer, more accurate SQL.
Removed
  • Removed the include_knowledge_graph option on data cluster search. It read from a decommissioned dataset and added no signal beyond the stakeholder columns now folded onto the interactions surface, so the tool no longer accepts it.
Fixed
  • data tool: cluster_detail now accepts the source_id returned by cluster_search verbatim. Previously the cluster_id argument only accepted a number, so drilling into a theme failed with "Cluster not found" because theme ids are opaque strings — pass the source_id straight through and the drill-in works.
Added
  • A public changelog at docs.amdahl.co/changelog - a searchable, branded timeline of what's shipped, refreshed automatically with each release.
  • Notion Knowledge Sync — one-way mirror your Amdahl knowledge base into a Notion database in your own workspace. Connect Notion over OAuth, pick a parent page, and every promoted document syncs into Notion automatically, with an hourly reconcile that backfills and self-heals drift. Configure / monitor it over REST or read its status + activity ledger over MCP (notion_sync://).
  • The assistant can now draw on more of your data directly for richer answers: the deal stage as it stood at the time of each conversation, theme insight summaries and headline hooks, theme lifecycle and lineage over time, and additional per-company deal-qualification detail.
  • The assistant now answers deal-stage and pipeline-funnel questions at the deal level with human-readable stage names ("Discovery", "Closed Won", …), win/loss outcome, and true funnel ordering — instead of raw internal CRM stage codes — so per-stage pipeline value, win rate, and funnel breakdowns come back clean and correctly ordered.
  • The assistant can now name themes directly when tracking how they evolve over time (a stable theme name now travels with each theme's history), and deal-stage / pipeline-funnel questions now return human-readable stage names for Pipedrive-based workspaces too — so theme-trend and funnel answers read cleanly across more CRMs.
Changed
  • knowledge_base.upload: a document's description is now its stable purpose ("what is this document for"). When you append a new version to an existing living document, the purpose is carried forward automatically and any description you pass is ignored — record per-version "what changed" notes in version_changes instead.
  • Internal cleanup: retired the legacy V1 cluster-evidence channels behind external research. The customer-voice / divergence-map pane now sources cluster evidence entirely from the V2 pipeline — no customer-visible change, since these channels already returned empty once the V1 pipeline was decommissioned.
Fixed
  • The GTM health report now reads correct, human-readable deal stages from your CRM (e.g. "Discovery", "Research", "Closed Won") instead of raw internal stage codes, and no longer splits a single account across multiple stage rows.
  • Asking the assistant about themes, deal stages, or deal qualification is now materially more reliable. It reads the correct underlying fields (so theme-lifecycle and stage questions no longer fail on some workspaces), keeps the "how complete is this deal's qualification" and "how likely is it to close" scores distinct, and stops surfacing internal placeholder columns that don't apply to your data.
  • Fixed "Make it living" on a Knowledge Base document failing with a schema-validation error. The synthesized refresh workflow now always declares a valid output, so turning a static doc into a self-refreshing living doc succeeds reliably.
  • Fixed external_search (search / enrich_company / enrich_topic) dropping its web results and competitive divergence map. The web source's underlying search call was rejected by the model API; it now succeeds, so the divergence map and web summary come back reliably.
  • Knowledge base search and other embedding-backed features now reliably use the current embedding model. Previously, newly uploaded documents could fail to become searchable, and semantic search could silently fall back to keyword-only matching.
  • Restored the internal-evidence keyword aggregates in external research (the customer-voice / divergence-map pane) after the V1 pipeline decommission — they now read the live V2 unified view instead of the dropped V1 dataset.
Added
  • Blueprints - shareable, forkable recipes an agent reads and walks step by step. Author, validate, and fork via the blueprints tool family and REST; seven starter blueprints ship out of the box.
  • Connections - a unified connector catalog and connect / disconnect surface spanning CRM, calls, comms, docs, support, and social (X / LinkedIn). Poll connection health and sync-run history over connection:// reads and REST.
  • External search fuses your CRM + call corpus with live market sources into a single brief (the divergence map). Four actions: search, enrich_company, enrich_person, enrich_topic, with an opt-in SSE event stream.
  • Notifications - agents can email workspace members (member-only, rate-capped, idempotent) via the notifications tool and POST /notifications/email-member, and read the send ledger.
  • Pages - workspace-authored, data-backed UIs composed from a catalog of components (tables, charts, stats, signal maps) bound to your own queries. Author + validate via the pages tool family and REST, publish, and embed.
Changed
  • The performance.* operations were renamed to social.* (clean break, no aliases) for social account tracking and engagement reads.
Removed
  • Retired the customer-facing artifacts REST API (/artifacts*) and its public read endpoint. Pages and Blueprints are the structured-output primitives now; artifact webhook events and data models are unchanged.
Added
  • Generic Agent Runner. New agents.* tool family: agents.start, agents.status, agents.resume, agents.cancel, agents.list, agents.profiles_list.
  • Server-Sent Events stream for agent progress at GET /api/platform/v1/agents/:session_id/stream. Emits state and progress frames, :ping keepalives every 15 seconds, auto-closes on terminal status.
  • Three built-in agent profiles: content_writer (end-to-end content creation, 25-turn budget, emits content_piece artifacts), researcher (rigorous research with citations, 20-turn budget, emits research_report artifacts), copilot (general-purpose assistant, 15-turn budget, optional artifact output).
  • Three pause types on awaiting_input sessions: approval, question, continue_or_finish. Each carries a JSON Schema that agents.resume validates against.
  • Consumer docs tree at /docs/consumer/ with auto-generated API reference covering every tool, scope, webhook event, and data model.
Changed
  • Every agent tool call is now written to platform_audit_log with the caller's identity and correlation id, matching the audit trail direct REST and MCP calls already produced.
Added
  • platform_audit_log table. Every tool invocation across REST, MCP, and agent sessions is recorded with actor id, business id, tool id, inputs hash, status, duration, and correlation id.
  • audit_log.query tool for reading the audit trail. Scoped by business; platform admins can query across businesses.
  • Response-side redaction layer. Any field classified as sensitive is replaced with [MASKED] and paired with a <field>_masked: true sentinel in the response body.
Changed
  • Error responses now include X-Correlation-Id on every status code, not just 5xx, so failed requests can be traced end to end.
Added
  • Webhook extensions. POST /api/platform/v1/webhooks/:id/test fires a single test.ping delivery without affecting production aggregates. GET /api/platform/v1/webhooks/:id/deliveries returns the delivery history with status filtering and pagination.
  • is_test column on platform_webhook_deliveries to separate test fires from production traffic.
  • X-Webhook-Test: true header on test deliveries so receivers can branch on synthetic traffic.
Changed
  • Webhook delivery retry policy codified at 3 attempts with 1s and 10s backoff intervals; after the third attempt the failure is recorded and failure_count is incremented on the webhook.
Added
  • scope_mode column on API keys and OAuth clients, with per-tool scope enforcement. Tools whose declared scope is not in the caller's effective scope set are silently dropped from the runtime tool list.
  • Scope reference page at /docs/consumer/api-reference/scopes.md, auto-generated from the tool registry.
Changed
  • Role defaults tightened. New keys default to the minimum scope required for the role; existing keys retain their prior effective scope via the grandfather rule.
Added
  • Artifact unification. Bidirectional triggers between platform_artifacts and the legacy writing_samples, customer_posts, customer_testimonials, and style_collections tables. Reads from either side return identical data; writes propagate automatically.
  • platform_artifact_versions append-only version audit trail. Every write to platform_artifacts inserts a corresponding version row.
  • artifacts.get tool now supports include_versions: true to return the version history inline.
Changed
  • Artifact writes must supply expected_version for concurrent-edit safety. Mismatches return 409 version_conflict with the current version in the details block.
Added
  • Platform API v1 initial release. Base URL https://api.amdahl.com/api/platform/v1. Four-tool architecture: data.*, context.*, artifacts.*, plus the supporting surfaces for sessions, webhooks, scopes, and OpenAPI docs.
  • OpenAPI 3.1 spec at /api/platform/v1/openapi.json, regenerated on every release.
  • Canonical error envelope with code, message, and optional details.
  • Global per-IP rate limit of 100 requests per minute on /api/platform/v1/*.
  • OAuth 2.0 dynamic client registration per RFC 7591 at POST /oauth/register, with its own tighter limit of 5 registrations per minute per IP.
Changed
  • Nothing; this is the baseline.