Skip to main content

Sklful Technologies How we build

The engineering detail, for the person who will actually check.

Our delivery argument rests on two pieces of our own tooling. Both have public source, so none of what follows has to be taken on trust. This page is the detail we keep off the front page — what each one does, what it is measured against, and where the limits are.

The workflow

pipeline-skills

A language model asked to run a fifteen-stage process from a single prompt will not run it. As the conversation grows, the original instruction is pushed out of active attention: the model implements the fix, skips the code review, forgets to post it, and reports success. Not deception — the instruction is simply no longer there.

The state file is the program. The model is the executor.

Every pipeline writes a state file to disk holding each stage and each mandatory checklist item. To advance a stage the model has to tick items from that file, read fresh — not from what it remembers of the conversation. The record of what happened is a by-product of the process rather than a document written afterwards from memory.

Ten skills plus a headless runner cover the loop from roadmap entry to merged pull request, with review, security scan, documentation and a written retrospective as stages that must complete rather than as intentions.

The four failure modes it is built against

attention dilution

The instruction falls out of the active window as context grows.

summarization loss

Compaction drops the specific constraint and keeps the gist.

rationalization drift

A skipped step is justified after the fact rather than caught.

plausible shortcuts

A cheaper path that sounds correct is taken over the specified one.

Gate-off testing

A quality gate that cannot fail is decoration. Each gate is verified by deliberately breaking what it guards and confirming it stops the build. A test suite that passes tells you nothing on its own; a suite that has been shown to fail for the right reason tells you something.

This site was built that way, and it caught real defects in its own demonstration — a queue that deadlocked after thirty seconds, and a record that displayed an extraction score before extraction had happened. Both were invisible to a passing test suite that asserted only correctness properties.

Read it on GitHub · public workflow repository

Context engineering

A large context window is not the same thing as attention.

Most disappointment with AI-assisted delivery comes from treating the context window as a filing cabinet — put everything in, and assume the model is weighing all of it. It is not. Relevance decays across a long window, summarization silently drops the specific constraint and keeps the gist, and the model has no way to tell you which of the two just happened. Engineering around that is most of the work.

Put less in, deliberately

Irrelevant context is not free — it competes for attention with the part that matters. We scope what a stage can see to what that stage needs, and keep the long-lived record on disk rather than in the conversation, where it degrades.

Read from disk, not from memory

A checklist recalled from earlier in a conversation is a guess about what was said. The same checklist re-read from the file is a fact. Every gate in our pipeline reads fresh, which is the entire reason the state file exists.

Make a wrong answer fail a check

A fabricated citation that looks plausible will survive human review. It will not survive a script that resolves it against the source. We prefer controls a reader does not have to be alert to.

Citation audit, on a legacy conversion at volume

Converting a mainframe-era system's documentation is exactly the task where a language model is most useful and least trustworthy: enormous volume, and an output that reads as authoritative whether or not it is. One of our principals ran a conversion of over 25,000 documents on a federal claims modernization. The discipline that made it defensible was not a better prompt.

Output landed in a staging area rather than in the deliverable. Every citation it produced was mechanically resolved back to a real path in the source material, and anything that did not resolve failed the audit rather than reaching a reviewer. A human read the result; a script decided whether the result was allowed to exist. That ordering is the whole technique, and it generalises well beyond documents — it is the same shape as the confidence gate in the demo on our front page.

Where a rule lives decides whether it holds

When a retrospective produces a new rule, the interesting question is not whether to adopt it — it is where to put it. A rule that depends on somebody remembering is a different kind of object from one a machine refuses to proceed without. We rank the venues honestly, including the weak ones, because some rules genuinely belong there.

Enforcement venues, weakest to strongest guard
Venue Fires when Can it be bypassed?
Instruction file The agent reads it, and remembers Easily — by forgetting
Pre-push hook At git push Yes — --no-verify
CI workflow After push, on the pull request Yes — an admin merge
Mandatory state-file item The stage executor reads it from disk and must tick it Hard — the gate refuses to advance the stage

The honest caveat is the bottom row is not always available. "Trust the reported symptom, not the file path the reporter cites" is a judgment rule — there is no script for it, so it lives in the instruction file and relies on the operator. Pretending everything can be mechanised is its own failure mode. Knowing which rules cannot be is the useful part.

The framework

djust

An open-source Django framework that renders reactive interfaces from the server. There is no separate front-end application — no bundler, no build step, and no second codebase to keep in sync with the first. On a typical government web application that removes an entire discipline from the staffing plan and an entire class of defect from the schedule.

Measurement snapshot: djust commit c133110f. Its generated client-size manifest reports 63,851 bytes for the gzipped minified client. Fonts, styles, page content, and development tools are separate; verify transfer size on the deployed application.

Client payload
~62.4 KiB
gzipped client artifact, not total page weight
Rust crates
5
templates, VDOM, core, live, components
Licence
MIT
source available for ongoing maintenance
Template engine
7–11×
faster than Django on variable- and filter-heavy templates; no faster on static markup

Conformance

Scored against Django's own template test suite, with the miss rate published.

Against Django 5.2.16, 1,032 of 1,047 cells that reach the engine pass unmodified — 98.57%. Nothing in Django's checkout is edited to get there. The 15 remaining cases stay in the denominator, because documenting an unsupported API does not turn its failures into passes.

What matters for an application is what those 15 are. None of them is template syntax. Every one is a Python-introspection API that djust deliberately does not reproduce:

The 15 non-passing cases, by category
Cases Category What is being inspected
8 Django node inspection template.nodelist, get_nodes_by_type(), Python node representations. Applications needing these use Django's own backend for that inspection.
5 Loader-cache representation The number and identity of objects inside Django's template cache. djust keeps its own parsed-AST cache. Missing templates still raise TemplateDoesNotExist.
2 Compiler metadata template.extra_data from a custom compiler extension. Ordinary registered tags and filters are supported.

Read the versioned compatibility report for this result and the 409 additional tests that do not reach the engine. These are API boundaries, not unsupported syntax. We publish them because the alternative — quoting a percentage and leaving the reader to guess what the remainder is — is how vendors get caught.

GitHub · PyPI · Documentation

The obvious objections

Questions an evaluator should ask about all of this.

We would rather answer these in writing than have them raised for the first time in a debrief.

The framework was written by one of your principals. What happens if he leaves?

The framework is MIT licensed, with public source, tests, and documentation. Project handover should include the application's source, dependency versions, setup instructions, and a walkthrough for the receiving team.

Django skills transfer to its models, URLs, ORM, and templates; maintaining reactive behavior also requires familiarity with djust. A license does not supply replacement staff. We agree handover and any ongoing support in the engagement scope, including the receiving team's training needs.

Are you locking us into something proprietary?

No. Python, Django, PostgreSQL, and an MIT-licensed rendering layer you can fork. Nothing in the stack is ours to withdraw and nothing requires a licence from us. If the relationship ends, you keep a Django-based codebase with public dependencies. The handover should account for djust-specific behavior as well as standard Django skills.

If AI writes the code, who is accountable for it?

We are, exactly as we would be for code typed by hand. The workflow exists precisely because a model's self-report is not evidence: the gates run whoever wrote the change, they are themselves tested to fail when they should, and the record of what passed is written as the work happens rather than reconstructed afterwards.

GSA's June 17, 2026 revised proposal for GSAR 552.239-7001 concerns LLMs processing government data, with exceptions and role-specific flowdown requirements. Public source and test records alone do not establish compliance. We review the applicable solicitation and agree permitted tools, data handling, and required documentation for the engagement. Read the June 2026 proposal.

Ask us something we have not answered here