mjdeving

Agentic engineering, one decision at a time

Each block isolates one decision an agentic system forces (what counts as done, when knowledge loads) and gives a verdict with its reasoning. Under each block: how my own system answers it.

THE LOOP specification Which part of the agent loop is yours to engineer? The one around the turns: what done means, what checks it, and what stops it.

Both loops in one picture: the tool loop feeds a real result back for the next decision, and the task loop checks the answer against the goal.

Two loops: the tool loop inside, the task loop around it
the goal + a success test model picks a tool, or answers tool call tool acts on a system real result from the real system the tool loop the result feeds the next decision no tool call the answer success test meets the goal? the task loop fails, another pass stop rule: a cap on passes passes done

Each turn the model chooses: call a tool, or answer. A tool call sends a real result back for the next decision, and that cycle is the tool loop. An answer leaves it, and the task loop takes over: the success test checks the answer against the goal, and it passes to done or returns for another pass. The green dot marks the model-call step, re-entered every pass, where the branch is decided. The success test is a plain box and the stop rule a code-owned cap: both are code, not the model.

The agent loop is two loops. The tool loop alternates model calls and tool results until the model answers, and it is standard machinery: an SDK can run it for you, or you can run it yourself against the API. The task loop sits above it, and that is the engineered one: the goal, what done means, the checks along the way, and the bound.

All four of those live in one file, written before the work starts: the goal as stated, then numbered sub-goals, each carrying the check that would prove it false. The loop climbs against that file and closes a sub-goal only on evidence. What follows is how to write one so it holds up under a run that would rather be finished.

  • freeze the goal Freeze the stated goal verbatim before writing a single sub-goal. Everything downstream optimizes toward whatever the goal says, so a paraphrase means the run spends itself optimizing the paraphrase. Frozen in a field nothing may rewrite, softening shows up as a diff instead of a feeling.
    the substitution a frozen line catches
    stated_goal: |
      make the nightly report land in my inbox before I start work
    
    wanted to close on:  "report job rescheduled to 05:00"
    against the goal:    not the same claim. the job takes three
                         hours. reopened.
    
  • name the check Give every sub-goal the check that would prove it false, on the same line. A sub-goal with no named check negotiates its own standard at closing time, and the standard always drops. Written next to it, the spec stops describing the test suite and becomes one.
    a sub-goal carrying its own falsifier
    - [ ] SUBGOAL-4: every quote in the research file appears
          verbatim in the source it names.
          Check: a script matches each quote against its source;
          an unmatched quote kills the entry.
    
  • name the anti Write at least one sub-goal about what must not happen. A spec of what to build passes cleanly when the build also did three things you did not want, and prose about what is out of scope does not test.
    the same shape, pointed the other way
    - [ ] SUBGOAL-5 [MUST NOT]: no private detail reaches a
          publishable field.
          Check: scan every publishable line for file paths, real
          names, dates. Zero hits.
    
  • quote evidence Close a sub-goal only on evidence you can quote in the same breath. A gate that reads your wording passes on rewording; a gate that reads the actions actually recorded does not.
    real close lines from the run behind this page
    SUBGOAL-3 closed: model line reads "executed=fable-5" on all
                      six run logs
    SUBGOAL-4 closed: 128 of 128 quotes matched their named sources
    SUBGOAL-5 closed: 0 hits, 15 patterns, 384 lines
    
  • never renumber Never renumber a sub-goal. Split it into children and tombstone what you drop. The number is the only stable handle between a run and the record of it, so renumbering breaks every reference at once and silently, and the failure presents as work that vanished rather than an id that moved.
    a split and a tombstone, side by side
    - [ ] SUBGOAL-7.1: umlauts survive the export
    - [ ] SUBGOAL-7.2: the file opens with no import dialog
    - [~] SUBGOAL-9:   [DROPPED, superseded by 7.2]
    
  • unverified When the right check is unavailable, mark it unverified and never substitute a weaker one. The cheap check is always available, which is exactly why it gets reached for the moment the real one breaks. A named third state lets you ship past something unchecked on purpose instead of by accident.
    not passed, not failed, and not quietly closed
    - [ ] SUBGOAL-6 [UNVERIFIED]: renders correctly on a phone.
          The real browser is wedged.
          Not closed. Re-check before deploy.
    
  • state, not todo Between runs this file is the project’s state, not a task list. A task list says what is left and says nothing about what is currently true, while sub-goals plus the checks that closed them answer what the system does right now without reading the code.
    what the file answers between runs
    phase:    complete
    progress: 14/16     closed sub-goals, counted, never a guess
    
    so "add a feature" means "add sub-goals that do not hold yet"
    
My instance One way to build the task loop: a written definition of done, and a claim graph when the work is big enough.

One way to build the task loop, not the only way. A written definition of done fits almost any task; the claim graph is the heavier tool, for work big enough to need it.

Definition of done

