Rob Dull/ Tools/ AI ProdOps/ Technical notes
Agentic PDLC · Engineering Notes

How this is actually built.

This page is for a technical program manager, delivery systems leader, or engineer sizing up the judgment behind the toolchain rather than the product pitch. It states the stack, the component boundaries, the data contracts between tools, what's enforced in code versus asserted by a model, the trust boundary around API keys, the deploy model, and the debt that's tracked but not yet paid. Plainly, not promotionally.

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

Two build systems, deliberately, not one

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
  • Zero dependencies, trivial to edit, 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) is what keeps nine apps from becoming nine forks
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, not nine forks

Every spine app imports the same internal @robdull/toolkit package rather than re-implementing its own client, scoring math, or 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 spine apps

Shared domain logic

  • A single scoring module: the one WSJF and RICE implementation every prioritization-touching app calls into, so there is exactly one formula to get right
  • A fixture-based MCP evidence layer, keyless, that grounds prompts in cited PetHealth data until live connectors 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 spine app also ships a keyless sample: for most, a demo.html rendering a real 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 chain runs entirely same-origin through localStorage, not a backend. Each arrow below is a small versioned TypeScript module, not a loose object shape passed by convention, playing the same 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 + Architecture epics, D/F/V, benefits-realization plan
robdull:business-cases04 → 05kind, caseType, roughEffort, execSummarySeed
robdull:epic-ranking05 → 06Method, weights, scores, funding line
robdull:roadmaps06 → 07Milestones, release windows
robdull:brds07 → 08One BRD per funded epic
robdull:backlogs08 → 09One backlog per epic
Jira CSV09 → JiraFile download; terminal handoff, no further chain

Guardrails enforced in code, not asserted by the model

The AI drafts every artifact. It does not get the final word on whether that artifact is internally consistent; a handful of checks are computed in plain code and cannot be talked around by a confident-sounding response.

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 deliberately not adopted for this deployment. The full reasoning, cost per session, blast radius of a leaked key, and the UX trade-off of asking a visitor for their own key, is written up on its own page rather than asserted here. 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 enables same-origin handoffs without a backend but creates real 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, plainly stated

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. For a solo-maintained portfolio project this is a scope choice, not an oversight: a broken push is caught by hand within minutes, and the alternative, a pipeline maintained for two repos with no team behind them, buys safety this project doesn't currently need.

One deploy-safety habit worth naming: at least one spine app's site directory holds a hand-authored page that is not a build artifact and would be silently 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.

Debt tracked, not hidden

A short, current list, not an exhaustive one:

What isn't verifiable from here

The monorepo is private

The repository behind the nine-tool spine is private, so this page describes the architecture rather than lets you inspect it directly. 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 sprint 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.