Repository navigation
Conversation
An option or slot token carrying entity_choice joins the
no_data.ambiguous_entities group of that index, so two groups written
alike ("aid from Congo to Congo") open two menus, each from its own
slot. Without the field, menus group by mention text as before.
Co-authored-by: Claude <noreply@anthropic.com>
The client tarball is built from DevelopmentFinanceObservatory/sdk 97df221, whose wire types carry entity_choice on NoDataOption and SentenceToken, so src/lib/search/types.ts re-exports both from the client again. Co-authored-by: Claude <noreply@anthropic.com>
… links Search Console reported pages indexed though blocked by robots.txt, 404s and other 4xx answers. robots.txt blocked /s, /embed, /studio, /history, /login and /register, so Google could not read their noindex. Those routes now leave the block list and send X-Robots-Tag: noindex from one list in src/lib/crawl.ts, which next.config.ts serves on every response, redirects and errors included. A /data?share= page is indexable only when a dataset item in GALLERY_ITEMS names that share. robots.txt now blocks /mcp and /s/*/download and names a new sitemap of the public pages. Docs pages advertise and link a .md copy only when the page has a corpus file, so pydeflate and resolvekit no longer point at a 404.
A gallery search at /data?share=<id> loads its result in the browser from /api/share, which robots.txt blocks, so crawlers saw only the empty Get Data screen. The page now looks up the gallery item with gallerySearch, the same lookup the robots rule uses, and the server writes its title, description and data sources into the page, with the title as the page's h1, and into the page title and Open Graph tags. DataSearch renders without a Suspense boundary, since the route is dynamic and the first HTML can hold the whole view. Other shares get no summary and stay noindex.
The test harness ended its pools and then terminated every backend left on the test database. pg-pool's end() resolves once it has asked its clients to close, before their connections have. A backend that had not yet read its client's Terminate got the terminate first and sent the client a FATAL error, which the ended pool emitted with no listener. CI failed limit-counter.test.ts this way while every subtest passed. The harness now records each connection its pools open and teardown waits for all of them to close before it terminates stragglers.
…indexing fix(seo): let crawlers see noindex, add a sitemap, stop dead Markdown links
…ounter-flake fix(db): wait for test connections to close before terminating them
The platform proxy now carries x-dfo-client to the APIs, cleaned as the APIs clean it (non-printable characters and edge space dropped, cut to 256 characters) and left out when blank. Every other x-dfo-* request header stays blocked. The label is caller-chosen and serves usage counting only.
* feat(studio): switch how a plan figure is counted from the plan card Decision rows that carry a scope choice list its options: the active one marked, available ones selectable, partial ones with their years and unavailable ones disabled with their reason. A pick sends a switch with the plan revision through the interrupt stream, keeps the card until the re-offered plan arrives, and shows what moved. A stale revision or an unavailable option leaves the card with a notice. The wire mirror gains the plan revision, requirements, operations and asks it lagged on. * fix(studio): keep the switch control usable after a refusal A stale-revision refusal stops further switches on that card and says why; options in flight keep focus; the moved note and notice stay mounted so screen readers announce them; a plain detail body reaches the notice. * fix(studio): replace a stale plan card with the one the harness holds A switch or approve refused as plan_revision_stale now takes the current_plan the harness returns and shows it with the refusal's detail, so switching and approving continue on the plan actually pending. Approve sends the plan revision the user saw. * feat(studio): render reading chips after an answer and switch on a click Studio shows the harness's apply_choice chips beside the follow-up prompts on the latest answer. A click sends a turn carrying the chosen option and no message, shows the chip label as the user's side, and streams the answer like any turn; a refused chip shows the reason and is removed. * docs(studio): tidy the plan switch and chip comments * feat(studio): send the turn and reading a chip was offered for A chip carries the turn whose answer offered it and the spec_id of the reading it switches, and the click sends both in apply_choice, so the harness can refuse a chip whose answer or reading is no longer current. * fix(studio): keep a stale plan unapprovable and own turn starts and ends in one place A switch refused as stale keeps the card's revision, so an approve is refused, and only the harness's switch refusals count as refused switches; any other failure ends the turn. stream() guards every refusal against a stopped or superseded turn, send and applyChoice open a turn through one startTurn, a chip clicked mid-request queues, a forked conversation shows no chips, and the card shows its notice. * fix(studio): count a chip click as a prompt A chip passes the guest prompt limit and is tracked as studio.prompt with intent apply_choice, through the one wrapper typed prompts use.
…approved plan under its answer (#74) * feat(studio): lead the plan card with what is counted and keep the approved plan under its answer The plan card shows the plan's title, a one-line summary, each scope choice with Change, the step that gives the answer and a View full plan button. A failed switch keeps the card and states its reason under the choice it concerns. A changed value carries a Changed tag. plan.approved attaches an approved-plan pill to the answer, stored with the message and opened read-only. A harness that sends none of the new fields still gets a card. * fix(studio): settle a switch that ends without a plan and make the choice rows accessible A switch stream that closes, errors or is stopped without a plan returns the card to idle with its notice and leaves the paused reply untouched. Every refusal shows the harness's detail; 401 and 429 offer no retry. Options are buttons with aria-pressed in a group, focus returns to the switched row, and the notice sits in a live region mounted empty. An older harness's card leads with the question. * docs(studio): tighten the plan card's comments * fix(studio): mark a row Changed against the turn's first plan A switch re-pins a part, so a choice's id carries a new spec id; rows are matched by their axis. A row is Changed when its option differs from the turn's first plan, so two switches mark both rows and a switch back marks none. * fix(studio): keep the plan card live only on a server pause and key choices on their stable ids Stop on a switch sends cancel and keeps reading: a re-offered plan makes the card live again, and a stream that ends without one leaves it read-only with its Activity entry closed. Try again follows switch_failed.retryable or the refusal's retry mode. Choices are keyed on choice_id, with the axis only for an id missing from the earlier plan, and a stale refusal keeps the turn's first plan as the baseline. Map.groupBy is replaced for older Safari. Conversation search matches message text only. The approved plan shows its caveats. * fix(studio): end a gone pause read-only, show caveats before approval and quiet a stopped switch A refusal for a pause that no longer exists ends the card read-only. A choice falls back to its axis only when its id was replaced. 401 and 429 never offer an immediate Try again, and a busy refusal offers it after its retry delay. Moved choices with no row, each choice's reason and the plan's caveats show on the card, and a stopped switch is a quiet note. Switch settling moves out of stream() into an onEnd callback, notices share one builder, and the card and full plan share one approve bar. Conversation search also matches a user message's card title, with a database test. * fix(studio): keep a switch's card live when the harness was unreachable and match choices by id only A switch whose request got no response keeps the card live with Try again; only a server-confirmed end makes it read-only. Every failed switch clears the steps-updated mark. Choices match on choice_id alone. The fallback answer step is the last answering step in plan order, the headline takes the harness's title when it has one, caveats key by index, and the three switch notices share one builder. * fix(studio): give a stopped switch time to be re-offered and time retries from the notice A switch's stop grace (15 s) outlasts the harness's 10 s re-offer, and repeated Stop clicks send one cancel. A 429 with a retry delay offers Try again after it, timed from when the notice arrived. The switch-ended path reuses endTurn, stream() handles a caller-owned end in one place, and the live card and approved view share the answer-step rule and the caveats list. * fix(studio): end a switch read-only unless its refusal left the pause alone Only a busy, option-unavailable or rate-limited refusal keeps the card live; every other refusal ends it read-only with a reader sentence, and a proxy's raw text goes to the console. Try again appears only when the harness asks for a retry after a delay. done and error frames end the turn when they arrive, a stopped switch keeps its Stopping line, a Stop after a fresh plan sends no cancel, and a switch stream's Activity entry closes by how the harness ended it. * fix(studio): keep the plan live when the site proxy refused a switch A switch the proxy refused before the harness answered (its 502 with no upstream status, or its 429) left a live pause behind a read-only card or a row without Try again. The proxy's 502 now names the upstream status when the harness had answered, the card stays live otherwise, and a proxy 429 offers Try again after Retry-After. A live row shows detail only from a harness ToolError, and a stopped switch's notice is quiet. * fix(studio): let Stop end a switch still waiting to be sent A switch picked while the paused stream was still open waited with no halt, so Stop did nothing. The halt is published when the stream is queued, and a Stop before the request starts skips it and keeps the card live with a quiet note. A Stop followed by a refusal ends as stopped, and the approved view guards stored steps and choices. * fix(studio): end a stopped switch as stopped whatever answers it A refusal after Stop ends the switch with the quiet stopped note, a Stop on an unsent switch clears its halt so a later switch can be stopped, and only a switch publishes its halt while queued. A proxy 429 offers Try again only with a positive Retry-After and reads "Studio is busy." * fix(studio): end a stopped switch as stopped when its fetch fails A switch the user stopped whose fetch then rejected came back as a live card reading "Studio could not be reached." It now ends as stopped, as a refused one does. * fix(studio): announce a switch's outcome and say steps changed only when they did The card keeps one polite live region that states what a switch changed, as the moved-choices note did, and "Steps updated to match." shows only when the step labels differ from the previous plan's. * docs(studio): tidy the plan card and switch comments
…screen (#80) * fix(studio): let a tall plan card scroll so the approve bar stays on screen The plan stack had flex-shrink: 0, so a plan taller than the chat foot pushed the "Start building?" bar and the prompt input below the clipped 100dvh section. The card now gives up height and scrolls inside; the bar, input and note keep their natural height. * fix(studio): keep the plan card usable on short screens At 844x350 to 370 the plan card's scrollport collapsed to zero height, so View full plan and the scope controls could not be reached, even by keyboard. The card now stops shrinking at a floor of rem(120), its wrapper takes no box of its own (display: contents), and below that floor the chat foot scrolls as a whole, with bottom scroll padding so focus brings the input fully into view.
…ard (#76) * feat(studio): show planner decisions as switchable rows on the plan card The harness sends a planner decision the user can switch as a plan-card row with choice_id decision:<slot>. The ledger groups those rows under "Choices the plan made", apart from the scope rows under "Counted as", and a decision switch shows "Replanning" until the harness answers, since it runs a planner replan. switch_failed and Stop take the scope switch's paths. * fix(studio): read planner decision rows by the decision/<slot> id * fix(studio): show a planner question asked during a switch A question the replan asked while a planner-decision switch waited kept the "Replanning" card on screen and hid the picker. The question now takes the card's place and its pause carries the waiting plan; the answer resumes as the same switch, so a fresh plan, switch_failed, Stop and a second question still end it.
…approved planner decisions (#83) * fix: keep crawlers out of event counts, keep preview cards, and file approved planner decisions track drops bot requests, page openGraph keeps the site name and root card, /data share and spec URLs send X-Robots-Tag, approved choices file planner decisions by choice_id, a refused chip refunds the guest prompt, shared wordings are numbered in the entity menu, and a stale switch without a current card ends read-only. * fix: refund any refused guest turn and decide /data noindex in one function stream refunds a metered turn's prompt on any refusal, as meterTurn does. src/proxy.ts sets /data's X-Robots-Tag from dataPageRobots, the function the page metadata uses. Preview cards carry their size and type, and a gallery dataset previews with its own card.
The client asks the file selector only for its keys and reads nested columns. Shares accept the name_corrected assumption and the view states it as a corrected name.
Contributor
Author
|
Replaced by the release PR from the cut branch release/2026-10-29 at 24e53dc. |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Releases
devat6dc181b8to production: eight pull requests and three direct commits, each deployed and green on staging.Studio: #73, #74, #76 and #80 show a plan's scope choices and planner decisions as switchable rows on the plan card, and keep the approve bar on screen, reading the events dfo-ai #88 and #95 send. Search: #66 groups entity-choice menus by
entity_choice, and #69 and #70 vendor and re-lock the client at sdk97df221. #68 forwards the SDK clients'X-DFO-Clientlabel upstream. The direct commits41dd678anda887a6aadd noindex headers (next.config.ts,src/lib/crawl.ts), a sitemap and crawlable gallery previews, and9f24d1fwaits for test connections to close.The deploy runs no migration and adds no env var or workflow change. Merge after the ai release has deployed, since the plan card's switches need the harness events it sends.