Done written down before the work starts, as numbered checks, each naming the tool result that would prove it false, with the evidence kept beside it. The spec of record for one piece of work, and it outlives the session that wrote it. It fits almost any task.

the light, general format

Graph Climbing, a claim-first method

The heavier version, for work whose checks depend on each other: the definition of done becomes a graph, and the loop walks only the ready frontier, the checks whose dependencies are already met. A check stays a candidate until its evidence is reconciled; a gap found later can reopen it and lower the verified count. Not every task needs it.

a claim-first method

INTEGRATION composition How should an agent reach a system it does not already know? Through something that describes itself, so the knowledge lives with the connection instead of in the prompt.
agent app agent app agent app
MCP
a system a system
Describe a system once through MCP, and any client that speaks it can call it. N clients and M systems meet through one hub instead of N×M separate wirings.

MCP, the Model Context Protocol, is an open standard for connecting an agent to external systems: data sources, tools, and workflows, through one contract instead of a custom integration per system. The protocol is stateless as of its 2026-07-28 revision: self-contained requests, capabilities negotiated per request, so a server deploys like any other HTTP workload.

MethodWhere the knowledge livesWhen it fits
the API directly in docs, an SDK, or the context you assemble the system is well known and the call is simple
a command-line tool in the tool, read at run time from its help output a controlled execution environment, broad reach, output you parse
an MCP server in what the server advertises: tools, resources, prompts the integration should be bounded, stable, and reused
  • text out A model emits text. Everything real runs outside it.
  • the axis API, CLI, MCP. Same question each time: where does the knowledge to make the call live.
  • describe once An MCP client can discover and call what any MCP server exposes. N times M wirings become N plus M. With an API or a CLI, each client has to know that interface itself.
  • mcp vs skill MCP carries the how: tools for actions, resources for data, prompts for workflow templates. A skill carries the when, and how calls chain. That is the split drawn today; a working group is drafting skills into MCP itself.
  • the tax A tool the model can always reach sits in its context, costing tokens whether it is called or not.
My instance CLI-first across a trusted host, MCP where an integration is bounded and durable.

One way to make the call, not the only way. The interface follows the scope: a broad operator runtime leans on a CLI, a bounded or shared integration on MCP.

CLI-first, MCP for the bounded, durable ones

My agents are generalist operators in one trusted host, so they reach most systems through typed command-line tools with JSON output, the broadest and fastest substrate. I add MCP where an integration should stay stable and bounded and can carry its own schemas and context. The interface follows the scope.

one answer: CLI-first, MCP where scope demands it

Knowledge lives closest to its trigger. A skill attaches know-how to a situation; a self-describing tool attaches it to the tool call, the tightest trigger there is. MCP absorbs tool-shaped knowledge; skills keep workflow-shaped knowledge.

SKILLS composition When should knowledge load? Only when its relevance triggers. Cold until then.
the model’s goal semantic match load that skill
descriptions, always loaded
  • reviewing a design
  • researching a topic
  • shipping a claim
what loads, and when
  • descriptionalways in context
  • bodyloads only when picked
  • resourcesload as the skill runs
A description says in plain words when its skill applies. The model matches that against what it is trying to do and routes itself to the one that fits, by meaning rather than by a keyword you typed. Only the skill it picks ever loads.
  • routing In a skill-based agent, descriptions are the routing layer; optimize them for routing, not documentation.
  • description decides The agent can pick a skill mid-run from the task in front of it, with no prompt from you at that moment. The description controls that routing: specific enough to match the intent, distinct enough not to misfire on neighbours, tight enough to stay loaded.
  • the contract A skill is a narrow responsibility with explicit inputs, outputs, failure modes, and safety boundaries.
  • no trigger An invariant has no trigger moment, so it cannot be lazily loaded. A rule that must always hold goes where the agent always sees it.
  • the trade Lazy loading buys context and pays in routing risk. Better models change the price, they do not remove the trade.

You loaded this block by triggering it; the rest stayed collapsed until you asked.

