13 pieces of work, written up properly.
Each one states the problem, what was already there, what I changed, and what it measured afterwards, including the measurements that came back flat and the designs I deleted on their own evidence. They are long. The figure and the first two paragraphs are the short version.
Giving an AI assistant real access to a company's data
Corporate OAuth and four agentic tool servers added to an internal AI assistant, plus the security engineering that made giving a language model write access to mail, chat and calendars defensible.
→ Four tool servers live behind one consented identity. The assistant acts on a user’s own mail, chat, calendar and documents, and never sees a credential.
- Go
- Python
- Vue 3
- MongoDB
- Valkey
Answering tender questionnaires from a knowledge base that contradicted itself
A three-tier answering path (exact match, semantic match, retrieval-augmented generation) built over a corpus of roughly 3,900 reusable question-and-answer pairs, and what measuring that corpus revealed about trusting it.
→ The in-house tender answering system that displaced a $1,299/month commercial subscription, answering from the company’s own corpus after auditing it.
- Go
- MongoDB
- AWS Bedrock
- OpenSearch
- Embeddings
The thirty-thousand-token tax on asking what time it is
A per-user tool toggle and an embedding-based relevance gate in front of the model call, cutting the fixed token cost of having tools at all, plus the measurement that deleted the cleverest part of my own design.
→ The fixed cost of having tools at all, cut by up to ≈93% on a message, and the cleverest part of my own design deleted on its own evidence.
- Go
- Vue 3
- TypeScript
- MongoDB
- AWS Bedrock
Two vendor integrations, and the least privilege neither token could express
A read-only proxy to a compliance-automation platform and a delegated integration to a device-management platform. One authenticates as the organisation, one as each user, and the access control had to move somewhere else in both cases.
→ Two vendor integrations live and read-only by construction, with least privilege enforced in the proxy because neither vendor’s token could express it.
- Python
- Go
- MCP
- OAuth 2.0
- Docker
Measuring an agentic SOC triage pipeline before improving it
A multi-source indicator enrichment pipeline behind a cross-tenant cache, a grounding-and-validation layer that stopped a model attributing attack techniques from memory, and a labelled ground-truth baseline built before any of it was tuned.
→ An enrichment pipeline running on free-tier sources with no spend committed, plus the labelled baseline that makes any future tuning measurable.
- Go
- MongoDB
- Valkey
- AWS Bedrock
- MITRE ATT&CK
Filling in a spreadsheet you are not allowed to redesign
Answering a buyer's supplier response schedule inside the buyer's own workbook: resolving which columns are answers, deciding which rows are questions at all, generating one value per cell against the column's own vocabulary, and reporting honestly on everything withheld.
→ Several-hundred-row tender workbooks come back filled in and structurally intact, with 169 machine-written rows checked line by line against human ones.
- Go
- MongoDB
- AWS Bedrock
- Retrieval-augmented generation
- Excelize
The gate that would have been a deletion
Admitting a class of third-party vendor documentation into a retrieval library without letting it answer questions it has no business answering, and finding, before shipping, that the filter as designed could only ever subtract.
→ Per-bid control over which content may answer a question, shipped with the interface that sets it, after catching that the filter as designed could only subtract.
- Go
- MongoDB
- OpenSearch
- AWS Bedrock
- Object storage
The half of the report I refused to generate
Two AI-generated reports on a bid, and a third that judges the bid's own answers. It includes a grader that had to declare which of the answers it was marking had already seen the mark scheme, and a set of sections deliberately left as empty boxes for a human to type into.
→ Kickoff decks and review reports generated from what the system actually knows, with about two fifths of the deck left as empty boxes rather than invented.
- Go
- MongoDB
- OpenSearch
- AWS Bedrock
- AWS KMS
The only answer whose value is the customer's name
Every tender asks for three customer references matched to the work. The corpus already held a hundred of them, unreachable by construction, and the one part of the tab the system did answer filled a referee's phone number with the supplier's own.
→ Customer references now selected per bid by product and sector, where no single question could previously reach more than one of the 108 in the corpus.
- Go
- MongoDB
- AWS Bedrock
- AWS KMS
- BM25
The optimisation that would have bought one per cent
One page load spent roughly twenty-eight key-management round trips decrypting a field no handler anywhere reads. One returnable workbook took seventy to eighty minutes. The first was measured and fixed; the second was measured, and the change everyone reaches for first was dropped.
→ A bid page that stopped waiting on a decrypt nobody reads, and an obvious optimisation measured at ≈1% of wall clock and dropped rather than shipped.
- Go
- MongoDB
- AWS Bedrock
- AWS KMS
- OpenSearch
There is no buyer
"Learn more about this buyer" was a card that had shipped disabled months earlier. The system stored the buyer as free text with a substring search over it, recorded no won-or-lost outcome, and let its audit feed expire at a year. The feature was an identity problem wearing a reporting problem's clothes.
→ Win/loss history that follows a buyer across tenders and questionnaires, with zero external integrations. The fix was a data model, not a CRM link.
- Go
- MongoDB
- Vue 3
- AWS Bedrock
- OpenSearch
The role restriction that guarded nothing
The feature had a role, a flag and an admin tab, and forty-four of its routes asked only whether the caller was signed in. Fixing it meant separating four gates that get discussed as one: does this exist, who is it for, how much of it may they use, and who decides that from outside the code.
→ Forty-four unguarded routes closed, the most expensive calls in the product metered for the first time, and the frontend gate now fails closed.
- Go
- Gin
- Vue 3
- MongoDB
- Valkey
The cache that had never served an answer
A three-tier answer cache that was wired up, logging, healthy and passing its tests had served zero answers in its entire life. The reason was a gate reading one number as if it were a different one.
→ The cheap answer path switched on for the first time, after finding two stacked defects that kept it dark across 658 attempts.
- Go
- MongoDB
- AWS Bedrock
- Retrieval-augmented generation
- Cost measurement
Everything here is generalised: the engineering is described, my employer's systems are not. More are written up as they're cleared for publication.