DR-008 — Routing, preflight and segregation¶
Converted from
docs/decisions/DR-008-routing-preflight-segregation.mdto MADR (backlog B25). The text is unchanged; its sections are grouped under the MADR headings below, in their original order within each group.
Context¶
1. Browser harnesses talk through the repository; Atul's verbs drive them¶
Rule: no agent asks Atul to carry a prompt to another agent. Everything one harness needs from another is an issue in the right repository, or a row in docs/relay/answers.md for cross-forge notes.
- Each harness has a queue: open issues labelled
for:design,for:codeorfor:test, plus the project label. Each issue body carries the full instruction (see §3), so it can be acted on without chat history. - Atul's verbs work the same everywhere:
| Verb | What the agent does |
|---|---|
| PROCEED | Read rules, heartbeat, answers relay and your queue; do the next items in priority order; report |
| CONTINUE | Carry on with the item in progress |
| STATUS | Report queue, progress, blockers; change nothing |
| HOLD | Stop starting new items; finish safely what is open |
| REDUCE | Do only the top item, smallest safe step |
- An agent that needs nothing from Atul doesn't ask. It reports what it did. Questions for Atul only follow §14 of the agent rules (production, scope, money, compliance, irreversible).
2. Code preflight: split work by complexity and context sensitivity¶
Before any coding, a preflight step reads each lld-ready or bug issue and writes four labels and a routing block:
| Dimension | Values | How it's judged |
|---|---|---|
Complexity cx: |
cx:1 trivial (one file, under 30 lines) · cx:2 small (a few files, clear tests) · cx:3 medium (cross-module, new tests) · cx:4 large or ambiguous (split it first) |
LLD size, files touched, test changes, open questions |
Context ctx: |
ctx:public · ctx:internal · ctx:restricted (credentials, client-data paths, production config, security fixes) |
Paths and data classes the change touches (spec §5B) |
Contract contract: |
yes / no | Changes an API or interface other projects rely on |
Mode mode: |
attended · scheduled · burst | From the three above (DR-007) |
Routing table (initial; tuned from measured results):
| cx | ctx | Mode | Agent and model |
|---|---|---|---|
| 1–2 | public/internal | scheduled | Gemini Flash (API) via mmdep jobs; Flash-Lite for docs-only |
| 3 | public/internal | scheduled or attended | Claude Sonnet (API, scheduled) or the project's ChatGPT agent (attended) |
| 4 | any | attended | Split by Design first; then route the parts |
| any | restricted | attended only | Project agent with Atul present; never a free tier; never a gig worker |
| any | contract: yes | attended | Design reviews the contract change first |
Preflight itself runs on Gemini Flash-Lite (cheap, about one request per issue) and is checked by Claude in batches until its accuracy is measured. A cx:4 is never coded directly.
4. Choosing the model from the issue¶
- Scheduled and burst modes (API): yes, fully automatic. The controller reads
model:and calls that model; the cost goes to the ledger. If the result fails tests twice, it escalates one level (Flash → Sonnet → attended). - Attended browser agents (ChatGPT, Claude chat): an issue can suggest a model, but the agent can't switch its own model from a prompt; the model is chosen in the app when the chat starts. So the suggestion tells Atul (or whoever opens the chat) which project and model to use.
- A second Claude project for lighter work: worth setting up ("MMDEP Coding — Sonnet"), with the coding rules as project instructions. Model choice in Claude is made per conversation in the app, so the project gives the right context and Atul picks Sonnet when starting the chat. I can't switch models for a conversation myself.
5. What I (Claude, Opus, PM chat) keep and what I delegate¶
| Keep (high priority, high complexity) | Delegate to |
|---|---|
| Architecture, specs (0.12 HLD), DRs, cross-project dependencies | — |
| Decisions with Atul; reviewing risky merges, contracts, security changes | — |
| Calibrating preflight and the controller until measured | Controller, once accuracy is known |
| Digests, collector summaries, routine nudges | MMDEP assistant (attended runs) and the Gemini controller |
| Running queued jobs | mmdep jobs (sprint 1) |
Small MMDEP code items (cx:1–2) |
Claude Sonnet project (attended) or the API (scheduled) |
| Test design drafts, failure triage | Test harness on Gemini |
6. Code segregation¶
6a. Two different needs (Atul, 17 Oct 18:36)¶
| Who | Read access | Rule |
|---|---|---|
| Paid AI agents (ChatGPT, Claude, paid APIs) | May read any code in the estate | Scope discipline, not hiding: read only the branch, paths and documents in the issue's scope: block, plus the LLD. Reason: saves their context memory and keeps them focused. Preflight fills scope: from the LLD and a quick code search; the agent asks (in the issue) to widen scope instead of browsing |
| Free AI agents and outside developers | Only what the task needs | Hiding: they get a satellite repository (§7) or a task pack with public or synthetic code only. Never the estate repositories |
Context pack: for scheduled (API) runs, mmdep jobs sends the model only the files listed in scope: (plus the LLD and the contract tests), never the whole repository. This also caps token cost per task.
What GitLab gives (and doesn't)¶
| Control | What it does |
|---|---|
| Project membership and role (Guest, Reporter, Developer, Maintainer) | Controls who can read code. Guests cannot read code in private projects |
| Protected branches | Who may push or merge to main, production and development branches. Does not hide code |
| Merge request approvals, required pipeline | Changes reach protected branches only through reviewed, tested MRs |
| Group structure | Membership inherited per group: put code with different sensitivity in different groups |
So: read segregation = which projects someone can see; branch protection = what they can change.
Immediate plan for GitLab projects (API, MM-Cron, website, sandbox, webapp-sakai)¶
- Protect
mainand production branches: merge by Maintainer (Atul) only, push by nobody, pipeline must pass. - Protect development and staging branches: merge through MRs with a green pipeline; agents as Developers.
- Move credentials and production configuration out of code (security fast lane, under way), so that read access to code no longer exposes secrets.
- Split groups by sensitivity where needed: for example, keep production deployment config in a restricted project only Maintainers can read.
- Give each agent or person its own identity when the access needs differ (bot users or tokens created by Atul). Until then, agents act through Atul's tokens, which is acceptable only because everything they do goes through MRs and protected branches.
GitHub projects (PE, MCRM, MMDEP): branch protection rules and separate repositories per module later, when more coding agents or people join.
7. Satellite repositories (MMCLONE-style) for absolute segregation and outside developers¶
Idea (Atul): for a task, our agent creates a separate repository (a satellite) containing only what the task needs. The developer (gig worker, agency or a restricted agent) works there. Changes are tested by deploying the full code, with the satellite's changes applied, into a test environment like MMCLONE. They never see the full code.
How it would work:
- Design writes the LLD and marks it
satellite: yes. - Our agent creates the satellite repo from a template: the module or files in scope, stubs or contract mocks for everything else, contract tests, a README with the task, and CI that runs the contract tests.
- The developer works on a branch in the satellite and opens an MR there.
- Our private CI (in the main repo) fetches the satellite branch, applies it to the full code, runs the full test suite and deploys to a test environment (MMCLONE-style, one per task or shared). The developer gets the test report and the preview URL, not the code.
- When accepted, our agent brings the change into the main repo as an MR with the usual protections; the satellite is archived and access revoked.
Assessment:
| Pros | Absolute read segregation; per-task access that ends with the task; lets us hire outside developers without exposing the estate; same pattern works for restricted agents and free AI tools (only public or synthetic code in the satellite) |
| Cons | Extracting a clean module is work (coupled legacy code is hard to cut); sync if the main code moves during the task; test environments cost time or money; review of the returned change is still needed |
| Fits best | Self-contained work: a WordPress plugin, a calculator, an API route with a clear contract, a report, UI components |
| Fits poorly | Changes spread across the legacy core (the API app, MM-Cron scripts) |
Trust levels for outside developers (Atul, 17 Oct):
| Level | Who | What they may get |
|---|---|---|
| T0 New | Not yet proven | Only new features or new modules that don't touch the core: a new plugin, calculator, report, UI component or a new API route behind a contract. Satellite repository only |
| T1 Proven | Several accepted tasks, clean reviews | Changes to non-core modules, still in satellites |
| T2 Trusted | Long track record, agreement in place | Core changes through satellites or, case by case, Developer access to a non-restricted project |
Restricted context (ctx:restricted) never goes to an outside developer at any level.
Recommendation: pilot once, on a self-contained item (for example a calculator or a WordPress plugin change), after sprint 1, with an agent playing the outside developer. Measure: time to create the satellite, sync effort, test turnaround. Then decide whether to offer it to gig workers. Build the template and the "apply and deploy" CI job as reusable components (register in DR-007 §3).
Options¶
3. Labels: what we learned, and the alternatives¶
What we tested since 12 Oct: question-atul, ask-<project>, run-job (GitHub), support-test / support-release (GitLab), read by the collector.
| Worked | Didn't work well |
|---|---|
| Collector found every labelled item on both forges (3 questions, 8 support items, PE run-jobs) | No executor: GitLab support items sat 2–4 days untouched |
| Survive outages; readable by any agent with repo access | Labels say "what kind", not "who" or "what state"; closed-loop depends on agents remembering to update |
| Same mechanism on GitLab and GitHub | Naming drifted (run-job vs support-test for the same idea) |
| Cheap: no accounts or paid features needed | Instructions lived partly in comments, so the latest gate was hard to find (PE #337 HOLD was misread by the MMDEP assistant) |
Alternatives considered:
| Option | Pros | Cons |
|---|---|---|
| Labels only (today) | Simple, both forges, free | No owner, no state machine |
| Assignees with a bot user per agent | Clear owner; forge notifications | Needs accounts per agent (Atul creates them); seats may cost on paid tiers |
GitLab scoped labels (state::ready, exclusive) |
One state at a time, enforced | Paid GitLab tier (check before relying on it) |
| Issue boards / GitHub Projects fields | Visual, good for Atul | Another place to keep in sync; agent APIs differ |
| Structured block in the issue body | Full instruction in one place; model and gate explicit; works anywhere | Agents must keep it current |
Recommendation: keep labels for kind, harness and state (one fixed vocabulary across forges, published in docs/registers/labels.md), and add a routing block at the top of every issue body, which is the single source for the current instruction:
mmdep:
for: code # design | code | test
project: api
cx: 2
ctx: internal
contract: no
mode: scheduled # attended | scheduled | burst
model: gemini-flash # suggestion; see §4
gate: "CI green on <exact head>"
state: ready # ready | in-progress | blocked | review | done | hold
by: 2026-10-24
scope: # the only code the agent should read (§6a)
branch: feat/category-flags
paths: [app/routes/category.py, tests/test_category.py]
docs: [docs/lld/LLD-API-012.md]
The controller (or Claude until then) flags any issue whose block says ready for over 48 hours, or whose state contradicts its labels.
Decision¶
8. Decisions for Atul¶
- RTE-1: Repo-based hand-offs with your verbs only (§1), routing block in every issue (§3)?
- PRE-1: Code preflight with the routing table (§2), Gemini Flash-Lite as the classifier, Claude spot-checking until measured?
- CLP-1: Set up a second Claude project for lighter coding (you pick Sonnet when you open a chat there) (§4)?
- SEG-1: GitLab protection plan now (§6, steps 1–5); GitHub later?
- SAT-1: Pilot one satellite repository after sprint 1 (§7)?
Consequences¶
Not stated separately in the original record.