The kinds of skill A universal taxonomy: what triggers each kind, what it carries.
KindTriggered byCarries
Integration reading or acting through a specific external system the system’s surface: its commands, auth, and quirks
Operation a recurring procedure with a defined end state the runbook: ordered steps, verification, cleanup
Expertise building, fixing, or diagnosing inside a domain judgment: what good looks like, and the failure modes
Generation an artifact to produce or transform the pipeline from input to finished artifact
Evaluation a claim or artifact needing an independent check the criteria, kept blind to whoever produced it
Orchestration work that should run on another agent or model routing rules: who gets what, how results come back
Method a class of problem, whatever the domain a way of thinking: how to decompose, analyze, synthesize
My instance The same taxonomy, filled with skills I actually run.
  • Integration
    • ├─ GoogleWorkspace the Workspace CLI surface, taught once
    • ├─ Telegram send, read, and thread messages
    • └─ Cloudflare Workers, KV, and DNS from one tool
  • Operation
    • ├─ GitWorkflow commit, review, push, to a clean end
    • ├─ TriggerDevDeploy ship a task to the runner
    • └─ Migrate move a system without losing state
  • Expertise
    • ├─ CreateCLI what a good command-line tool is
    • ├─ Frontend how a page should be built
    • └─ Troubleshooting find why it broke
  • Generation
    • ├─ DocForge turn inputs into a document
    • ├─ VisualExplainer turn an idea into a diagram
    • └─ LogoGenerator turn a brief into a mark
  • Evaluation
    • ├─ autoreview a fresh model reviews the diff
    • ├─ RedTeam break the claim before it ships
    • └─ Evals measure the output against a bar
  • Orchestration
    • ├─ Delegation hand the work to another agent
    • ├─ Council several models weigh in, then decide
    • └─ CodexBridge route a task across to Codex
  • Method
    • ├─ FirstPrinciples deconstruct to axioms
    • ├─ RootCauseAnalysis trace a symptom to its cause
    • └─ SystemsThinking see the whole, not the part

Three of these encode judgment rather than commands: autoreview has a fresh model review the diff before it lands, FirstPrinciples deconstructs a problem to its axioms, Delegation routes work to another model.

Projects

Repositories I built. Each card says what it does and what was measured.

project

audit-grade-rag

A self-hosted question-answering system over a fixed document collection. It rejects answers without supporting passages, verifies each citation against retrieved text, and records the inputs and model version so later runs can expose changes.

inspect
project

industrial-doc-rag

RAG over 497 near-identical MOSFET datasheets, graded on 2,718 questions. Dense retrieval alone finds the right one about two times in three. Fusing in the part number fixes it.

inspect
project

dacs-spec-mcp

A read-only MCP server that lets an agent query an agent-commerce standard by section. It serves a committed index built at a pinned commit, hash-locked so it cannot drift.

inspect
project

managed-agents-research

Five agent patterns on the Claude Agent SDK, from one one-shot agent up to an orchestrator with parallel sub-agents and a plan-execute-reflect flow that splits roles by model cost.

inspect
project

n8n-nodes-utcp-codemode

A published n8n community node that swaps many per-tool model calls for one. Where the agent node grows calls quadratically as the pipeline lengthens, code-mode stays at a single execution.

inspect
project

dokument-extraktor

Messy documents to schema-validated JSON: OCR, model extraction, and a labelled golden corpus to score accuracy against, each number naming its provider and model. The corpus runs the real extraction path, so the score is measured, not asserted.

project

openclaw-hardened

A six-layer prompt-injection defense for a self-hosted AI agent, run as a native plugin across five gateway hooks. The runtime is external and the config auditor is a third-party plugin; my contribution is the hardening.

inspect
project

storj-sno-cluster

An implementation-architecture reference for a Storj storage-node cluster: topology, monitoring, hardening, and an operations runbook. The architecture is the deliverable, with no earnings or runtime claims.

inspect
project

operator-references

Three infrastructure references for solo operators in Germany: storage, compute, and validation. I selected activities where the operator does not hold or manage another person's funds, because custodial work may require financial licensing.

inspect
project

soc-alert-triage

A SIEM alert enters, a scored and MITRE-mapped triage decision comes out. Every threat-intel lookup fires in parallel inside one sandboxed call, so the model reads the result once.

inspect
project

dacs-verify

An independent verifier for an agent-commerce standard. It rebuilds each specified result byte for byte and reports mismatches with the relevant section of the standard. It is read-only and holds no wallet or keys.

inspect
project

voice-agent

A German phone agent for medical practices: booking against a real availability API, emergency detection, call transfer, holiday-aware greetings. 156 tests. It has never run against a live practice.

inspect
project

invoice-parse-agent

Invoice PDFs into structured JSON: text extraction, schema-constrained model output, a low-confidence review queue, and accuracy reported against a small ground-truth corpus rather than asserted.

inspect
project

code-mode-tools

An MCP server that hands any client a sandbox: the model writes TypeScript that chains tool calls, runs once, and returns. Published to npm, forty-four tests.

inspect
project

omniweb-agents

Agents that can read blockchain state but cannot publish a transaction without explicit permission for that action. When an authorized action runs, the system records the request, decision, transaction, and result.

inspect
project

my-dai-cloud-solution

Claude Code as an always-on agent I reach from my own phone: a bridge to the CLI, persistent memory, guardrails, and an agent-to-agent pipeline. 460 tests.

inspect
project

demos-fixnet-operator-kit

The operator layer around an upstream node runtime I did not write: setup, preflight, verification, burn-in, recovery, and a harness that detects a dirty host. No tenant data, no live fleet data.

inspect
project

code-first-n8n

Five POC workflows proving the n8n lifecycle can run without clicking, authored from the terminal. A measured run collapses eleven model calls into one, five times faster.

inspect