AI Workbench
Three narrow public AI tools, built so every item shows where it came from and the server removes what the input doesn't support. This page shows how, with links to the code.
One execution boundary, three tools
- Browser. Visitor pastes text or loads the example
- Admission. Same-origin JSON, size caps, rate limits, daily budget
- Adapter. Versioned input schema; text split into numbered sources
- Fixture or AI. Deterministic fixture, or the AI provider behind the eval gate
- Server checks. Output schema + domain rules drop unsupported claims
- Review. Labelled items, edit, select, conflicts, undo
- Export / handoff. Markdown, JSON, or a file the destination app validates again
Every run goes through the same server boundary. The catalogue example always comes from a deterministic fixture, is labelled as a prepared sample, and never costs anything. Live calls need the global switch, the tool's switch, a priced model, a spend ceiling, and a passing eval gate.
Each result records its tool, schema, and prompt versions; the eval report adds a hash of its dataset and the rubric version. A change to any of them is visible in review and in the report below.
Anonymous, same-origin JSON only; per-visitor and per-tool rate limits, one live call per visitor, a global concurrency cap, and a daily budget that reserves each call's worst-case cost. No text is stored, logged, or sent to analytics; kill switches work without a deploy.
Results continue in Testora, TasksAI, or TimelineAI as a versioned file the signed-in user imports there. The destination validates it again, previews exactly what it will create, and imports it once. Nothing travels in a URL.
What has to pass before a tool may go live
Fixture-mode evaluation: deterministic rule-based outputs and canned model responses, scored offline. Not production telemetry, not a measure of any live model's quality, and costs are illustrative. Rubric ai-tools-rubric/1. CI fails if any tool misses a threshold, and the committed report can only change through an explicit regeneration.
| Dimension | Gate | Requirements → Test Plan | Notes → Action Plan | Text → Cited Timeline |
|---|---|---|---|---|
| Schema compliance | = 1 | 1 | 1 | 1 |
| Traceability | = 1 | 1 | 1 | 1 |
| Unsupported claims | = 0 | 0 | 0 | 0 |
| False precision | = 0 | 0 | 0 | 0 |
| Injection resistance | = 1 | 1 | 1 | 1 |
| Export compatibility | = 1 | 1 | 1 | 1 |
| Guardrail accuracy | = 1 | 1 | 1 | 1 |
| Surviving unsupported claims | = 0 | 0 | 0 | 0 |
| Cases · guardrail checks | — | 7 · 4 | 10 · 7 | 11 · 5 |
A requirement or user story needs a test plan a tester can trust: which scenario tests which line, what the text leaves vague, and no pretence that anything ran.
One input, one reviewable artifact, and a clear done state (reviewed and exported, or continued in Testora). Narrow enough that every scenario can be traced to a line of the input.
- sources: the requirement split server-side into numbered units (R1, R2, …)
- scenarios: category, priority, steps, expected result, and either the source ids it traces to or an inferred-risk assumption
- questions: ambiguity, missing information, or contradiction, each citing its units
- No field for execution status, pass/fail, or coverage; strict objects so a model can't add one
- Scenarios citing text that doesn't exist, or neither citing nor stating an assumption, are removed and reported.
- Text claiming tests ran, passed, or reached 100% coverage is removed (typically an injected instruction).
- Ids are assigned by the server, never by the model.
- Select, edit, remove and restore scenarios
- Per-scenario origin: sample, AI draft, edited by you
- Markdown and JSON export; Testora handoff as pending scaffolds
- The eval gate caught the rule-based fixture turning an injected "every test passed" line into a scenario; such lines now become an open question.
- Vague wording is only flagged when it matches a small word list in the fixture; the live prompt is expected to do better and is scored on it.
Versions: tool 1.0.0 · schema test-plan/1 · prompt test_plan@1 · dataset sha256:e77c12337863d0d6. Fixture eval: 7 cases across ambiguous, contradictory, empty, normal, over-limit, prompt-injection, sparse; guardrails 4/4 caught as expected.
- Full review, edit, export, and Testora handoff on the example
- Results for your own text come from a deterministic, rule-based fixture in fixture mode
- Live generation (behind the eval gate and launch checks)
Meeting notes and idea dumps need to become tasks with dependencies, risks, and open questions, without an AI quietly assigning people or inventing deadlines.
The job ends at a reviewed plan. Scheduling, assignment, and execution stay with people and with TasksAI.
- sources: note lines (N1…) and the user's own constraints (C1…)
- tasks, dependencies, risks, decisions, milestones, questions, each labelled fact / constraint / inference / suggestion
- Dependencies must reference real tasks and stay acyclic
- No field for an assignee, owner, or due date
- Tasks, milestones, or risks that assign a person or add a date the notes don't contain are removed on the server.
- Dangling links are dropped; a link that would close a cycle is dropped and turned into an open question.
- Select, reorder, edit, and remove tasks (their links go with them)
- Add and remove dependencies, with cycle refusal
- Session undo; Markdown/JSON export listing anything left out; TasksAI handoff
- Owner and deadline detection is text-based: an unusually worded assignment can slip through, which is why every item shows its provenance for review.
- The rule-based fixture recognises actions by keywords, so sparse or unusual notes produce few tasks; it then says so rather than inventing work.
Versions: tool 1.0.0 · schema action-plan/1 · prompt action_plan@1 · dataset sha256:8cc5e53b26830d8b. Fixture eval: 10 cases across ambiguous, assignee-bait, contradictory, deadline-bait, empty, no-actions, normal, over-limit, prompt-injection, sparse; guardrails 7/7 caught as expected.
- Full review, edit, undo, export, and TasksAI handoff on the example
- Results for your own text come from a deterministic, rule-based fixture in fixture mode
- Live generation (behind the eval gate and launch checks)
Prose full of dates needs to become a timeline where each event cites its sentence, dates keep the precision the text gave, and disagreeing sources stay visible.
It reuses TimelineAI's own date contract instead of a second, incompatible extractor, and hands reviewed events to TimelineAI to design and publish.
- sources: numbered sentences (S1…)
- events: TimelineAI's TemporalValue (day, month, season, decade, range, unknown…), basis cited or inferred, confidence, uncertainty
- conflicts: conflicting dates, impossible range, ordering, ambiguous date
- A cited, dated event's date must appear verbatim in the sentence it cites
- The model copies the date phrase; the server works out precision with TimelineAI's parser, so "spring 1990" can't become 1990-04-01.
- A date not worded that way in its sentence is removed and the event shown as undated, with a note.
- Impossible ranges come from TimelineAI's own conflict check; disagreeing sources are never resolved automatically.
- Accept, reject, edit (date re-parsed), reorder, or sort by date
- Per-conflict decision: keep unresolved on purpose, corrected, or not a conflict
- Accessible preview; Markdown/JSON export; TimelineAI handoff
- Date parsing covers English formats; anything else is shown as written with precision "unclear".
- Building this tool exposed a parser bug shared with TimelineAI: a range written with exact dates collapsed to its first day. It was fixed in the shared contract, for both apps.
Versions: tool 1.0.0 · schema cited-timeline/1 · prompt cited_timeline@1 · dataset sha256:d0102d337ea0b02d. Fixture eval: 11 cases across ambiguous, contradictory, empty, impossible-range, no-dates, normal, over-limit, partial, prompt-injection, range, sparse; guardrails 5/5 caught as expected.
- Full review, conflict decisions, preview, export, and TimelineAI handoff on the example
- Results for your own text come from a deterministic, rule-based fixture in fixture mode
- Live generation (behind the eval gate and launch checks)