Skip to content

MMDEP Orchestrator Design

MMDEP runs projects with a mix of AI agents and people, where nobody waits on anybody: work is queued, pulled when someone is free, checked before it counts, and recorded in one ledger. Safety comes from what the system cannot do (credentials, accounts, protected branches), not from agents behaving well. This is a living design; each iteration updates it.

0. Change log

Version Date Change
0.11 2026-10-05 Approved (#71): experiment E1 (GitLab issues as the task envelope) resolved by DR-002: the forge is the shared bus between agents and MMDEP the conductor; MMDEP items stay for approvals, local-only work and anything that must not be on a forge; tried first on two sandbox repositories (FB1) (§19). DR-003 (controller hosting) is recorded in docs/decisions/; it changes no spec text now, and its amendment to §3 comes with B2's approve item (atul, #71)
0.10 2026-10-03 Approved (#59), with Atul's answers applied: the desktop writes the mmdep-inbox mirror and Apps Script is read only; no silent coding fallback; the dependency split; the H1 flags (atul: #58's reject and the decisions of 3 Oct). Four golden rules open §2: facilitator not regulator; existing tools first; repository = content and MMDEP = coordination, each linking to the other; reduce waste (harness automation and push communication); principle 11 and §1 reconciled with rule 3. §1 restated: nine objectives; this orchestrator is TEM's coordination implementation (D1), with governance and TEM issues staying in GitLab. Estate knowledge lives in the GitLab MMDEP governance repo (D2, #47) (§10, §12A, §14A); registries, one source each (D3, §14A); documents build on GitLab's Cross-Project Knowledge Governance, and new managed documents get IDs now (D4, §12A). Development phases of the orchestrator itself and the exit criteria from phase 1 (D5 = #56, D6; §9). A triage item type in GitLab's format, and the handover record mapped to GitLab's handoff template (D7; §4, §7). §5C project staffing rule (one lead and one coder per project; handover, never parallel coding). Repository zones (§10). Harness spike H1 (§6). The online view in three gated phases (§15B): phase 1 = Drive snapshots, two candidate views (a Sheet, a Claude artifact board) chosen after a trial, a one-way mirror of items to the private repo mmdep-inbox for ChatGPT's read-only connector, requests pulled into specify items, free plans only; phase 2 = a stateless MCP server with OAuth on Bluehost; phase 3 = AWS serverless when volume, team size or client data justify it. A secrets plan (§11). A readiness gate for the next project (§17.0). A feedback item type (§7). G0 moves to phase 2, G1–G3 to phase 3, the read-only GitHub adapter into iteration 3 (§18)
0.9 2026-10-02 Approved (item #43): online gateway moved to iteration 3, not 5 (atul, 27 Sep) (§7, §15A, §18); snapshot content is a named field allowlist, with redaction as a second line, not the primary control (§15A); a person runs every gateway deploy and no agent holds AWS write credentials for it (§15A); mmdep-gateway targets the MCP SDK's current major version (§15A)
0.8 2026-09-28 Approved (item #41): release discipline installs main via a git+file:// URL, not a plain local path, so the installed commit is recorded (§3; found while verifying item #39's release)
0.1 2026-09-25 First design: principles, agents and roles, task lifecycle, fallbacks and review debt, iterative specs, workspaces, interfaces, billing pilot, phases
0.2 2026-09-26 Workspaces and git: MMDEP origin is the source of truth; anyone may push branches; only MMDEP updates main (item #6)
0.3 2026-09-26 Separate Windows account for agents before billing; protected main on the server long-term (item #11)
0.4 2026-09-27 Merge approval by risk (item #18)
0.7 2026-09-27 Proposed (atul): repository profile note (origin and forge are configuration; local → hosted migration; code-repo vs estate-repo decision record) (§10); document management (three layers, IDs and versions, snapshots with lock files, mmdep docs check) (§12A); TEA estate loop (estate register, metrics, dated monthly and quarterly reports, decision triggers, horizon scan) (§14A); app AI layer for the pilot apps, website and CRM (§17.1)
0.6 2026-09-27 Approved in item #27, with atul's amendments (principle 14 reworded; data classes confirmed) and a note adding the engine type "hosted open model" (§5B). Content: low-risk merges go to an integration branch, so nothing reaches main without a person (§9); the orchestrator stays local and only a small gateway goes online (§3, §15A); a Mac as the local model host, with several Ollama endpoints (§3); routing by engine type (online frontier, hosted open model, local) and data class, plus triggers for local models and extra AI platforms (§5B); no repositories in cloud-synced folders, and exports to Google Drive (§10); pilot suite of four projects (§17). Also added from atul's draft: principles 13–14, §5A tools/platforms/agents/people, §15.7 runbooks and migrations, §15A online gateway, §16A platform decisions
0.5 2026-09-27 Consolidates iteration 1 learnings and the TEM review: positioning against MMDEP/TEA/TEM (§1); state ownership rule (§2, §4); handover, authorization, evidence and lease concepts (§4); task safety mechanisms (§6); identity and guards (§7); agent evaluation and task shaping (§8); runtime/dev separation and release discipline (§3); security model (§11); operations board (§14); forges, credit budgets, automation levels, CI rules and deployment assist (§5, §15); roadmap (§18)

1. Purpose and positioning

What this is. A local orchestrator that coordinates AI agents and people on engineering work: tasks, human items (approvals, questions, inputs, manual steps), agent dispatch, isolated git workspaces, and an audit ledger. It is the coordination implementation of TEM (the Technology Estate Manager of the MMDEP governance repo) (0.10, D1; draft ADR-004).

Objectives (atul, 3 Oct):

  1. Coordination without waiting: work that needs someone is queued for them; nobody blocks on a chat.
  2. One accountable owner per role: every role in every project has one named holder (§5C).
  3. Safety by infrastructure: what must not happen is made impossible by accounts, credentials and protected branches, not by prompts.
  4. Evidence and decision kept apart: outputs are evidence; only a person's recorded decision accepts them.
  5. A full trail: every run, handover, approval and assumption is in the ledger, linked to the repository.
  6. Cross-project visibility and impact: what one project changes, the projects that depend on it learn about.
  7. Cost-effective AI: tools first; models chosen by data class, quality and cost; results per unit of cost measured.
  8. Governance authority in GitLab: standards, ADRs and the registers live in the MMDEP governance repo; this orchestrator follows them.
  9. Staged maturity: each capability moves up a stage only after measured evidence and a gate (§9, §15B).

How it relates to the MoneyMarche programme:

Party Owns Relationship to this orchestrator
MMDEP governance repository (GitLab) Programme requirements, standards, ADRs, the decision register, the Portfolio Register, the estate register and estate reports (D2, D3), authorization records, the TEM issues The authority. This orchestrator follows its standards. Its code never moves into the governance repository (ADR-002); the governance repository links to it.
Project repositories Code, specs, decisions, handovers, project evidence Owners of project truth. The orchestrator works on branches and never owns project conclusions.
TEA (Technology Estate Audit) Authorizing, interpreting and accepting estate evidence Humans decide; the orchestrator never produces findings or acceptance.
TEM-Evidence (collectors, evidence packs, estate dashboard) Read-only estate evidence Separate component. It shares vocabulary, not runtime.
This orchestrator Coordination: tasks, items, approvals, dispatch, workspaces, ledger, role maps, cross-project task impact, messages between agents TEM's coordination implementation (0.10, D1). Code in its own repository (GitHub moneymarche-dev/MMDEP, #47; ADR-005 draft); governance and the TEM issues stay in GitLab.

It is not: a deployer, a production operator, a CMDB, a replacement for GitLab issues/MRs/CI, a regulator, or a decision maker.

Where truth lives (golden rule 3): the repository holds content, and MMDEP holds coordination. Each links to the other, and neither copies the other (§2).

2. Principles

Golden rules (atul, 3 Oct; they come first, and the principles below apply them):

  1. MMDEP is a facilitator, not a regulator. It offers best practices and model processes that evolve from the projects' own experience. It doesn't impose process for its own sake; a rule stays only while it helps the projects.
  2. Existing tools first. GitHub and GitLab features, and other tools, before anything we build. When a tool matches or beats something we built, we evaluate switching, and keep our code as a thin wrapper and fallback.
  3. The repository and MMDEP together are the source of truth.
  4. The repository holds content: code, specs, project decisions, committed handovers.
  5. MMDEP holds coordination: tasks, items, approvals, the ledger, roles, cross-project dependencies, messages.
  6. Each links to the other (an item links its branch and files; a merge commit names its item), and neither copies the other.
  7. Reduce waste. MMDEP's immediate purposes are:
  8. harness automation: start, pause, resume and hand over agent work (§6, story H1);
  9. push communication between agents, alongside the repository, which agents can only pull from.

Principles:

  1. Nobody waits. Work that needs someone becomes an item in their queue; everything else keeps moving.
  2. People pull; agents are dispatched. People act when it suits them; the dispatcher assigns work to agents.
  3. The LLM classifies, code decides. Models may label and draft; plain rules choose agents, check outputs and enforce limits.
  4. Agents and roles are configuration. Models, CLIs, people and roles are registry entries, not code.
  5. Everything leaves a trace. Every run, handoff, fallback, approval and assumption is in the ledger, with the agent's raw output kept.
  6. Specs grow in iterations. Agents ask, or proceed on a logged assumption a person confirms later; never silently guess.
  7. Start simple; add only on evidence. Single-agent mode is the baseline; extra agents, roles or infrastructure must show a measured gain.
  8. Client data stays local by default. Free-tier cloud engines see only synthetic or public data.
  9. Safety by infrastructure, not convention. What an agent must not do is made impossible by credentials, OS accounts and protected branches; conventions and prompts are a second line.
  10. Evidence is not a finding; output is not acceptance. Test results, agent outputs and collected facts are evidence. Only a person's recorded decision makes something accepted.
  11. Each kind of truth has one home, linked, not copied (0.10, golden rule 3). Content lives in the repository; coordination (items, approvals, tasks, the ledger, role maps) lives in MMDEP's database. A decision that changes content lands in the repository through a commit that names its item, and the item links the branch or file. Coordination state isn't rebuildable from repositories (it was claimed so before 0.10), so the database is backed up before every release (§3), and a lost database loses coordination history, not content.
  12. Integrate before building (golden rule 2). Use GitLab and GitHub issues, MRs/PRs, protections and CI where they already do the job; the orchestrator adds only the coordination they lack.
  13. Tools before agents. If a deterministic tool does the job (a linter, a test runner, a scanner, a migration tool, a cloud API), use it. Agents are for judgement and drafting; people are for decisions. AI is used where it adds results, not by default.
  14. Cost-effective and result-oriented. Every workflow is measured by accepted results per unit of cost and elapsed time. Tools first; among models choose by data class, needed quality, then cost; in the current phase development work prefers online models, and local models are used where a trigger applies (§5B).

3. Deployment path and runtime

Stage Orchestrator State store Models Users
Now: test Atul's desktop SQLite file (mmdep_hub/mmdep.db) Ollama on CPU; Claude, Codex, Gemini via CLIs and APIs Atul
Next: team Local team server PostgreSQL Ollama on a Mac model host (see Hardware), possibly several hosts; cloud agents per seat Team on the LAN
Online, alongside either stage Outbound copies, in three gated phases (0.10, §15B): Drive, a Sheet and an issue mirror first; a stateless MCP server next; the AWS gateway (§15A) last Drive and Sheet (phase 1); the gateway's own store (phases 2–3) None People in a browser, on GitHub, and later in Claude/ChatGPT chats: read status, raise requests; never approve

The orchestrator stays local: on the desktop now, and on a team server next. The earlier "hosted orchestrator" stage is dropped. It comes back only if a trigger appears: a distributed team that can't reach the team server, or end users who need more than the gateway offers. Moving it would then need its own decision record (§16A).

Runtime and development copies are separate. Claude Code develops in the repository (mmdep\.venv, editable install). The installed runtime (mmdep_runtime) is what the MCP server and people's commands use. The runtime changes only through an approved release item.

Release discipline (learned from item #14):

  • back up mmdep.db first;
  • install from main only, via a git+file:// URL (e.g. pip install git+file:///C:/Projects/ai-sandbox/mmdep@main) rather than a plain local path — pip only records the installed commit for a VCS URL, and that commit is what mmdep --version and mmdep doctor's runtime-vs-main check report (item #39);
  • install new dependencies explicitly;
  • verify with the full runtime path from a neutral folder, never plain mmdep in a terminal with .venv active;
  • mmdep --version shows version, commit, install location, and runtime-or-dev.

A release command (iteration 3) automates these steps.

Hardware. CPU-only local models take 35 seconds to 22 minutes per call. - Local model host: a Mac. A Mac mini M5 Pro with 64 GB unified memory is recommended. If the same machine also becomes the team server, choose a Mac Studio M5 Max. - Several Ollama hosts are allowed. Each machine is a separate registry endpoint, and the dispatcher spreads tasks across them for throughput. One model is never split across machines. - When to buy: the purchase waits for the evaluation loop (§8) or a local-model trigger (§5B) to show local-model value.

4. Core concepts

Entity What it is Key fields
Project A body of work with its own repository: MMDEP's execution registration (0.10, D3) name, root, priority P1–P4, stage, role map (§5C), risk rules, the Portfolio Register reference (the authoritative product and repository entry in GitLab; a project with no entry there is registered as a sandbox or test project)
Member A person roles per project, agents they may use, availability
Role A job within a project responsibilities, outputs, definition of done, assigned agent, allowed substitutes, review rule
Agent A model, CLI, API or person that can do work kind, runner/account, capability profile (§5), data class, quota, health
Task One unit of work for one role id, project, role, assigned agent, executed-by agent, state, attempts, idempotency key, expires_at, authorization ref (when consequential), spec version, risk, item id, branch
Human item Anything waiting on a person type (approve, review, confirm, specify, input, manual), instructions, links (files, branch:), priority, due, response, responder, channel
Handover The continuity record for a task or assignment Defined in STD-AI-CONT-001 (AI Engineering Continuity and Handover, docs/decisions/gitlab-drafts/AI-Engineering-Continuity-and-Handover-v1.1-amendment.md). Role transfers, work requests, context packs, pointer prompts, session types, seats and commit trailers. Kept in the project repo (content) and linked from the task or item (coordination), readable by any incoming agent without chat history. A takeover handover (§5C) adds the new owner's confirmation.
Authorization record Permission for a consequential action who approved, which workflow, which targets, valid from/until, max runs. Held in MMDEP governance (or an approved item until GitLab integration). Checked by code before each consequential step.
Evidence artifact Output kept for audit kind (agent output, test log, diff, collector output), content hash, collected_at, producer and version, redaction applied
Lease Temporary exclusive right to run on a target target (project/branch), owner (run id), heartbeat, expires_at
Budget A metered resource with a monthly allowance resource (GitLab compute minutes, GitHub Actions minutes, Copilot premium requests, Claude/Codex seat usage, paid API spend), period, allowance, used (from the provider's API where available, else the ledger), reserve for releases, thresholds
Repository profile How a repository may be automated forge (GitLab/GitHub), automation level (§15), protected branches, CI rules profile, deploy method, owner
External change Work that arrived without the orchestrator forge branch/MR/PR, author, channel (desktop git, ChatGPT connector, Copilot, other), linked task if any
Spec A versioned requirements document in the repository version, sections, open questions, assumptions
Ledger entry An append-only record of one event ts, actor, action, project, ref, detail (hashes, not secrets)

Tasks record both the assigned and the executed-by agent, and fallback rules depend on the difference.

5. Agents and roles

The registry (agents.yaml in MMDEP_HOME, falling back to a packaged default) lists agents with an adapter per kind. Every adapter implements run(prompt, workdir) → result and health() → (ok, reason).

Agent Kind Hosting Notes from iteration 1
Claude CLI claude -p Cloud Default model Sonnet (Opus uses the Pro allowance faster); per-seat caps; no --dangerously-skip-permissions
Codex CLI codex exec --sandbox read-only --skip-git-repo-check --ephemeral Cloud Native on Windows; prompt on stdin; reads the answer from the output file
Gemini API Cloud Free tier: 429/503 under load and content may be used to improve products, so synthetic/public data only; paid tier for anything else
Llama 3.1 8B, Llama 3.2 3B Ollama Local Routing and summaries; slow on CPU
DeepSeek Coder 6.7B Ollama Local Produced broken code and a confidently wrong status answer; kept only if the evaluation loop shows value; candidate for replacement
Qwen Coder 1.5B Ollama Local Fallback for tiny scripts only
GitHub Copilot CLI copilot -p Cloud Several models through one subscription; each call consumes premium requests by model multiplier, so it is budgeted (§15)
ChatGPT with forge connectors Hosted, human-relayed Cloud Commits and MRs made online reach the forge directly; they enter the orchestrator as external changes (§15)
Human Human Local Approvals, specifying, inputs, manual steps

As built (iteration 1): the packaged default registry holds claude, chatgpt (Codex placeholder), gemini, deepseek, qwen, llama (3.1 8B) and atul. Llama 3.2 3B, the real Codex adapter (iteration 2), the Copilot CLI and platform adapters (iteration 4) arrive with their stories.

Platform adapters are not agents. glab, gh and the GitLab/GitHub REST APIs perform deterministic operations (read issues, MRs/PRs, pipelines, releases, protections, quotas; open an issue or MR; comment). They sit in the registry as kind platform, with the same health, quota and identity fields as agents, but they never reason or decide. Rules:

  • APIs first, CLIs as fallback. Use the REST/GraphQL APIs through a small forge-neutral interface (same operations for GitLab and GitHub). glab/gh are a convenience and fallback, not the integration.
  • Bot identities, not personal logins. glab/gh on the desktop are logged in as Atul, so anything an agent does through them happens as Atul. Agents use their own tokens: a read-only token (board, audits, reviews), and a bot token that may open issues/MRs/PRs and comment but cannot merge, approve, tag releases or run deploy jobs. People merge and deploy with their own accounts.
  • Write operations are allowlisted per repository profile and recorded in the ledger with the token identity used.

Capability profile per agent: context limit, strengths, speed, cost, data class (may or may not see client data). The router shapes tasks to the profile (§8).

Role maps are per project. They say which agents may act in which role, and which member may use which agent.

The mmdep project's own role map:

Role Held by
Spec owner, approver Atul, through the CLI, the approval desk, or later the web inbox
Architect, developer, documentation Claude Code, run by Atul in the repository, outside the orchestrator
Test runner The orchestrator, plain code, under the agent account
Second-opinion reviewer Codex, or Gemini (paid tier), read-only

The orchestrator assigns no Claude agent to the mmdep project and never writes to its repository.

5A. Tools, agents, platforms and people

MMDEP distinguishes four kinds of worker. The registry records each with its kind, function, cost, credentials and allowed targets.

Kind What it does Decides anything? Examples
Tool A deterministic operation with a predictable result No git, test runners, linters, formatters, security scanners, secret scanners, dependency checkers, migration tools, pandoc, monitoring checks
Platform A deterministic operation on an external service, through its API or CLI No GitLab/GitHub APIs, glab, gh, CI, AWS APIs (read-only by default), Systems Manager
Agent Reads context and drafts: code, reviews, runbooks, summaries, plans Proposes only Claude Code/CLI, Codex CLI, Copilot CLI, Gemini, local Ollama models, ChatGPT with connectors
Person Approves, decides, performs consequential steps Yes Atul, team members, TEA reviewers

Each role is a chain: tools first, then an agent, then a person.

Role Tools (always, cheapest) Agent (where judgement helps) Person (decides)
Developer Formatter, linter, type checker, unit tests Writes and changes code Merges (by risk and automation level)
Reviewer Linters, static analysis and security scanning, secret scanning, dependency audit, test coverage Reviews design, readability, edge cases and anything the tools can't judge Approves
Test runner Test suite, local pipeline replay Explains failures, proposes fixes Accepts results for high-risk work
Deployment CI pipeline; runbooks as versioned scripts; Systems Manager documents (§15.7) Drafts runbooks, collects pre/postflight evidence, compares checksums Performs or approves every server-changing step
Database change Migration tool, dry-run on a copy, backup Drafts migrations and rollback scripts Approves and runs production migrations
Documentation pandoc and the docs build Drafts and updates the manual Reviews
Estate audit (TEA) Collectors, monitoring, cloud read-only APIs Summarises, compares options, drafts recommendations Interprets and decides

A role's tool results are evidence the agent receives as input; the agent doesn't redo what a tool already checked. For example, a code-review agent receives the linter, scanner and test results and reviews only what they can't judge. Adding a tool is preferred to adding an agent whenever a tool can do the job.

5B. Routing by location and data class

Every engine is tagged in the registry with: - its engine type (below); - the data classes it may see.

Engine types (0.6 note):

Type What it is Typical allowed data classes
Online frontier Vendor-hosted frontier models (Claude, ChatGPT/Codex, Gemini, Copilot) Per vendor terms and plan: free tiers public, synthetic; paid, non-training plans may add internal
Hosted open model Open-weight models run by a hosting service. For trials: Hugging Face Inference Providers. For internal data: a dedicated scale-to-zero endpoint, or our own AWS account Inference Providers trials: public, synthetic. Dedicated endpoint or own AWS account: may add internal
Local Models on our own machines (Ollama on the desktop, later the Mac model host) All classes, including client

The allowed classes are set per engine in the registry, not per type. The table shows the usual starting point.

Data classes (confirmed in #27): - public: published or open information; - synthetic: made-up test data, like the pilot suite's; - internal: project code, specs and plans without client data; - client: anything with client identifiers or financial records.

Free-tier online engines get public and synthetic only (principle 8).

Routing rules: 1. The data class is a hard block. A task's data class must be in the engine's allowed classes, or the engine is never chosen, not even as a fallback. If no allowed engine is available, the task parks with a manual item. It is never downgraded to a less protected engine. 2. Now: online first, local fallback where the data class allows it. Online engines are faster and better today, and local engines cover outages and quota limits. 3. Later: some functions become local-only. Each such move is a decision per function (for example, anything that sees client data, or routing and classification when volume makes it cheap locally), taken when a trigger below is met.

Triggers for local models (any one starts a §16A decision record):

Trigger Example
Data Work must process client data that no allowed online engine may see
Regulation A rule or contract requires processing to stay on premises
Volume Online calls for a function cost more per month than a local host amortised, or burn a quota
Quality A local model measures as good as or better than the online one for a function (evaluation loop, §8)
Availability Online outages or quota limits block work repeatedly
Team size More members make per-seat online cost higher than a shared local host

Triggers for adding another AI platform (each goes through the §16A trial): - a measured capability gap in the current platforms; - a second opinion from a different vendor (reviewer role); - availability, when one vendor's outages or limits block work; - better cost per accepted result; - data terms that allow a data class the current platforms don't.

5C. Project staffing rule (0.10; draft ADR-006)

Per project, at any one time:

  • one lead agent: architecture, design and project management;
  • one coding agent: the only agent that writes the project's code. It may be the same agent as the lead.

A second agent joins only:

  • for a read-only review, on request or by a risk rule (§9), with no write access; or
  • for a full takeover: a written handover (§4) that the new owner confirms, and a role-map change made by an approved item. The previous coder stops coding when the takeover is approved.

Every move is a handover, never parallel coding. Atul sets each project's priority and stage. MMDEP proposes reallocations (for example, when a project's coder is idle and a P1 project waits), as items; a person decides.

Read access for dependencies: every other agent may read a project it depends on (for example, Portfolio Engine reads api and mm-crons), never write it.

Enforcement, strongest first:

  1. Forge permissions where the plan allows: GitLab Reporter, GitHub organisation Read, read-only tokens for non-coders.
  2. MMDEP's role map and dispatcher: coding tasks go only to the project's coder; worktree access follows the role (story 11's per-task grant).
  3. AGENTS.md and the agent's context (the second line, as with every convention, principle 9).
  4. Detection: a commit by an agent that isn't the project's coder is an external change (§15.1) and raises an item.

No silent coding fallback (reconciles §8; atul, #59): when the project's coder is unavailable, a coding task doesn't fall back to a different agent. MMDEP raises an item proposing a takeover with a handover, and a person decides. A read-only review may still use another agent, as may other non-coding work (summaries, tests).

6. Task lifecycle and dispatcher

stateDiagram-v2
    [*] --> Backlog
    Backlog --> Ready: dependencies met
    Ready --> Running: lease acquired, agent assigned
    Running --> AwaitingHuman: needs a person (valid output to approve; review after failures; manual when all agents are down)
    Running --> Ready: attempt failed, next agent
    Running --> Done: output valid, no person needed
    AwaitingHuman --> Ready: person approved (merge on next pass) or released a review/manual item (retry)
    AwaitingHuman --> Cancelled: person rejected
    Ready --> Blocked: depends on a parked task
    Blocked --> Ready: that task resolves
    Ready --> AwaitingHuman: expired, never executed (review item returns it to a person)
    Done --> [*]

The dispatcher (mmdep run <project>) makes one pass and never waits on a person. Only the response to the task's linked item moves a task out of AwaitingHuman, and parking always needs a fresh, open item.

Safety mechanisms:

Concern Mechanism Status
One run per target One slot per project; later a lease with heartbeat and expiry Slot: done (iteration 1). Leases: not yet planned (candidate with the iteration 5 dispatcher work)
Crash or interruption A task Running past the 30-minute slot timeout returns to Ready (task.recovered); the worktree is reset before each attempt Done
Hard time limit Wall-clock limit enforced by killing the process (I/O timeouts don't bound total time) Iteration 2
Output validity "No usable change" is a failed attempt; changed files must compile and tests pass before an item is raised; failure falls back to the next allowed agent Iteration 2
Duplicates and staleness Idempotency key per task, unique per project (adding the same request twice returns the existing task); expires_at; expired tasks never execute and return to a person Iteration 2
Kill switch Global and per agent, checked before every step Iteration 2
All agents down Task parks with a manual item giving start instructions Done
Authorization Checked at start and before each consequential step (no consequential actions exist yet) Iteration 5
Subprocesses Every subprocess gets stdin=DEVNULL (Windows MCP hang); a guard test enforces it Done

Harness: start, pause, resume, hand over (0.10, golden rule 4; spike H1). An agent run is a resumable session, not a one-shot call:

  • MMDEP starts a CLI agent in the task's worktree with a fixed tool allowlist and permission mode (for Claude: claude -p --output-format json, explicit --allowedTools, a permission mode, and no permission prompts), and stores the agent's session id on the task.
  • When the agent needs a person, it raises a specify item and stops; the task is AwaitingHuman.
  • When the person answers, MMDEP resumes the same session (--resume <session_id>) with the answer, instead of starting over.
  • The ledger records each relay step and the waiting time (§12).
  • Story H1 proves this on a synthetic sandbox project, two projects in parallel, one slot each. The Claude Agent SDK (interrupts, approval callbacks) is a candidate to replace our subprocess adapter (golden rule 2); H1 notes what it would remove.
  • H1 runs as Atul (the CLI agent's opt-in) on synthetic data only. CLI agents log in under the agent account before any real project.

7. Human interaction and identity

Item types: approve, review, confirm (an assumption), specify (a question), input (data), manual (a step a person performs), feedback (0.10: a remark on how MMDEP itself works, such as a tool, a step or a document, filed from any project into the mmdep project and tagged with the source project; it is closed with done and read at the iteration review), triage (0.10, D7: a finding that may affect another project, in GitLab's triage format: fact → affected project or decision → implication → required action → constraints → MMDEP candidate; it is closed by a person's decision on the action, and one marked an MMDEP candidate is considered for promotion under §12A). The agent that raises an item writes the instructions; the person responds whenever they like. Approvals never default to yes.

Channels:

Channel Who Status
mmdep CLI via the bin\mmdep.cmd launcher (UTF-8, runtime copy) Atul, developers Done
MCP server (stdio), agent identity Claude Code Done
Approval desk: a Claude session with human identity and a permission prompt before every respond/write_spec Atul Iteration 3
Local web inbox (mmdep serve) Everyone, including non-technical staff Later
Online view in phases (read status, raise requests; no approvals) (§15B) Atul, then the team Phase 1 (Drive, Sheet, mmdep-inbox issues) in iteration 3; phases 2 (MCP on Bluehost) and 3 (AWS) after their gates (0.10)

Identity rules:

  1. MCP: identity comes from the client's configuration (MMDEP_ACTOR, MMDEP_ACTOR_KIND), never from what a model says. Agents can raise items and read; only humans can respond or write specs.
  2. CLI (a gap found in iteration 1): the CLI trusted MMDEP_ACTOR, so anyone with a shell could approve. Iteration 2 adds a guard: respond and spec writes are refused for agent identities and non-interactive callers, and the ledger is audited for agent-run responses.
  3. Agents run under a separate OS account with access only to task workspaces (iteration 2), so they can't reach people's credentials or the database.
  4. Agents may run operator commands (register a project, add a task, run a pass) with their own actor name, and must list every command they ran in their report.

8. Fallbacks, review debt and agent evaluation

Circuit breakers: an outage, 503 or quota limit marks an agent unavailable until reset; the dispatcher skips it; a health check reopens it.

Review debt: when the executed-by agent differs from the assigned agent, the assigned agent reviews when available (accept / minor fixes / rework). Low- and medium-risk work merges and is reviewed after; high-risk work waits for review. Substitutes that keep producing rework lose that substitution.

Any allowed agent may get any task (by rule, fallback or availability), except coding tasks, which go only to the project's coder (0.10, §5C). So the system shapes the task to the agent:

  1. Task shaping: the router or Program Manager breaks work into sub-tasks sized to the agent's profile, attaches only the relevant context, and requires a fixed answer format. In the role-chat experiment, a fixed format turned a small model's wrong one-line answer into a structured list.
  2. Model by complexity: the router labels tasks simple or complex; rules map role plus complexity to a model (small local → larger local → cloud).
  3. Evaluation loop: answers are rated by a person or a reviewer model, with scores per agent and task type in the ledger. The outcome is one of: better instructions or examples, narrower tasks, or removal from the role. Fine-tuning only with evidence.

9. Specifications, iterations and approval

Specs live in docs/spec/*.md with a version in front matter. Tasks record the spec version they were built from, and a spec change raises review items for work built from the changed sections.

The iteration cycle:

  1. Plan approved as an item.
  2. Stories on iter-NN/<story> branches, tests first.
  3. Merge approval by risk (below).
  4. Iteration review with ledger numbers.
  5. Release item.

Claude Code writes its end-of-turn status into the iteration file as well as the terminal, listing every command that wrote something.

Merge approval by risk (0.4, item #18; amended in 0.6 so that nothing reaches main without a person). Every story in an approved plan is labelled high or low risk, and the person can change a label when approving the plan.

  • High-risk stories keep their own approval item. The branch merges only after a person approves it. High risk covers the store schema, identity and permissions, isolation, approvals and the inbox, secrets, cloud engines that see project code, and anything touching client data, money or compliance (commission, payout, GST, TDS).
  • Low-risk stories merge into the iteration's integration branch iter-NN/integration, not into main (0.6). A story merges there once all of these hold: the test suites are green, a second-opinion review by a different agent (for example Gemini or Codex) raises no blocking finding, and the merge commit names the review. Low-risk merges are listed at the iteration review, and a person approves them together there. A story rejected at the review is reverted on the integration branch.
  • Nothing reaches main without a person (0.6). main is updated from the integration branch only after that batch approval. High-risk stories still merge into main individually after their own approval. This keeps the TEM Phase 1 non-goal "no autonomous merge approval".
  • No release before the review is approved. Until a second-opinion reviewer is actually available, low-risk stories also keep their own approval item and merge into main like high-risk ones.
  • If a story turns out to touch a high-risk area, it becomes high risk and waits for its own approval.

Development phases of the orchestrator itself (0.10; D5 = #56, D6). These are not the online view's phases (§15B).

  • Development phase 1 (now):
  • only Claude Code, run by Atul, develops mmdep;
  • free plans only;
  • GitHub main is protected by drift detection (doctor flags a GitHub main that doesn't match an MMDEP-approved commit), a local pre-push hook, and PRs merged by Atul in the GitHub UI, because a private repository on GitHub Free doesn't enforce rulesets (#56);
  • the ChatGPT connector gets no write access to the mmdep repository;
  • no bot account yet;
  • projects where ChatGPT or other agents write live on GitLab Free, with a protected main;
  • until the PR flow starts, Atul pushes main to GitHub after each merge.
  • Exit criteria, phase 1 → 2 (D6): all of
  • enforced repository protection (GitLab Free or GitHub Pro, decided then);
  • a PR flow with a second developer agent and a separate reviewer;
  • a generic AGENTS.md alongside CLAUDE.md;
  • the release command (R) and the manual;
  • the readiness gate (§17.0) met, and one test project run end to end.
  • Development phase 2 (Claude freed from mmdep): a bot identity, and a second developer agent working through PRs, under §5C.

10. Workspaces and git

The first six bullets keep the wording approved in items #6 (0.2) and #11 (0.3).

  • Origin: mmdep_hub/repos/<project>.git, a bare repo and the source of truth for the project's main. MMDEP creates it once as a clone of the project's working repo and adds it to that repo as the git remote mmdep.
  • Who writes what: anyone may push branches to the origin. Only MMDEP updates main, and only after an approved item. A hook on the origin refuses pushes to main. People get approved changes with git pull mmdep main and propose their own through a branch and an approval item.
  • Protecting main from agents: while origins are local, the hook doesn't cover local git operations, and agents run as the same Windows user. MMDEP therefore rolls back any change an agent run makes outside its task branch (refs, hook and config are recorded before every run), and refuses to merge if main moved outside MMDEP. Before the billing project starts, agents that run generated code or scripts use a dedicated low-privilege Windows account that can reach only the task workspaces (iteration 2). The long-term enforcement is a protected main branch on the server once origins move to GitLab (iteration 5). Detection and rollback can't prevent a change; the account and the server-side protection do.
  • One worktree per task: mmdep_hub/workspaces/<project>/<task-id>/ on branch task/<task-id>, created from the origin's main, reset before each attempt and removed on close.
  • Approval = merge: the reviewer sees git diff. Approve merges to main with the approver and item number in the commit message. A merge that conflicts leaves main unchanged.
  • Every change can be undone with git revert, and every commit links back to its task.
  • Line endings: the origin normalises CRLF to LF (core.autocrlf=input). This was found when an agent's Windows script made every line look changed; it amends #6, as approved in #9.
  • Cross-project dependencies stay in mmdep_manifest.json. A change merged in one project creates impact-check tasks in the projects that consume it (brought forward to iteration 4 for the pilot suite, §17).
  • No repositories in cloud-synced folders (0.6). Working repos, origins, worktrees and the hub never live in OneDrive, Google Drive, Dropbox or similar folders, because sync clients corrupt git metadata and copy code off the machine. Document exports (status, specs, reports; non-sensitive content only) may be written to a Google Drive folder by the docs build (iteration 3).

  • Repository profile (0.7 proposal). The origin URL and the forge type (local, gitlab or github) are configuration in the project's repository profile (§4), not code.

  • Hub state (mmdep.db, workspaces, evidence) never goes into git.
  • Moving a project from a local origin to a hosted forge is a documented migration: mirror-push the origin to the forge, switch the origin URL in the profile, and keep the local origin as a read-only mirror until the move is proven.
  • Decided (DR-001, #47; 0.10, D2): estate knowledge (standards, ADRs, the decision register, the estate register, estate reports) lives in the GitLab MMDEP governance repo; the orchestrator's code stays in its own repository (GitHub moneymarche-dev/MMDEP for now; ADR-005 draft amends ADR-001 to allow it). Revisit when development phase 2 starts (the protection decision, §9) or when TEM moves repositories.

Repository zones (0.10). Every file belongs to exactly one zone:

Zone What In git?
Source Code, tests, configuration defaults, scripts Yes
Documents Source documents (specs, plans, decisions, handovers, the manual's text) are committed. Generated documents (exports, snapshots, rendered manuals) are rebuilt from source and are not committed, except where §12A says a snapshot is committed with a lock file Source yes; generated no (one stated exception)
Executables Built packages and release artifacts: built by CI or the release command, published with checksums, installed into a separate runtime (mmdep_runtime) Never
Runtime state mmdep.db, workspaces, origins, evidence, agent I/O, test envs, logs Never; lives in MMDEP_HOME, outside any repository

.gitignore enforces the last two for this repository: build/ and *.egg-info/ are ignored, and no commit in any branch has ever tracked them (checked 3 Oct).

11. Security model

Threat Control
Agent approves its own work MCP identity from config; CLI human-only guard; separate agent account; ledger audit
Agent moves main or edits config Agent account can't write the origin's protected refs or MMDEP config; detection and rollback meanwhile
Prompt injection from repo content or items Fetched content is data; agents hold no authority tools; consequential steps are checked by code
Malicious build or test scripts Tests run in task worktrees under the agent account (later, disposable containers)
Secrets in ledger, items or kept output Redaction on write, plus a planted-secret test (iteration 2)
Client data to free-tier engines Data class per engine; role map enforces it
Stale or replayed tasks Idempotency keys, expires_at, leases
Credential creep toward production The orchestrator holds no production-write credentials; deployments only through CI (§15)
localhost exposure MCP over stdio; no tunnels; the online view is outbound-only in every phase, with OAuth sign-in from phase 2 (§15B)
Data to the wrong engine Data class per engine is a hard block in routing (§5B)
Agents acting through personal forge logins (glab/gh as Atul) Bot and read-only tokens for agents; write operations allowlisted per repository profile; token identity in the ledger
Online connector changes bypassing review Protected branches on both forges; every change via MR/PR; external changes recorded and shown on the board
Credit exhaustion blocking releases Budgets with thresholds and a release reserve (§15.2)

Secrets (0.10). Every secret has one home, one owner (Atul), the narrowest scope that works, and a revoke path:

  • Locally: Windows Credential Manager (generic credentials under the person's own profile), read by name at run time, as the agent account's password already is (story 11). This holds the bot token (#58): the mirror's fine-grained token for mmdep-inbox issues, because MMDEP writes the mirror from the desktop (#59). Never in agents.yaml, environment files, scripts or the repository.
  • Apps Script is read only (phase 1; atul, #59). It holds no GitHub token. If a Sheet script ever needs a secret, it goes in Script Properties with the narrowest scope, and only after an approved item.
  • GitHub Actions: Actions secrets, for workflows only. Actions secrets can't be read back through the API, and Actions variables are not secret, so neither is a store MMDEP can read from: a secret that MMDEP itself needs lives in Credential Manager. No code repository's workflow receives the mirror token.
  • Phases 2–3: the gateway's OAuth client secret and the desktop's push key live in the host's secret store (decided with G0 for Bluehost, and with G1 for AWS), never in the web root or a repository.
  • Never in a repository, a Sheet cell, an item, the ledger, logs, kept evidence or a chat. Redaction (iteration 2) is the second line, not the control.
  • A secrets register lists each secret's name, home, scope, owner and rotation date, and holds no values. Rotation is at least yearly, and at once on any suspicion or when a person leaves.
  • Agents never read these stores. mmdep reads only its own named Credential Manager targets; Claude Code and mmdep-agent read none of them.

12. Traceability, evidence and reports

  • Ledger: every event, append-only.
  • Kept evidence: agent raw output (redacted), test logs and diffs as evidence artifacts with hashes.
  • Reports: per iteration, from the ledger:
  • pass rate, rework, fallbacks, time to human response and cost per agent and mode;
  • backlog health and dependency graph;
  • human relay steps and minutes per task, and the waiting time between an agent's question and its resumed session (H1), the measure of whether coordination saves effort.
  • Modes: single:<agent> (baseline), multi, and compare (two agents, a person picks).
  • The benchmark harness is absorbed into the ledger reports.

12A. Document management (0.7 proposal; iteration 5; 0.10 amendments)

It builds on GitLab's Cross-Project Knowledge Governance standard (0.10, D4), rather than replacing it:

  • evidence vs decision: observed behaviour, outputs and findings are evidence; only an accepted rule is a decision (principle 10);
  • the promotion lifecycle: discovery → project documentation → validation → decision review → cross-project reuse assessment → an MMDEP standard, ADR, framework or template. Knowledge stays in the project until it is validated and reusable. A triage item marked "MMDEP candidate" (§7) is the entry point.

Now vs later (0.10):

  • Now: every new managed document gets an ID and a version (S1, STD-CI-001, is the first).
  • First in the accounting test project: a per-project document set and its IDs are defined there first; cross-project referencing comes after it works in one project.
  • Iteration 5: snapshots, lock files and mmdep docs check (below), unchanged.

Three layers, each with an owner:

Layer What Owner Lives in
Estate Programme standards, ADRs and the decision register, the estate register, estate reports, shared templates Programme (Atul) The GitLab MMDEP governance repo (0.10, D2; DR-001, #47)
Project A project's specs, plans, handovers, runbooks The project owner The project's repository
Interface contracts What one project promises another (for example accounting's journal-posting interface, §17) The providing project, reviewed by its consumers The providing project's repository, referenced by consumers

Identity and versions: - Every managed document carries a stable ID and a version in its header (for example id: STD-CI-001, version: 1.2). - References use the ID, not a path or a title. - Legacy documents get an ID when they are next touched; there's no bulk migration.

Snapshots in project repositories: - Each project repository gets a generated snapshot of the estate documents it references, under docs/mmdep/, with a lock file listing id, version and sha256 per document. - The snapshot changes only through an MR, so a project decides when to take a new version of a standard, like a dependency update.

mmdep docs check reports: - stale snapshots, where a newer version exists upstream; - unknown IDs, referenced but not defined anywhere; - the impact of a changed standard: the consumer projects whose lock file pins an older version. It raises an item in each affected project, and a person decides whether and when to update.

13. Interfaces

The CLI, MCP server, approval desk, operations board and future web app are front ends on one core library, so every feature is built once.

Interface Phase
CLI: inbox, show, respond, raise, ledger, projects, agents, task, run Done
CLI additions: --version, doctor (iteration 2); start, status, board, show --open, interactive shell, install-launcher, feedback, report, docs build (iteration 3) Iterations 2–3
MCP (stdio): whoami, projects, inbox, get_item, list_items, raise_item, respond, specs, ledger; then add_task, add_backlog_item, export_docs Done / iteration 3
Role chat (from the playground prototype) with refer Iteration 4
Local web app (mmdep serve) and desktop tray Later

14. Operations board and dashboards

Operations board (this orchestrator):

  • Per agent: up/down, last success, quota state, recent failure and rework rate.
  • Per repository (GitLab and GitHub): automation level, last pipeline result, CI availability (including quota exhaustion), open items and MRs/PRs, external changes, last release, settings drift.
  • Per budget: allowance, used, projected month-end, release reserve.

Data comes from health checks, the ledger and the GitLab API, read-only. It starts as a terminal and static HTML view (iteration 3), then moves into the web app.

The estate status dashboard belongs to TEM-Evidence, not here. It shows every service's active/inactive state, performance, deployed revision, evidence freshness and TEA findings. Live status comes from adopted monitoring tools; scheduled audits come from collectors. The orchestrator may link to it and raise items from its alerts.

14A. TEA estate loop (0.7 proposal; iteration 5)

This is the recurring loop that keeps the programme's technology estate visible and its decisions fresh. The orchestrator gathers facts and drafts; TEA and the owner interpret and decide (§1).

Registries, one source each (0.10, D3):

Register Holds Home Authority
Portfolio Register Products and their repositories GitLab MMDEP governance repo Authoritative
MMDEP projects table Execution registration: role map, priority, stage, origin, test command This orchestrator References the Portfolio Register entry; never redefines a product
Estate register Forges, AI subscriptions, accounts, hosting, each with owner, cost and renewal date GitLab MMDEP governance repo, as a minimal markdown table, started now (Atul's) Authoritative; MMDEP reads it later (iteration 5)

Declared product-to-product dependencies are the Portfolio Register's; MMDEP's manifest holds the execution-level links that create impact tasks (§10), and points at the register entry (ADR-002 reconciled with golden rule 3; accepted in #59).

Estate register: every resource with its owner, cost, capacity and renewal date. Examples: forges and CI minutes, AI subscriptions and seats, cloud accounts, domains, hosting, model hosts, runners.

Automatic metrics: - from the ledger: runs, pass and rework rates, fallbacks, human response time; - from budgets (§15.2): tokens, credits and cost per engine and per project, compared with provider usage figures where an API exists.

Reports: - a monthly estate report; - a quarterly technology review.

Both are saved dated and never overwritten under estate/reports/ (for example estate/reports/2026-10-estate.md), in the GitLab MMDEP governance repo (0.10, D2). MMDEP drafts them; a person commits them there through an MR.

Decision triggers: each report evaluates the revisit triggers of every decision record (§16A) and the local-model and platform triggers (§5B). For each trigger that is met: - if the decision record already specifies the action, an implementation item is raised; - otherwise a discovery item is raised: research the options and draft a decision record.

A person approves either kind; nothing is bought, changed or cancelled by the loop itself.

Monthly model and price horizon scan: new models, price changes, plan and terms changes for the engines in the registry and for candidates. The results go into the monthly report as proposals, marked for verification. Pricing and terms are always verified by a person before a decision uses them.

15. Forges, credits, CI and deployment

15.1 How work actually reaches the forges today

  • Desktop: normal git commits and pushes (Claude Code, people).
  • Online: ChatGPT through its GitLab and GitHub connectors, committing and opening MRs/PRs directly.
  • Two forges: GitLab (legacy projects, governance) and GitHub (newer projects: this orchestrator and Portfolio Engine; ADR-005 draft). Free plans only for now; a private repository on GitHub Free doesn't enforce branch protection or rulesets (#56), so there main is guarded by drift detection and convention (§9).
  • Deployment: mostly through CI. The manual path is: prepare a release in the repository, download its artifacts, copy them to the server, and follow the CI pipeline's steps by hand.

Design rule: the forge is the meeting point. Whatever the channel, every change arrives as a branch plus an MR/PR; nobody commits to protected branches (enforced by the forge, not by agreement). The orchestrator reads forge activity through the platform adapters and records work that didn't go through it as external changes, linked to a task where a commit trailer allows it (MMDEP-Task: <id>, Agent: <name>). ChatGPT-connector work is then visible in the ledger and on the board, instead of invisible.

15.2 Credit budgets

Copilot premium requests, GitLab compute minutes, GitHub Actions minutes and AI seat usage are all budgets (§4). Rules:

  1. Every metered call checks its budget first. The dispatcher prefers free or local resources for routine work and spends credits where they add most value.
  2. Thresholds per budget: at 70% an item warns Atul; at 90% only P1 work and releases may spend; the release reserve is never used for routine runs.
  3. Consumption is recorded per call (ledger), reconciled monthly against the provider's own usage figures where an API exists.
  4. The operations board shows each budget: allowance, used, projected month-end.

15.3 Automation levels per repository

Level For Agents may Merges Deploys
L0 Legacy Legacy applications and their branches Open MRs/PRs, comment, run tests locally Manual only, by a named person; auto-merge disabled Manual only; no automatic deploy jobs; the deploy job (if any) is when: manual on a protected environment
L1 Managed Maintained apps As L0, plus trigger non-deploy pipelines when the budget allows By a person after approval Staging on approval; production manual
L2 Modern New services with good tests As L1 May merge on approval + green pipeline Staging automatic; production manual with approval

The level lives in the repository profile (MMDEP governance data). It is enforced by forge settings (branch protection, auto-merge off, protected environments, required approvals), and the orchestrator checks for drift read-only through the APIs: for example, an L0 repository with auto-merge enabled raises an item.

15.4 CI rules (a standard for project repositories)

The quota was exhausted because every issue produced an MR, and every MR ran tests and deploy. The rules below are proposed for MMDEP's CI standard; each project applies them in its own pipeline files.

  1. Tests run locally first. The orchestrator's Test Runner (or the developer) runs the suite before an MR is marked ready. CI is the confirmation, not the first attempt.
  2. No pipeline on draft MRs; one pipeline when the MR is marked ready; no duplicate branch-plus-MR pipelines.
  3. Run only what changed: path-based rules, so documentation-only changes skip test and build jobs.
  4. Cancel superseded pipelines: interruptible jobs and auto-cancel of redundant pipelines.
  5. Deploy jobs never run on MRs: only on release tags or release branches, always manual, always on a protected environment.
  6. Batch low-risk work: related low-risk issues may share one branch and one MR per iteration (each issue still linked), instead of one MR per issue. High-risk and L0 changes keep one issue per MR.
  7. Heavy and routine jobs run on self-hosted runners where that saves metered minutes (GitLab self-managed runners don't consume compute minutes; GitHub's billing for self-hosted runners changed in 2026, so check the current terms before relying on it).
  8. Scheduled pipelines are budgeted like everything else.

15.5 Fallbacks when CI can't run

In order of preference:

  1. Self-hosted runner. The same pipeline, the same approvals, no metered quota.
  2. Local pipeline replay. The orchestrator runs the pipeline's test and build jobs locally in a container. The result is recorded as local CI evidence, clearly not a CI pass, and never used for a deploy.
  3. Agent-assisted manual deployment (formalises today's manual path):
    1. The runbook is generated from the pipeline's deploy job, so manual steps can't drift from CI.
    2. The release artifact is downloaded from the repository's release, and its checksum recorded.
    3. The agent collects preflight evidence (read-only).
    4. A person performs every step that changes the server, following the runbook, as a manual item.
    5. The agent collects postflight evidence and checks that the deployed artifact's checksum matches the release.
    6. The ledger records who did each step.
  4. Never: an agent deploying with personal or production credentials.

15.6 The orchestrator never deploys

Deployments run in CI, or by a person through 15.5, under the repository's automation level. The orchestrator detects CI outages (board), raises items, prepares runbooks and evidence, and verifies afterwards.

15.7 Server and database changes: from ad-hoc scripts to controlled runbooks

Today: agents write bash scripts, and a person runs them over SSH, for deployments and database updates. No agent has deployed on its own yet. The path to safer operation has four steps, taken one at a time:

  1. Runbooks as code.
    • Agent-written scripts are committed to the repository (a runbooks/ folder) through an MR, not pasted into a terminal.
    • Each script is checked by a shell linter, is idempotent where possible, supports --dry-run, echoes every command, and stops on the first error.
    • A person reviews the MR, then runs the script, and the output is kept as evidence.
  2. Database changes as migrations.
    • Schema and data changes are migration files with a matching rollback, run by a migration tool, never ad-hoc SQL on production.
    • Before production: a backup or snapshot, then a dry-run on a copy or staging, then the same migration on production by a person or the pipeline.
    • Agents get a read-only database user for evidence (row counts, schema checks) and nothing more.
  3. Replace SSH with cloud-native, logged execution (for AWS servers).
    • Instead of open SSH, use AWS Systems Manager: documents as pre-approved, versioned runbooks with parameters, and Session Manager for interactive access.
    • Every run is authorised by IAM and logged centrally (CloudTrail).
    • Agents may prepare a run (choose the document, fill parameters). Execution needs a person's approval, through the tool's own approval flow or an MMDEP authorization record.
  4. Read-only cloud APIs for evidence.
    • A read-only IAM role for collectors and the operations board: instance and service status, Lambda configuration and metrics, costs and quotas.
    • No agent credentials ever carry write permissions in AWS.

Never: an agent holding SSH keys, database write credentials or AWS write permissions for production, and no agent running a server-changing command unattended.

15A. Online gateway (MCP for chat apps)

Goal: let Claude and ChatGPT chats (including this design conversation) see MMDEP status and raise requests, without exposing the desktop or moving the orchestrator online.

What goes online (a small gateway):

Snapshot content is a named field allowlist, not a general export (0.9). The push in step 1 below serializes only the fields named here — nothing else leaves the desktop, even by accident: - project: name, priority, risk default; - inbox item: id, type, title, body text, state, priority, due, age; - status/operations board: agent up/down, last success, quota state, per-repository pipeline and open-item counts, budget allowance/used/projected; - spec: version, status, section text (read only); - ledger: per-iteration summary counts (pass rate, rework, fallbacks, cost), never raw ledger rows.

Redaction (merged in iteration 2, §11) is a second line, applied to every allowed text field before upload — it is not what decides which fields are eligible; the allowlist above is.

Online Stays local
The allowlisted fields above Code, worktrees, agents, the dispatcher, credentials, the full database, raw ledger rows
Write, limited: raise an item, add a comment, submit feedback, draft a spec change as a proposal item Responding to items (approve/reject), merging, releases, anything consequential

How it connects, outbound only:

  1. The local orchestrator pushes a snapshot (status, items, specs, board data) to the gateway every few minutes, over HTTPS with a gateway key.
  2. Requests made in chat (a new item, a comment) are queued on the gateway. The local orchestrator pulls them, checks them, and creates the real items.
  3. The gateway never calls into the desktop, and the desktop opens no ports.

Security:

  • OAuth sign-in is required, because the connector must be reachable from the public internet. Only named people's accounts are allowed.
  • No approval tools online. Decisions stay local, or move online only after identity is proven (Phase 3).
  • Data minimisation: the field allowlist above, plus redaction as a second line (0.9) — no code, no secrets, no client data.
  • A person runs every gateway deploy (0.9). No agent — including this one — ever holds AWS write credentials for the gateway account; this follows the same rule as production deploys generally (§11, §15.7).
  • Rate limits and an audit log on the gateway.
  • Prompt-injection hygiene: everything the gateway returns is data.

Where to host it:

Option Verdict
Bluehost shared hosting Not suitable for this long-running gateway. Shared plans allow 25 concurrent processes and kill processes that run too long. The account also hosts other sites, so a security or resource problem spreads. Phase 2 (0.10, §15B) uses it differently: a stateless MCP server (short requests only), on a separate subdomain or a separate cPanel account, with no WordPress, which answers both objections.
AWS, serverless (API Gateway plus Lambda, with DynamoDB or S3 for the snapshot and queue) Recommended. Nothing to maintain, pay per request (likely very low cost at this volume), IAM-controlled, logs in CloudWatch. Stateless MCP over HTTP fits it.
AWS, a small VM (Lightsail or a small EC2 instance) Good alternative if a long-running process is preferred; needs patching and monitoring. Don't put it on an existing production server.

Timing (0.10): this AWS gateway is phase 3 of the online view (§15B), built when volume, team size or client data justify it, after the phase 2 → 3 gate. G1–G3 move there, and G0 (OAuth research) moves to phase 2. The rest of this section describes that phase.

The gateway is a small separate program (a few hundred lines), with its own repository (mmdep-gateway) and its own tests. Originally planned from iteration 3 (0.9; moved up from iteration 5, atul 27 Sep), now that the CLI human-only guard and secret redaction are merged (both iteration 2). mmdep-gateway targets the MCP SDK's current major version (0.9) — this repository's mcp<2 pin (the "migrate to MCP SDK v2" backlog item, iteration 3b) is a fact about this codebase's own upgrade path, not a reason for a new repository to start on a superseded version.

15B. Online view: deployment phases (0.10 proposal)

The goal is §15A's: people can see MMDEP's status and raise requests from outside the desktop, without exposing the desktop. It is reached in three phases. Each phase starts only when the previous phase's gate is met, and each gate is an approve item with the evidence attached.

Rules for every phase:

  • Outbound only. The desktop pushes copies and pulls requests; it opens no ports, and nothing online calls into it.
  • Content is §15A's field allowlist, with redaction as a second line.
  • No approvals online, in any phase. Responding to items, merging, releasing and spec writes stay local, at a person's own prompt. An "approved" comment on an issue, a Sheet cell, a request file or a chat message means nothing to MMDEP; MMDEP never reads decisions from online sources.
  • Requests are untrusted input. An online request becomes a specify item only after the local orchestrator pulls it, checks it (size limits, a known requester, duplicates) and records the source. Its text is data, never instructions, and it approves nothing.
  • A kill path: stop the push, and revoke the phase's tokens (§11, secrets register).

Phase 1: Drive snapshots, two candidate views, an issue mirror (iteration 3)

Free plans only (GitHub Free, GitLab Free) in this phase. GitHub main protection is by drift detection plus convention (§9, #56).

  • Drive snapshots (story D): mmdep drive publish writes snapshot.json and a markdown summary, snapshot.md, into a Drive for desktop synced folder. Only exports go there, never a repository (§10). Phase 1's allowlist is narrower than §15A's (atul, 3 Oct):
  • items: number, type, title, status, project, priority, created, updated;
  • tasks: id, project, state, title;
  • tests: the last result per project;
  • doctor: a summary (check names and ok/warn/fail);
  • no item bodies until a redaction rule for them is approved. mmdep drive pull turns request files from a Drive requests folder into specify items raised by drive-request (size and type checks; handled files move to processed\ or rejected\).
  • Two views, both kept in the plan; one is chosen after a trial:
  • (a) a Google Sheet with Apps Script views (open items by age and type, per project, the board) and a requests tab. The Sheet holds no secrets.
  • (b) a Claude artifact board, on trial: it reads the snapshots through the viewer's own Drive connector and writes request files into a Drive requests folder. It stores no secrets.
  • Requests back: MMDEP pulls the Sheet's request rows (from the export) or the request files from the synced requests folder, and turns each valid one into a specify item (rules above).
  • A one-way mirror of items to GitHub issues in a separate private repository, mmdep-inbox, which holds no code, so that ChatGPT's read-only GitHub connector can see the inbox. Each open item has one issue with allowlisted, redacted fields, and labels for type and project; it is updated when the item changes and closed when the item closes. Editing or closing an issue changes nothing in MMDEP. MMDEP writes the mirror from the desktop with a fine-grained token scoped to mmdep-inbox issues, from Credential Manager (§11); Apps Script only reads (#59). Issues labelled mmdep-request may become items, read through the read-only GitHub adapter (story GH), under the same rules.
  • Gate 1 → 2: four weeks of reliable read and request flow, with no leaks and no lost items (atul, #58). Evidence (proposed): a snapshot audit finds no field outside the allowlist; every request seen became exactly one item or a recorded rejection; the mirror token's scope is verified.

Phase 2: a stateless MCP server with OAuth on Bluehost

  • A stateless MCP endpoint over HTTPS on a separate subdomain or a separate cPanel account (not the account that hosts the websites), with no WordPress on it. Each request reads the latest pushed snapshot and returns; raised requests are stored for the desktop to pull. Nothing runs long, so shared hosting's process limits (§15A) don't apply in practice.
  • OAuth sign-in for named people only. G0 (OAuth and identity-provider research) belongs to this phase.
  • Tools: read status, items and specs; raise a request. No approval tools.
  • Rate limits and an access log; the push key and the OAuth secret in the host's secret store (§11).
  • Gate 2 → 3: a month on a real project with no security findings (atul, #58), and a trigger below. Evidence (proposed): OAuth verified for named people only, with everyone else refused; rate limits and the access log working; a short security review recorded.

Phase 3: AWS serverless

§15A's AWS serverless gateway, when volume, team size or client data justify it (atul, #58): G1 (the detailed spec), G2 (the local push/pull proven against a fake gateway) and G3 (the mmdep-gateway repository). A person runs every deploy. It replaces phase 2's server once it has passed its own tests and run alongside it for a while.

16. Keeping overhead in check

Cost of MMDEP Against the benefit
Routing time, wasted attempts, quality-gate rejections Cloud cost saved; tasks completed through outages
Human review minutes and relay steps per task Defects caught before merge
Rework from substitute agents Client data kept local
Tooling friction: wrong copy, wrong hub, wrong shell Elapsed time per iteration

Rules:

  • Keyword rules route first; an LLM is used only when they can't decide.
  • An agent with a high rework rate in a role is removed from it.
  • A new agent, role or infrastructure piece needs a stated expected gain, and is dropped after one iteration without it.

16A. Platform and subscription decisions

Some decisions aren't regular, but recur at each stage of product maturity. They should be taken as decision records with evidence, options and a revisit trigger, not by habit.

Examples:

  • Forge hosting and CI capacity:
    • stay within hosted quotas and optimise CI;
    • buy credits (GitHub directly; GitLab through a reseller, since GitLab offers no direct billing in India);
    • add self-hosted runners;
    • self-host GitLab or GitHub;
    • run tools locally.
  • AI platforms: whether to keep, add or drop a subscription (Claude, ChatGPT/Codex, Copilot, Gemini, a local model host); triggers in §5B.
  • Deployment execution: SSH scripts, Systems Manager, or CI-only.

Each decision record contains:

  1. The question and the trigger that raised it.
  2. Evidence from MMDEP/TEM: usage, quota burn rate, cost per accepted change, outages, time lost.
  3. Options with cost (set-up, monthly, maintenance hours), capability, risk and lock-in.
  4. A recommendation, labelled as a proposal.
  5. The decision and its owner.
  6. Revisit triggers. For example, burn rate above 80% for two months, a new product maturity stage, a price change, or a team-size change.

Agents and tools draft; people decide. The orchestrator and TEA produce the evidence and the options; the owner decides; the record is kept in MMDEP governance.

Adding a paid AI platform. Copilot is the current example: it exposes models from several providers through one subscription, with limited premium requests and model multipliers. The same rule applies to any new platform:

  1. A stated purpose it serves better than what's already paid for. For Copilot: GitHub-native work (PR review, issue-to-PR), a second-opinion model from a different vendor, and access to models not otherwise subscribed.
  2. A one-month trial with usage rules: which roles may use it, which models, a monthly premium-request budget, and no client code until its data terms are confirmed.
  3. Measurement in the ledger: accepted results per premium request, compared with the same work on existing platforms.
  4. A decision record at the end: keep with rules, narrow, or drop.

Routing stays in MMDEP, not in any vendor's product. A multi-model platform like Copilot may serve as a secondary gateway to models, but MMDEP's rules decide which agent does what, so vendors stay replaceable.

17. Pilot suite (0.6; replaces the billing pilot)

The first real work is a suite of four separate projects, each with its own repository, spec, role map and risk levels, on synthetic data only:

Project Role in the suite Depends on
Accounting Upstream: chart of accounts and the journal-posting interface —
Billing Commission and brokerage, invoicing; posts journals to accounting Accounting
Expense management Expenses and approvals; posts journals to accounting Accounting
Compliance GST, TDS and other statutory views; reads accounting and billing Accounting, billing

Order and rules: - Accounting's interface contract comes first (chart of accounts, journal-posting interface), before the consumers start building against it. - The dependencies are declared in the manifest, so the dependency checks and impact items (brought forward to iteration 4) catch a breaking change upstream. - The suite starts after iteration 3, with local origins first (#58). Billing's docs/spec/ v0.1 comes from the written billing specification. - Accounting defines the per-project document set and its IDs first (§12A). - Commission, payout, GST and TDS logic are high risk. Regulatory rules come from research and are verified by a person before they enter a spec.

17.0 Readiness gate for the next project (0.10)

The next project (accounting, the suite's first) is registered only when all of these hold. The gate is an approve item listing the evidence for each line:

  1. Story 11 released in required mode: the runtime includes the agent account, agent_account.mode is required, and mmdep doctor shows agent account: ok (required…).
  2. Story 5 and the per-task worktree access list released:
  3. the Test Runner runs the project's tests as mmdep-agent from a test env (mmdep test-env create), and doctor shows test env <project>: ok;
  4. mmdep-agent is granted only the task's own worktree, not the whole workspaces folder (the story 11 follow-up approved in #50).
  5. Project registration: a local origin (mmdep_hub\repos\<project>.git), a role map and a test_command in agents.yaml. Hosted forge origins come later (§10).
  6. One task end to end on the new project: added, dispatched, its tests run as the account, an approve item, merged on the next pass, and the ledger showing each step.
  7. The working method is written down: Claude Code works interactively (run by Atul in the project's repository, on branches, raising items), and MMDEP tracks the work (inbox, tasks, ledger). It is not autonomous dispatch of Claude; the harness (H1) is proven on the synthetic sandbox first. The project's role map follows §5C (proposed).
  8. A feedback item type (§7) exists, so friction found on the new project reaches MMDEP as a record.

Synthetic data only, as before.

17.1 App AI layer (0.7 proposal; with the pilot suite onboarding)

Applies to the pilot apps and the website: - each app talks to AI through its own AI interface, with a provider switch by data class (§5B); - small models do classification and extraction; - tax and accounting logic is deterministic code, never a model's answer; - a person or a rule checks anything before it is posted to the books; - uploaded or received documents are untrusted input: their content is data, never instructions.

Website, three AI needs: 1. Public catalogue Q&A. It answers from the published product catalogue only, with no personal data and no advice. 2. Calculators as tools. The model calls the site's calculators and reports their results; it never computes a figure itself. 3. Logged-in explanations. It explains the outputs of the portfolio engine for that user and nothing beyond them. It doesn't invent recommendations.

CRM helpers: drafting, summarising and next-step suggestions for staff, backed by a versioned knowledge base. Product rules are data (versioned tables), not prompt text, so a rule change is reviewed like any other data change.

Regulatory review: anything that could be read as a recommendation or advice (investments, insurance, loans) needs a regulatory review of the feature, the wording and the disclosures before it goes live. Research marks the relevant rules for a person to verify (§17).

Candidate engines (to be verified before any decision; availability, regions and terms change): - gpt-oss on AWS Bedrock in ap-south-1 (Mumbai), for client data processed in-region under our own AWS account; - Sarvam 30B for Indian-language work; - plus the local and hosted-open options of §5B.

18. Roadmap

Iteration Theme Main contents
1 One task end to end Done: registry, tasks, workspaces, dispatcher, service-down handling, crash recovery, UTF-8 and stdin fixes, release
2 Safe enough for billing Legacy review (story 0), agent account, wall-clock timeout and kept output, output validation, test runner, doctor, version and active hub, CLI human-only guard, kill switch, Codex adapter, idempotency and expiry, secret redaction
3 Online view phase 1 and agent isolation (0.9, plan: item #43; reshaped in 0.10) Story 0 (iteration 2 release baseline); online view phase 1 (§15B, 0.10): Drive snapshots (Drive publishing phase A, no longer after G2), a Sheet with Apps Script views, a Claude artifact board on trial, the one-way issue mirror to mmdep-inbox, requests pulled back as specify items; the harness spike H1 (right after D); a triage item type; the read-only GitHub adapter (moved from iteration 4, 0.10); agent account (story 11, #37) and, after it, the Test Runner (story 5) with per-project test envs; a feedback item type; evidence retention; the release command (using the git+file:// install, item #41); a doctor low-memory warning; the CI standard STD-CI-001; accounting's kickoff docs (PROJECT.md, interface contract v0.1)
Phase 2 (after gate 1 → 2) Online view: stateless MCP on Bluehost (0.10) G0 (OAuth and identity-provider research); the stateless MCP server with OAuth for named people, on its own subdomain and cPanel account (§15B)
Phase 3 (after gate 2 → 3, when volume, team size or client data justify it) Online view: AWS gateway (0.10) G1 (gateway spec), G2 (push/pull against a fake gateway), G3 (mmdep-gateway repository; deploy run by a person) (§15A)
3b Daily operation start/desk, status, operations board v1, show --open, help, shell, launcher installer, per-project identity, add_task, backlog as records, feedback/report, docs build and manual, MCP v2, Drive publishing phases B and C
— Decided (0.10, D1) TEM convergence: this orchestrator is TEM's coordination implementation; ADR-004 drafted for the governance repo
4 Multi-agent quality, forges and the pilot suite Capability profiles, data rule and routing by data class (§5B), task shaping, evaluation loop, model by complexity, circuit breakers, review debt, second-opinion reviews, role chat and refer, ledger reports; forge-neutral platform adapters (GitLab + GitHub APIs, bot and read-only tokens; the read-only GitHub part moved to iteration 3 in 0.10); credit budgets; Copilot CLI adapter; external-change ingestion; automation levels with drift checks; cross-project dependency checks and impact items (from iteration 5); pilot suite onboarding, accounting's contract first; multiple Ollama endpoints; local model evaluation (after the hardware decision)
4b Deployment assist and tool chains Runbook generated from the pipeline's deploy job, artifact checksums, pre/postflight evidence, manual-step items, local pipeline replay; runbooks as code; database migrations with dry-run and backup; tool registry entries and role tool chains (linters, scanners, tests before agents); AWS read-only role
5 Planning, GitLab, authorization, estate and documents Iteration objects, PM grooming, assumptions register, backlog reports, GitLab origins with protected main, authorization records, decision records; TEA estate loop (register, metrics, monthly and quarterly reports, triggers, horizon scan) (§14A); document management (IDs, snapshots, mmdep docs check) (§12A)
Pilot suite First real projects Accounting, billing, expense management, compliance (§17), after iteration 3; accounting's PROJECT.md and interface contract v0.1 start in iteration 3 (S2)
Later Team Team server (desktop → team server), PostgreSQL, members and permissions, runners, web app, tray; the Mac model host when a trigger is met (§5B). A hosted orchestrator only if a trigger appears (§3)

19. Open questions and decisions

  • TEM convergence: decided (0.10, D1). This orchestrator is TEM's coordination implementation. Its code stays in its own repository; governance and the TEM issues stay in GitLab. Open: Atul submits draft ADRs 004–006 (docs/decisions/gitlab-drafts/) to the governance repo as an MR; the TEM issues (#18/#20/#21) are then linked to this spec's sections.
  • GitLab issues as the task envelope (experiment E1): resolved by DR-002 (docs/decisions/DR-002-agent-platforms-and-automation.md, atul, 5 Oct; recorded through its approve item). The forge (GitHub or GitLab issues, labels and PRs) is the shared bus between agents, and MMDEP is the conductor: it defines workflows, enforces roles, budgets and gates, and records every step in the ledger. MMDEP items stay for approvals, local-only work and anything that must not be on a forge. Tried first on two sandbox repositories (iteration 3, FB1). The TEM review's original proposal: structured GitLab issues as the task and handover store, with the local inbox as one backend behind the same interface.
  • Billing spec: share the written specification.
  • Pilot suite: accounting's interface contract (chart of accounts, journal posting) is the first deliverable; confirm who writes accounting's spec v0.1.
  • Risk levels for the pilot suite: confirm the high-risk list (commission, payout, GST, TDS; journal posting in accounting).
  • Review-debt limit: proposed 3 days.
  • Local model host: a Mac mini M5 Pro 64 GB, or a Mac Studio M5 Max if it doubles as the team server. Timing depends on the evaluation loop or a §5B trigger.
  • Data classes: public, synthetic, internal and client are confirmed (#27). Still open: which specific engines may see internal (§5B).
  • Subscription seats: provider terms for automated and shared use.
  • Gemini: paid tier, or keep it for synthetic data only.
  • Automation levels: confirm which repositories and branches are L0 (legacy) and whether any are L2.
  • CI standard: adopt the §15.4 rules in MMDEP's delivery standard, including batching low-risk issues into one MR per iteration.
  • Bot identities: create a GitLab bot account or project access tokens, and a GitHub App or fine-grained tokens, for agent use.
  • Copilot terms: check the Copilot plan's data-use terms before it sees client code.
  • Copilot trial: start a one-month measured trial under §16A, or defer?
  • Forge hosting decision: first decision record under §16A (hosted plus self-hosted runners is the likely starting point, to be tested against the evidence).
  • AWS: create a read-only IAM role for evidence, and evaluate Systems Manager for server changes.
  • Online view (0.10): create the private mmdep-inbox repository and the mirror's issues-only token (Atul's steps); after the trial, choose the Sheet or the artifact board (§15B); for phase 2, a separate subdomain or a separate cPanel account on Bluehost.
  • Harness (0.10, H1): --permission-prompts none (Claude Code v2.1.259+), --output-format json (which returns session_id) and --resume <id> are documented (atul, #59); H1 still checks them against claude --help when it starts; whether the Agent SDK replaces the subprocess adapter is decided from H1's notes (golden rule 2).
  • Cross-project dependencies: decided (#59). Declared product dependencies live in the GitLab Portfolio Register; execution-level impact links live in MMDEP and point at the register (§14A).
  • Repositories and estate knowledge: decided (DR-001, #47; 0.10, D2): estate knowledge in the GitLab MMDEP governance repo, code in its own repository (§10).
  • App AI layer (0.7): verify the candidate engines (gpt-oss on Bedrock ap-south-1, Sarvam 30B) and plan the regulatory review before any recommendation feature (§17.1).