feat(desktop): shared slot vocabulary — sort + top_n on the bind proposal - #555
Merged
mattcfilbert merged 3 commits intoJul 20, 2026
Merged
Conversation
…oposal
jam gen-23 Move 1 (receipts: m1's order-by strand; the ranking family cannot
say 'top 10'). The proposal schema gains two optional concepts — sort {by,
direction} and top_n — advertised in PROPOSAL_OUTPUT_SCHEMA so Call-2 models
learn them from the propose payload itself, validated against the workbook
schema BEFORE apply, spliced via the computed-sort/top-N helpers extracted
from refine-worksheet (built earlier today — reused, not duplicated), atomic
failure on splice errors. One bind call now carries ordering and limits; no
refinement tail. Growth law honored: receipt-backed concepts only, binder-
validated, riding the one-call path.
Full suite 4567 green, tsc clean, lint clean. combined-lean 45,992/46,000 —
8 bytes headroom; next growth must trim first.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…escribe trims These two files were part of the sort/top_n packet but missed the explicit staging list; the working-tree suite masked the gap (adjudication lesson: git-status-clean check BEFORE declaring a packet landed). Without them the pushed tree fails its own validate-proposal byte cap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g dies Receipt (m1, 2026-07-20): a sheet named 'P&L Waterfall…' surfaced entity- escaped through list-worksheets, made refine-worksheet miss by literal name, and silently confirm-miss (refined:false) by escaped name — any &-titled sheet was unreachable. Now: names decode exactly once at output boundaries (list-worksheets/dashboards, bind-template sheet_name/guidance), name inputs resolve normalized-to-normalized with escaped-input tolerance, apply gates compare normalized, and refine uses the canonical literal name from fetched XML for apply/readback/output. Coverage for & < " in literal and escaped paths. (Includes a sliver of the prior commit's file overlap — the two commits were disentangled from one worktree; suite green across both.) Full suite 4582 green, tsc clean, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mattcfilbert
added a commit
that referenced
this pull request
Jul 20, 2026
… slim surface, Call-2 auto-apply, result-carried readback (#554) * feat(desktop): surface the document round-trip in the command reference (discoverability) Live root cause (2026-07-19, two banked receipts): on calc-heavy asks the agent searched 'underlying-metadata' -> 0 hits -> concluded 'not available in this build' -> fell back to hand-writing workbook XML and drowned. The verbs exist (executor maps them to GET/POST /v0/workbook/document) but had zero entries in the JSON that search-commands, validateKnownCommand, and paramContractGuard all read — undiscoverable AND uninvocable through the tool. Adds honest entries for tabui:save-underlying-metadata / load-underlying-metadata (load declares required in-param 'text'), allowlists both, and names the verbs in the zero-hit recommendation. Empirically gated: her exact failing query now returns the pair at ranks 1-2; 'calculated field' puts save at rank 1; guard rejects load{} and load{filepath} with actionable steers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): containment guard for load-underlying-metadata (whole-document or nothing) Adversarial-review P1 mitigation for surfacing the round-trip verbs: a pre-dispatch guard on execute-tableau-command rejects fragment loads (non- <workbook> root, no datasources/worksheets), loads that would DROP live worksheets (steer: delete-worksheet), and gross-shrink documents (<50% of live) — with fail-open on live-read infrastructure failure. Guard built by GPT-5.5 minion, adjudicated + full suite re-run firsthand (4453 green). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(desktop): readback-verify law — a completed load envelope does not prove application Live-proven 2026-07-19 (Desktop main.26.0715, three probes): document loads that ADD columns or rewrite worksheet content apply; loads that REMOVE a datasource column are silently ignored — completed envelope, no effect. Teach: after every load, re-read with save-underlying-metadata and confirm the change landed. Applied to the load entry's description and the notional-spec-calc-authoring knowledge module. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(desktop): guard false-positive — real documents carry comments before the workbook root FATAL caught by live audition probe: Desktop documents open with a build comment between the XML prolog and <workbook> ('<!-- build main.26.0715 -->'); the root regex forgot comments, so the guard rejected EVERY legitimate whole-document load as a fragment — blocking the exact path it exists to protect. Live receipt: verse 2's 'fragment' rejections were false positives. Regression fixture uses the verbatim real head. Lesson (now in the stack skill): probe the guard's ACCEPT path against a real artifact, not only its reject paths against synthetic fixtures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): author-calc tool — semantic calc authoring, no document in the agent's hands Live evidence (two drown receipts, 2026-07-19): agents on the manual round-trip fragment the 50KB document re-emission. author-calc takes caption+formula primitives and does the round-trip internally: read → unique-name splice into the target datasource (single non-Parameters default, candidates listed on ambiguity) → guard-validate → load → READBACK-VERIFY (completed does not prove applied). Caption collisions rejected pre-write. Built by GPT-5.5 minion, adjudicated firsthand. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(desktop): fund author-calc under the 46k surface cliff — describe trims, ratchets tightened 46,691 → 45,753: prose-only trims across the six fattest describes; per-tool ratchets lowered to the new sizes. Load-bearing semantics restored after adjudication where the trim cut meaning (Call-2 proposal provenance on bind-template, plan-dashboard-creation pointer and applies-to-LIVE warning on build-and-apply-worksheet). Full suite 4,460 green, tsc clean, combined-lean under cap with headroom. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(desktop): calc knowledge — author-calc first; calc-editor door is human-in-loop only open-calc-editor-with-custom-calc returns completed WITHOUT committing (opens the editor pre-filled; open editor blocks the UI thread — live-proven twice 2026-07-19). Knowledge now routes: author-calc tool first, manual round-trip as fallback, calc-editor commands never in unattended runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(desktop): author-calc — only the top-level datasources block holds real datasources Live verse receipt (2026-07-19): worksheet views clone <datasource> elements, so a Superstore workbook offered 'Sample - Superstore, Sample - Superstore' as candidates, and splicing into the clone was silently discarded by Tableau (the readback-verify caught it). Selection now scans only the first <datasources> block. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(desktop): author-calc — always splice at datasource end; relation columns are a position trap Live untaught-verse receipt (4 failed author-calc calls, readback-verify caught every one): <connection>/<relation>/<columns> holds schema <column ordinal=.../> nodes; insert-after-last-column landed the calc inside the relation block and Tableau silently discarded it. End-of-datasource is the position every successful live splice used tonight. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(desktop): real-document replay fixture for author-calc + active-sheet law in spec knowledge Every author-calc bug tonight was invisible to synthetic fixtures and cost a live verse to find (datasource clones; relation-column position trap). The replay test runs the tool against a real saved Desktop document (username scrubbed) offline. Knowledge: generate-viz renders on the ACTIVE sheet — goto-sheet immediately before, or it clobbers a neighbor (live receipt: the agent detected the clobber via readback, restored the sheet, and rerouted — correct behavior, avoidable trap). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): author-calc resolves sibling-calc caption references to internal names Live finale receipt (2026-07-19): all six author-calc calls succeeded, but 5 of 6 layered formulas referenced sibling calcs by CAPTION ([Member Profit], [Profit Tier]) — Tableau formulas resolve internal names, and authored calcs get [Calculation_N] names the agent cannot know, so every dependent calc flagged invalid and the chart leg died. The tool now rewrites bracketed caption tokens to internal names at splice time (base fields where caption equals name pass through untouched). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): author-set — param-linked Top/Bottom-N sets via document round-trip Wraps the proven set shape (Segno's golden groupfilter + CODA's live param-link proof) as an author-* verb: primitives in (caption/dimension/orderBy/count/end), golden <group><groupfilter> XML server-side, spliced at datasource-end, readback- verified. count accepts a literal N or a [Parameters].[X] token — the melody plays over the key signature. Offline replay (5/5) incl. real 49KB Superstore document. Live-mapped this session (receipts): the document round-trip is the whole dialect — calcs/sets MERGE; parameters are OPEN-only (frozen to merge, all headless create/edit commands hit dlg.DoModal). Set authoring needs no parameter mutation: it references the param by token and Tableau resolves it at runtime. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(desktop): author-action — parameter-change actions via document round-trip Live-proven this session (CODA): a workbook-level <actions> block MERGES via the round-trip — spliced <edit-parameter-action> targeting [Parameters].[Parameter 1] survived readback, link intact. This refuted the map-agent's OPEN-only assumption (the same trap sets fell into) — a live probe beat the reasoning. Wraps it as a verb: primitives in (caption/sourceWorksheet/sourceField/ targetParameter/activation), golden <edit-parameter-action> XML server-side, creates the workbook <actions> block if absent (between </datasources> and <worksheets>) or appends with a fresh [ActionN] name, readback-verified. Offline replay 4/4. The interactivity layer over the key signature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(desktop): format-labels verb + surface-fund the author-* trio under the 46k cliff format-labels: turns mark labels ON/OFF for a worksheet via the document round-trip (PROVEN live 2026-07-19 — <format attr='mark-labels-show'> in a pane MERGES and survives readback). Idempotent: rewrites an existing rule or inserts one; readback- verified. Offline replay 4/4. Funding: author-set/author-action/format-labels pushed the combined tool surface past the 46k tools/list auto-deferral cliff (and the combined-lean profile's). Per the ratchet doctrine (never raise the cap — trim to fit), emptied redundant single- token .describe() stubs across the fattest tools (plan-dashboard-creation, build-and- apply-dashboard, validate-proposal, dashboard-health-check, inject-template, dashboard -auto-apply, add-field, apply-worksheet, resolve-field, build-and-apply-worksheet). Field names + enums already carry the meaning; empty describe drops the JSON key entirely (verified). Lowered the grandfather caps to lock the wins in; removed the tools that dropped under the 1200B per-tool budget. Full suite 4476 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(desktop): author-parameter — the honest modulation verb (seed at OPEN, reopen explicit) Parameters are the ONE shape frozen to live merge (PROVEN live 2026-07-19, CODA: create/add/value-edit all silently refused; every headless create/edit command is a blocking dlg.DoModal). A parameter is born ONLY at OPEN. So this verb does the document surgery — splices the <column param-domain-type> into the Parameters ds (creating that ds if absent; an empty one is dropped on load, one with a real column survives) — writes a reopen-ready stage, and returns { stagePath, reopenRequired: true }. The reopen + re-pin is the serving layer's job, surfaced explicitly, NEVER hidden inside the tool (ghost gen-18: it's a session-lifecycle event). The reopen preserving merged calcs/sets/actions/formatting is live-proven. Parameters = the key signature; everything else is the melody merged over it. Offline replay 4/4. Funds the 5th verb under both 46k cliffs by emptying redundant describe stubs (get-worksheet-xml, apply-dashboard, remove-field). Full suite 4480 green, tsc clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(knowledge): dynamic-authoring router — teach the 5 author-* verbs + key-signature/melody law New tactics/data/notional-spec-dynamic-authoring.md is the routing map that steers the agent to author-calc/author-set/author-parameter/author-action/format-labels instead of hand-XML, with the one governing law (params=key signature born at OPEN; calcs/sets/ actions/formatting=melody merged live) and the full WW44-shape recipe in build order. Cross-linked bidirectionally with the calc-authoring doc. Every claim live-proven this session. This is the teach-Sonnet layer — the verbs are the capability, this is discovery. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(knowledge): dialog-command misclassification guard — 15 commands the reference marks safe but block The command reference marks 15 *DialogCommand-sourced commands as opens_blocking_dialog= false + agent_can_invoke=true; invoking them unattended pops a modal that wedges the session (live-proven: edit-existing-parameter hung 12s while health stayed OK). Names the 15, gives the trust rule (source name > derived flag), routes to author-* verbs instead, and records the generator-fix heuristic (source =~ /Dialog/ => force blocking). Refines the ghost's 'reference omission' into the real bug: misclassification, not omission. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(desktop): dynamic-authoring TOOL_PROFILE — the 10-tool singable no-XML surface Answers 'make it shorter': instead of trimming describe stubs to squeeze verbs under the 46k tools/list cliff, define a lean profile that IS the whole authoring language. TOOL_PROFILE=dynamic-authoring = spec-loop's 5 (execute-tableau-command for the NotionalSpec chart/dashboard spine + discovery/readback) + the 5 author-* verbs (calc/set/parameter/action/format-labels). Ten semantically-named tools cover the full WW44 dynamic dialect; zero agent-visible XML/cache/validation/template tools. Measured wire surface: 9,644 bytes vs the 46,000 cliff — 79% headroom (vs the full 45-tool surface that fights the cliff). The cliff stops being a fight structurally. Full set stays reachable via TOOL_PROFILE=full. Tests: registers exactly the 10, banishes XML/template tools, asserts <30k. Full suite 4482 green, tsc clean. Ghost gen-19 Move 1 (the ruthless surface already half-existed as spec-loop; this bolts the write half on and names it). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(desktop): dynamic-authoring grows ask-user + search-commands — the 12-tool singable surface CODA's joy-cut overshot: a singer who cannot ask for help or discover the execute-tableau-command dialect is not lean, she is mute. Re-measured at 11,500 wire bytes — 75% headroom under the 46k cliff. * feat(desktop): author-parameter completes the reopen in-call — the key signature no longer stops the song CODA's one seam, closed tool-side: getExecutor discovers manifests dynamically and getDesktopConfig() re-reads env per call, so the tool itself relaunches the seeded stage (open -n, live-probed: manifest 2s, API-ready 3s), readback-verifies the parameter in the reopened doc, re-pins TABLEAU_DESKTOP_SESSION_ID in-process (only when a pin already existed), then SIGTERMs the old instance (probed: dies clean, no recovery sibling). Any failure degrades to the honest reopenRequired stage-on-disk result. stagePath is now optional — untaught agents never invent filesystem paths; the default stages beside the live workbook's own file. * chore: sync package-lock version to 2.26.0 * fix(desktop): reopen launches the bundle binary directly — open -a loses the document among instances Dress rehearsal caught two live defects the offline suite could not: (1) with multiple instances of the bundle running, 'open -n -a' starts a fresh instance but LaunchServices routes the document Apple Event unpredictably — the reopened instance came up EMPTY; spawning <bundle>/Contents/MacOS/<binary> <stage> detached carries the document deterministically (and puts it in argv). (2) The default stagePath cannot derive from the old process's argv for the same reason — it now stages under ~/Documents/My Tableau Repository/Workbooks (real user path; Desktop has crashed saving from sandboxed tmp dirs). E2E-proven live: reopened 78197→78328, param verified in the new instance's readback. * docs(knowledge): author-parameter reopens in-call — the router doc catches up to the shipped verb * feat(desktop): dynamic-authoring route joins the instructions — the verbs are named where the singer reads first Finale autopsy: untaught Sonnet landed both parameters through the in-call reopen but burned 55 of 65 calls spelunking raw commands for the set and dashboard, and never reached author-set — the tool list carried the verbs but the initialize instructions never routed a dynamic ask to them. Segno's discoverability law, one level up: ink the sign in the score she reads at note one. * fix(desktop): trim the dynamic-authoring route under the combined-lean 46k cliff The prior commit pushed combined-lean to 46,116 — the full suite caught it after an ungated commit chain (the lesson is the gate order, re-learned). * feat(desktop): dialog blocklist enforced in the param guard — the boo modal dies here revert-workbook-ui fired Error 47BF7751 on Matt's screen three times in one verse: the reference says safe, CODA's probe said modal, the knowledge doc knew, but nothing ENFORCED it. Now the guard refuses all 16 live-proven dialog commands outright, each with a FIX redirecting to the sanctioned alternative (author-parameter, author-action, NotionalSpec keys, or author-forward). Every annoyance dies exactly once. * fix(desktop): author-calc resolves PARAMETER captions to qualified [Parameters].[N] refs — the empty-sheet killer Verse-3 live receipt: the singer's filter calc named two parameters by caption; resolution only covered the target datasource's columns, so the refs never bound and the sheet rendered empty on Matt's screen. Parameter captions now resolve from the Parameters datasource to the qualified cross-datasource form, set after the field map so a caption collision resolves to the parameter — which is what a dynamic-ask formula means. * feat(desktop): notionalSpecGuard validates full v0.2 vocabulary — kills the silent-empty-sheet class Live eval receipt (2026-07-20 TUTTI Blake-set wave): a spec with aggregation:'none' (not v0.2) and a rangeFilter using max: (v0.2 is start/end) passed the guard, codegen generated NOTHING, and the /v0 success envelope shipped an empty sheet as a PASS. The guard now validates per-field keys/enums (data/type/role/aggregation/encoding, 'shelf' redirect, detail/tooltip v0.3 gate), sort, rangeFilters, relativeDateFilters (plural periods, next/previous), and categoricalFilters — every rejection carries a FIX line that teaches the correct vocabulary in-context. Accept fixtures are the six live-proven TUTTI golden specs; reject fixtures are the live failing payloads. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(desktop): teach the NotionalSpec dialect in the census entries for the semantic-loop pair The dynamic-authoring profile has no knowledge tools, so search-commands is the singer's only reachable teacher — expertise:// pointers are dead ends there. The generate-viz entry now carries the v0.2 cheat-sheet (chart enum, field props, filter/sort shapes), the author-calc-then- reference-by-caption idiom (aggregation 'default', never 'none'), the string-date DATE() idiom, and the write-blind law (probed raw 2026-07-20: /v0 invokeCommand returns state:SUCCEEDED with no result, no operations route — verify by readback, always). The read-spec twin's entry now states its output is NOT returned by the /v0 API (product gap) and routes readers to document readback. Both entries get real parameter metadata (was []). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * style: autofix lint (prettier, import-sort) + explicit return type on test helper Green firsthand: lint clean, build ok, 4531 tests pass. CI was red on lint only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(desktop): mock spawnDetached in the 3 reopenFromStage tests that omitted it CI Tests step failed (both node matrices): the timeout + 2 success-path reopen tests fell through to defaultSpawnDetached, which spawned the real macOS Tableau binary — ENOENT on the Linux runner fired as an async unhandled rejection after the test passed, exiting the process 1. Passed locally only because the app path exists on macOS. All other reopen tests already mock it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(desktop): the singer sings native by default — unset TOOL_PROFILE now selects the 12-tool dynamic-authoring surface Flips the desktop default from the full 40-tool surface (raw XML get/apply + templates + cache) to the lean native-authoring surface: semantic loop via execute-tableau-command + the five author-* verbs + discovery/readback, zero agent-visible XML. 'full' is the explicit opt-in escape hatch; demo/spec-loop/ combined-lean unchanged. Consumers that need the XML surface set TOOL_PROFILE=full. TAS + the eval kit already set the profile explicitly, so the singer is unaffected; this makes native the DEFAULT for every unset consumer (ghost gen-19 standing move). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(e2e): desktop + combined list-tools expect the lean native default surface The TOOL_PROFILE default flip (unset -> dynamic-authoring) changes what both the standalone desktop server and the combined bundle's desktop half register when no profile is set. Assert the lean 12-tool native surface (raw XML tools opt-in via TOOL_PROFILE=full). Desktop list-tools verified locally; combined needs CI web creds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(desktop): data-loss guard matches double-quoted worksheet names (was failing open) Review P1: WORKSHEET_NAME_RE only matched name='...' (single quotes), so a live worksheet with a double-quoted name was invisible to the dropped-sheet check and could be silently dropped on reload — the exact data-loss this guard exists to prevent, failing OPEN. Match both quote styles (the pattern formatLabels.ts already uses for the same attribute). Regression test with a double-quoted live sheet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(desktop): cut model round-trips — bind-template on the slim surface, coherent instructions, census, live-session fields Live receipts (2026-07-20 slim battery) root-caused the slow eval: ~9 model turns/song at ~5s each while every tool result returns in <0.1s. Three of those turns were manufactured by the surface itself: - instructions advertised bind-template and XML fallback tools the dynamic-authoring profile does not register (m1 receipt: two search-commands calls literally hunting for 'bind template'), so bind-template joins the slim profile (13 tools) as the deterministic ~0.3s fast-path for plain chart shapes; route prose no longer names unregistered tools; - a command census prose entry lists the load-bearing tabdoc/tabui commands so search-commands is reserved for the uncommon path (m1: 13 of 23 turns were discovery thrash); - list-available-fields required a cached workbookFile and its error pointed at cut get-*-xml tools (e1 turn 1 burned on 'File not found'); workbookFile is now optional and omitting it reads the live session workbook. Instructions stay under the 46k tools/list deferral cliff (combined-lean budget test green). Full suite 4535 green, tsc clean, lint clean. Known tradeoff: DESKTOP_INSTRUCTIONS is profile-independent, so full-profile consumers lose the dashboard-auto-apply routing prose; instructions now match the default surface. Profile-aware instructions are a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): Call-2 auto-apply + result-carried readback for generate-viz-from-notional-spec Live re-time receipt (e1, 60s/13 calls): a Call-2 bound result stranded the slim surface (auto-apply was Call-1-only and the manual apply tools are cut), costing 4 search-commands thrash turns; then 5 more turns re-verified a write-blind spec apply. - bind-template auto_apply now applies any bound fast-path-eligible result. A Call-2 proposal is binder-validated against the live workbook and applies under the same events-anchor user-change guard; the freehand fallback the model otherwise takes has fewer guards. - tabdoc:generate-viz-from-notional-spec success results now append a compact server-side readback (sheet, Rows/Cols shelves, mark, sort) resolved from the active window; fail-open, one metadata round-trip. The command reference's verify guidance now points at the result readback. - bind-template byte cap ratcheted down to 1629 (describe trim funded the gate-comment rewrite). Full suite 4537 green, tsc clean, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): retire the notional-spec dialect from routing — bind-template + author-* carry the song, refine-worksheet joins the slim surface NotionalSpec is retired (Matt, 2026-07-20). Three live pointers still steered the model at the dead command (jam gen-21): the plain-chart/dashboard/dynamic/ edit-in-place route prose, the command census, and the success-path hint strings author-calc and author-set return on every call. All re-pointed at the post-spec dialect: author the semantic object first, then bind-template the chart naming the authored caption; refine-worksheet (primitives-only top-N/sort) joins the 14-tool dynamic-authoring profile to carry edit-in-place. The spec command itself stays registered and functional — the door closes when the replacement chain is live-proven, not before. Full suite 4537 green, tsc clean, lint clean. Instructions +13 bytes, cliff-safe (refine-worksheet was already in the full surface the combined budget measures). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): inline calcs[] on bind-template — author + bind in one call jam gen-22 Move 1 (receipt: the author-calc→bind chain costs ~9-13s of model turns per calc song). bind-template accepts calcs[{caption,formula,datatype, role}]: formulas validate BEFORE any document mutation (atomic error, zero apply on a bad calc), authoring reuses author-calc's splice/load/readback via the new shared authorCalcCore, and the bind + auto-apply see the post-calc workbook. authored_calcs surfaces in every outcome. Route prose updated. Per-tool cap raised 1591→1725 for the capability (slim surface is ~11.6k of 46k; combined-lean cliff stays the hard gate, green at ~45.9k). Full suite 4540 green, tsc clean, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): refine-worksheet sort_by_field + empty session treated as absent jam gen-21/22 Move 2 (receipt: m1 waterfall — tabdoc:sort 500'd on seven wire shapes, ~150s of blind model turns, before a manual computed-sort splice landed direction/using correctly). sort_by_field produces that same computed-sort shape through refine-worksheet's readback-verified apply path, with caption resolution matching the existing ops. resolveSession now treats empty/whitespace session strings as absent (was a wasted error turn: session:'' against a pinned Desktop). Full suite 4548 green, tsc clean, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(desktop): tabdoc:sort is dialog-natured — block with redirect; teach the true sort contracts Live receipts (2026-07-20): tabdoc:sort popped blocking modals on the user's screen (47BF7751 'missing: global-field-name') after seven opaque 500s. The monolith's own sort-cmd.data settles it: SortCommand drives the sort UI dialog (updateSortDialog notification) — it was never agent-safe — and SortNested is the programmatic sort that existed all along. - execute-tableau-command now refuses tabdoc:sort pre-dispatch with a FIX line redirecting to refine-worksheet sort_by_field or tabdoc:sort-nested. - Reference corrected: Sort marked dialog-risky with the true wire contract (global-field-name, Type-required-unless-clear, computed-sort MeasureName); sort-nested pinned with its required params. - paramContractGuard enforces sort-nested's required params pre-dispatch. Full suite 4556 green, tsc clean, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(desktop): shared slot vocabulary — sort + top_n on the bind proposal (#555) * feat(desktop): shared slot vocabulary — sort and top_n on the bind proposal jam gen-23 Move 1 (receipts: m1's order-by strand; the ranking family cannot say 'top 10'). The proposal schema gains two optional concepts — sort {by, direction} and top_n — advertised in PROPOSAL_OUTPUT_SCHEMA so Call-2 models learn them from the propose payload itself, validated against the workbook schema BEFORE apply, spliced via the computed-sort/top-N helpers extracted from refine-worksheet (built earlier today — reused, not duplicated), atomic failure on splice errors. One bind call now carries ordering and limits; no refinement tail. Growth law honored: receipt-backed concepts only, binder- validated, riding the one-call path. Full suite 4567 green, tsc clean, lint clean. combined-lean 45,992/46,000 — 8 bytes headroom; next growth must trim first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(desktop): complete the slot-vocabulary commit — validate seam + describe trims These two files were part of the sort/top_n packet but missed the explicit staging list; the working-tree suite masked the gap (adjudication lesson: git-status-clean check BEFORE declaring a packet landed). Without them the pushed tree fails its own validate-proposal byte cap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(desktop): literal names at every tool boundary — the ampersand bug dies Receipt (m1, 2026-07-20): a sheet named 'P&L Waterfall…' surfaced entity- escaped through list-worksheets, made refine-worksheet miss by literal name, and silently confirm-miss (refined:false) by escaped name — any &-titled sheet was unreachable. Now: names decode exactly once at output boundaries (list-worksheets/dashboards, bind-template sheet_name/guidance), name inputs resolve normalized-to-normalized with escaped-input tolerance, apply gates compare normalized, and refine uses the canonical literal name from fetched XML for apply/readback/output. Coverage for & < " in literal and escaped paths. (Includes a sliver of the prior commit's file overlap — the two commits were disentangled from one worktree; suite green across both.) Full suite 4582 green, tsc clean, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
Stacked on #554. jam gen-23 Move 1: the proposal schema gains its first two shared semantic concepts —
sort {by, direction}andtop_n— receipt-backed (m1's order-by strand; the ranking family couldn't express 'top 10'), advertised via PROPOSAL_OUTPUT_SCHEMA, schema-validated before apply, spliced by the computed-sort/top-N helpers extracted from refine-worksheet, atomic on failure. One bind call now carries ordering and limits.Growth law: one receipt-backed concept at a time, binder-validated, one-call path only — this is deliberately NOT a grand vocabulary redesign.
Full suite 4567 green. combined-lean 45,992/46,000 (8 bytes headroom — next growth trims first). Per-tool caps raised with justification comments (bind-template 1908, validate-proposal 1555).
🤖 Generated with Claude Code