Changelog
RSSAll 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>; RESTGET /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_qualificationnow exposesrealized_is_won/realized_is_closed(a company's realized deal outcome), andcompetitor_mentionsnow exposescompetitor_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 withas_of. data.querynow accepts Common Table Expressions (WITH … AS (…)) and subqueries (inFROMandWHERE). 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.querynow 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.explorewith 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 firstexploreof a session no longer stalls for tens of seconds).data.cluster_detailnow accepts a durablelineage_id(surfaced on everydata.cluster_searchresult) as an alternative tocluster_id. A theme'scluster_idchanges each time topics are recomputed, so a saved handle could go stale; thelineage_idis 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_blueprintnow resolves a tenant blueprint by itsidentity.slug, not only by its UUID. Running a blueprint you authored by its slug used to returnnot_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-reportworkflow declared alookback_daysinput 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. Thelookback_daysinput is removed: only thedealscut 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_daysinput 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. Thelookback_daysinput 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_daysinput (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. Thelookback_daysinput 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:
LineChartacceptsyMin+yMaxto 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
Tabscomponent (labelled panels the viewer switches between — each tab carries an inline catalog subtree) andCarouselcomponent (rotate sibling charts one slide at a time), plusQuoteList.expandable+QuoteList.detailFieldsfor a per-quote read-in-place detail dialog with richer attribution. - Workspace README — a one-read orientation map of your workspace. Read
workspace_readme://currentover MCP (orGET /workspace/readmeover 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
heightpreset (sm|md|lg) and an orderedcolorstoken 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.RadarChartadditionally acceptsmaxto pin the radial scale (e.g.max: 5for a /5 rubric fills the polygon), andFunnelChartno 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.uploaddefaultsversion_as_ofto 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 newmax_rivalsinput), 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
transformstep could not read a workflow input via the canonical$inputs.Xreference, 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
totalsquery (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.querywhose result exceeds itsLIMIT(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 viaallow_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
searchaction, sosearchcould 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 onsearchas well as the company/person/topic enrichments.
Added
knowledge_base.promoteandknowledge_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 oncompany_id.deal_score_weightsexposes 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 viadata://schemaand honor data-scope —competitor_mentionsis company-scoped like the deal-grain surfaces, anddeal_score_weightsis a business-level admin/GTM read. POST /agent-blueprints/:id/activate— activate or deactivate a workspace workflow (body{ enabled?: boolean }, defaulttrue; 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) andworkflow_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`.
CopyButtoncopies 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.Dialogadds 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, RESTGET /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.refreshand theindustry_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/syncandGET /notion-sync/documents/:document_group_id(plus thenotion_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/:idon 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
dealssnapshot can't.deal_stage_historyis one row per stage change (deal_id, the raw CRMdeal_stageid,changed_at);ref_deal_stagesmaps each raw stage id to its human label, funnel position, and won/lost/open class. Readdata://schemafor 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
searchresult carries an optional_timingbreakdown (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_workflownow carries the producing workflow'snameandblueprint_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_runblueprint 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_topiccall. 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.uploadAPI now also returns aconsole_urldeep 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
CalendarandBoardpage components (authored via thepagestool) gained two optional props for this:contentField(the row column holding a piece's full markdown body) anddocUrlField(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 a400 invalid_category. This unblocks the Living Knowledge "needs review" count. - Living Knowledge workflow activation now reflects execution reality. The
workflow_activefield on documents and thePOST /agent-blueprints/:id/activatetoggle read/writeblueprint_schedules.enabled— the cron scheduler's source of truth — instead of theworkspace_workflowscuration 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_basetool (both the API operation and the MCP coarse tool) now returns aconsole_urlfor 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_topiccall 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, soPOST /agent-blueprints/fork(and theblueprintsfork 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_urlattached to aknowledge_base.uploadresult (on both the operation and the MCP coarse tool) was built from the document'sdocument_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 anas_ofdate now resolves the cluster generation that was live on that date (via the warehouseclusters_as_oftable-function) instead of being refused — so a blueprint that reads themes with raw SQL backtests cleanly. The append-onlytheme_lineagehistory surface still requiresas_ofreads to go throughdata.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 withpages.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_searchandkb_searchsources (in addition tosqlandartifacts), 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) andindustry.list_themes(the clustered market themes) operations, or trigger a fresh sweep on demand withindustry.refresh. - Substack and YouTube are now searched in external research. Founder newsletters, talks, and demos are strong go-to-market signal, so
external_search(thesearchandenrich_topicactions) 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.listentries now includeforked_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
industrytool'srefreshaction kicks off a "What's Going On In The Industry" sweep on demand instead of waiting for the daily run, and returns arun_id. Poll the newindustry_run://list+industry_run://<id>reads to watch the run to completion and read its per-stage step log; readindustry://themes/industry://divergencefor 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_msis also clamped so the full pipeline (search + synthesis) stays under the tool-call ceiling — a largedeadline_msno 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_searchno longer searches them; theenrich_personaction 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
undefinedprefix, 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. Theresources,social,pages,notifications,industry, andblueprintstools now also accept the same optional context so a client populating it gets full coverage across every tool, not justdata/context/knowledge_base/external_search.
Added
- Run and schedule Workflows directly from MCP. The
blueprintscoarse tool gains arunaction (a one-shot headless run) alongsidecreate_schedulefor recurring cron runs, gated by the newblueprints:executescope 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
pagescoarse tool gains acreate_from_templateaction that materializes a vetted, Amdahl-shipped page template bytemplate_slug; browse the available templates via thepage_template://listresource first. - Read drafted content pieces back over MCP. A new
content_piece://read scheme (content_piece://list+content_piece://<id>, gated byartifacts:read) surfaces the content pieces a content-calendar Workflow drafted, so an agent can review a run's output without leaving MCP. agent_blueprint.listnow returnsis_activeandsourceon 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(searchand theenrich_*actions) surfaces social signal instead of coming back empty.
Added
Actionpage component + thepages.invoke_actionoperation, 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_templateoperation. 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
Actionbuttons can now invoke `workflow` operations (e.g.agents.run_blueprint), not justwrite/computeops — 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); areadstays 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 needsworkflows:delegate). - Page
Actionbuttons can also target external providers via anexternal:<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 referenceexternal:echoprovider 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
CalendarandBoardpage components, plus anartifactsquery 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 warehousesqlsource.- A ready-made Content Calendar page template (
content-calendar) that pairs the two views over yourcontent_pieceartifacts. Fetch it viapages.get_templateand 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.querynow addresses two positioning surfaces,positioning_claims(your claim inventory: text, label, category, status) andpositioning(per-claim performance: leading buyer-reception lift and matched-control lagging win-rate lift), discoverable viadata://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_llmclaims are pulled from what your team actually says on calls (their lift is real messaging performance), whileseedclaims 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 thedata.queryschema 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/summaryand theconnection://<id>/summaryMCP 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
dataquery / explore over the stakeholder columns folded onto the interactions surface (is_champion,is_economic_buyer,champion_score,role_level) plus thedeal_qualificationchampion / economic-buyer / competition dimensions — taught in the schema explorer and the GTM routing guidance so the agent reaches for them automatically. - The
datatool's schema catalog now advertises the nativerecord_typecolumn (call/email/meeting) for filtering interactions by category. Category-filter prompts and examples use it instead of the olderinteraction_typeremap, so questions like "emails about pricing" or "calls per company" produce clearer, more accurate SQL.
Removed
- Removed the
include_knowledge_graphoption ondatacluster 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
datatool:cluster_detailnow accepts thesource_idreturned bycluster_searchverbatim. Previously thecluster_idargument only accepted a number, so drilling into a theme failed with "Cluster not found" because theme ids are opaque strings — pass thesource_idstraight 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'sdescriptionis 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 anydescriptionyou pass is ignored — record per-version "what changed" notes inversion_changesinstead.- 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
blueprintstool 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
notificationstool andPOST /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
pagestool family and REST, publish, and embed.
Changed
- The
performance.*operations were renamed tosocial.*(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. Emitsstateandprogressframes,:pingkeepalives every 15 seconds, auto-closes on terminal status. - Three built-in agent profiles:
content_writer(end-to-end content creation, 25-turn budget, emitscontent_pieceartifacts),researcher(rigorous research with citations, 20-turn budget, emitsresearch_reportartifacts),copilot(general-purpose assistant, 15-turn budget, optional artifact output). - Three pause types on
awaiting_inputsessions:approval,question,continue_or_finish. Each carries a JSON Schema thatagents.resumevalidates 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_logwith the caller's identity and correlation id, matching the audit trail direct REST and MCP calls already produced.
Added
platform_audit_logtable. 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.querytool 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: truesentinel in the response body.
Changed
- Error responses now include
X-Correlation-Idon every status code, not just 5xx, so failed requests can be traced end to end.
Added
- Webhook extensions.
POST /api/platform/v1/webhooks/:id/testfires a singletest.pingdelivery without affecting production aggregates.GET /api/platform/v1/webhooks/:id/deliveriesreturns the delivery history with status filtering and pagination. is_testcolumn onplatform_webhook_deliveriesto separate test fires from production traffic.X-Webhook-Test: trueheader 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_countis incremented on the webhook.
Added
scope_modecolumn 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_artifactsand the legacywriting_samples,customer_posts,customer_testimonials, andstyle_collectionstables. Reads from either side return identical data; writes propagate automatically. platform_artifact_versionsappend-only version audit trail. Every write toplatform_artifactsinserts a corresponding version row.artifacts.gettool now supportsinclude_versions: trueto return the version history inline.
Changed
- Artifact writes must supply
expected_versionfor concurrent-edit safety. Mismatches return409 version_conflictwith 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 optionaldetails. - 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.