Rob Dull/ Tools/ AI ProdOps/ Technical notes
AI-assisted workflow · Technical notes

How the tools are built

This page is for technical program managers, delivery systems leaders, and engineers who want to judge how the tools are built. It covers the stack, the component boundaries, the data contracts between tools, what's checked in code and what's left to the model, how API keys are handled, the deploy model, and the known technical debt.

React Vite TypeScript npm workspaces Hand-authored HTML GitHub Pages Claude API, browser-direct

Two build systems, each for a different kind of page

Hand-authored HTML

No build step. The .html file is the deployable artifact: markup, an inline stylesheet, and an inline script where the page is interactive.

  • The résumé, work history, every Perspectives essay, the tools hub, workshops
  • Two of the eleven tools: the persona generator and the product ops radar, which make no network calls at all
  • No dependencies, easy to edit, and nothing to build or version

React + Vite + TypeScript monorepo

An npm-workspaces monorepo (private repo, separate from this site's repo) holding nine of the eleven tools: everything except the persona generator and the product ops radar, which are hand-authored HTML with no network calls.

  • Each app builds independently with vite build
  • The hashed output is copied into this site's /tools/<app>/ directory
  • A shared internal package (below) keeps the nine apps from drifting into nine separate copies
Neither approach is the default. Content that doesn't call an API or hand data to another tool stays hand-authored HTML. Anything with sequential AI calls, shared scoring logic, or a handoff another tool consumes moves into the monorepo, where the shared package prevents the same bug from being fixed eight times.

One shared package for the nine apps

Every app in the monorepo imports the same internal @robdull/toolkit package for its API client, scoring math, and handoff logic.

Shared runtime

  • An API client shared by all nine apps
  • A generic useAgenticChain(steps) hook that drives run, edit, back, and reset for any array of pipeline steps
  • Shared React components: PipelineBar, RunButton, ResponseSurface, KeyModal
  • Design-token CSS shared across the nine apps

Shared domain logic

  • A single scoring module: the one WSJF and RICE implementation every app that ranks work calls, so there is one formula to get right
  • A sample-evidence layer: fictional PetHealth records with source-like identifiers, shaped like MCP responses and served from fixtures with no key needed, which the prompts cite until live connections exist
  • Every cross-tool handoff module (next section)

Each pipeline step is a declarative config object: { id, buildPrompt, parse, render, maxTokens }. The hook is generic over an array of these, so no app hand-rolls its own step state machine. Every app also ships a sample that needs no key: for most, a demo.html that renders a captured run through the same step renderers as the live tool; for Business Cases, a worked-example gallery on the tool itself (including the PetHealth EPIC-03 case the demo thread follows). Evaluating any tool costs a visitor nothing and needs no key.

The data contracts between tools

The tools pass data to each other through the browser's localStorage, on the same site, with no backend. Each handoff below is defined by a small, versioned TypeScript module, which plays the role an internal API schema plays between two services.

Handoff keyStageWhat crosses
robdull:personas01 → 02Persona → journey seed
robdull:opportunity-seeds02 → 03Journey pain clusters → intake candidates
robdull:journey-seeds03 → 02Bidirectional: intake can request more journey detail
robdull:epics03 → 04Business and architecture epics, demand/feasibility/viability assumptions, benefits plan
robdull:business-cases04 → 05kind, caseType, roughEffort, execSummarySeed
robdull:epic-ranking05 → 06Method, weights, scores, funding cutoff
robdull:roadmaps06 → 07Milestones, release windows
robdull:brds07 → 08One BRD per funded epic
robdull:backlogs08 → 09One backlog per epic
Jira CSV09 → JiraFile download; the last handoff, imported into Jira by a person

Checks enforced in code

The AI drafts most artifacts, but it doesn't get the final word on whether they hang together: a few checks run in plain code, and a confident-sounding response can't talk its way past them.

Sample-output provenance

Every public example should identify its origin using one of four labels, applied consistently rather than alternated.

The trust boundary: how API keys are handled

Visitor-supplied key, direct to Anthropic, no server in the path

All nine apps in the shared workspace, including the strategy-alignment tool, call api.anthropic.com directly from the visitor's browser using a key the visitor supplies. The key lives in sessionStorage and clears on tab close. Two tools, the persona generator and the product ops radar, make no network calls at all. There is no server anywhere in this system holding anyone's key.

A Cloudflare Worker pattern that would hold a server-side key was evaluated and not adopted for this deployment. The full reasoning, covering cost per session, the blast radius of a leaked key, and the trade-off of asking visitors for their own key, is on its own page. Read the trade-off ↗

Relevant risks include malicious or compromised site JavaScript, compromised third-party dependencies, browser extensions, shared or unmanaged devices, cross-site scripting, accidental exposure through debugging or screenshots, broadly privileged API keys, and sensitive content transmitted to the model provider.

Appropriate controls before broader testing include a strict Content Security Policy, a dependency inventory and update process, no unnecessary third-party scripts, clear model-provider disclosure, restricted-key guidance, usage monitoring, a sanitized-data requirement, a documented incident contact, and a security review before accepting confidential data.

Browser state and run files

Workflow state is stored in browser local storage, which allows handoffs between tools without a backend but has limits: state belongs to one browser profile, clearing site data removes it, shared work and concurrent edits aren't supported, there is no server backup, and local data may remain on the device.

Run-file download and restore provide portability, but a run file can contain everything entered and generated, and should be treated as potentially sensitive. Before a run file changes hands: it should be reviewed and sanitized first, notes alone are an acceptable substitute for the file, how received files are stored and eventually deleted should be stated, and files containing employer-confidential content shouldn't be collected.

Deploy model

Manual, no CI/CD, no staging

main is production on both repos. GitHub Pages republishes on every push to this repo's main. There is no staging environment and no automated pipeline. That's a deliberate scope choice for a portfolio project with one maintainer: a broken push is caught by hand within minutes, and a pipeline for two repos with no team behind it would add safety this project doesn't need yet.

One deploy habit: at least one app's site directory holds a hand-authored page that isn't a build artifact and would be deleted by a naive copy-and-overwrite. Deploys diff the existing directory against the fresh build output before wiping anything, specifically to catch that class of mistake before it ships.

Release checklist: build every application, confirm no unexpected file deletion, open each public route, test one complete handoff path, verify sample pages, verify key-modal and API-error behavior, verify run-file download and load, verify Jira CSV generation, check console errors, and record the release version and date.

Known technical debt

A short, current list:

What isn't verifiable from here

The monorepo is private

The repository behind the nine apps is private, so this page describes the architecture instead of letting you inspect it. The shared package has unit test coverage for scoring parity, chain-state handling, and API client behavior. There is no CI gate, no per-app test suite, and no end-to-end test; correctness beyond that unit coverage currently leans on the computed guardrails above and manual verification at each release. If you'd like to look at representative code directly, the scoring module or a single handoff contract, I'm glad to walk through it on request: rob.dull@gmail.com.

What can be verified publicly

  • The public interfaces exist
  • Worked examples can be inspected
  • Browser handoffs can be exercised
  • Scoring behavior can be changed interactively
  • The BRD funding restriction can be tested
  • Requirement mapping and batch warnings can be observed
  • Run-file behavior can be tested
  • Jira CSV output can be inspected

What cannot be verified publicly

  • The private source implementation
  • Correctness or completeness of the shared package
  • Automated test coverage
  • Security properties
  • Production reliability
  • Enterprise integration
  • Customer use
  • Productivity or decision-quality improvement
  • Business outcomes

This is a working proof of concept suitable for portfolio review and limited evaluation with fictional, public, or sanitized information. It is not suitable for confidential enterprise work or production use.