MMDEP capacity planning engine¶
1. What it does¶
Each cycle (daily, or hourly in idle mode) the engine: 1. works out how much usable capacity each resource has, after risks; 2. matches it to demand by priority; 3. records what actually happened; 4. proposes configuration changes from that experience, for Atul to approve.
It never buys, deletes or switches accounts. Those are budget decisions.
2. Configuration (the only source of behaviour)¶
config/resources.yaml, one entry per resource:
- id: gemini-paid-pe # a resource is an agent, tool, quota or seat
kind: model-api # model-api | chat-seat | coding-agent | ci-minutes | runner | reviewer | human
vendor: google
terms: paid # paid | consumer-training-off | free (vendor data note §4)
data_allowed: internal # public | synthetic | internal (never client)
capacity: {unit: usd, per: month, nominal: 10}
availability: {windows: always, depends_on: none} # or: atul-laptop, atul-present
roles: [shaper, auditor]
fallback_for: [gemini-free-routine]
cost: {per_unit_usd: 1}
risk: # discounts applied to nominal capacity
terms: 0.0 # 0 = no terms risk for this use
limit_volatility: 0.1 # vendor changes limits without notice
dependency: 0.0 # e.g. needs the laptop awake
reserve: 0.0 # share held back (Claude subscription: for Atul and the PM chat)
owner: atul
assumptions: [A-10]
config/projects.yaml: priority weight, repos, roles (lead, coder, reviewer), WIP limit, the data class of its content, and an optional monthly budget.
config/policy.yaml: the authority matrix (MCL §5), working hours, idle-mode switch, caps per run.
3. Usable capacity¶
usable = nominal × (1 − reserve) × availability_factor × (1 − Σ risk discounts)
availability_factor: the share of the cycle the resource can actually run. For example 0.5 for anything that depends on the laptop while Atul travels; 1.0 for vendor clouds.- Risk discounts:
- terms: using a free resource beyond routine work raises this, and the engine refuses the assignment instead;
- limit volatility: observed throttling or limit changes;
- dependency: laptop, a person, or another service;
- data: content class above
data_allowedblocks the assignment entirely; it is not a discount. - Three capacity pools, never mixed for private content:
- paid terms;
- consumer, training off;
- free (routine, non-confidential work only).
4. Demand and allocation¶
- Demand comes from open work items: type, size estimate, required role, data class, and priority score (MCL §6).
- Allocation, each cycle:
- take items by score;
- for each, choose the cheapest resource that has the role, is allowed the item's data class, and still has usable capacity;
- otherwise fall back along
fallback_for; - otherwise park the item (
state:blocked, reason "capacity") and report it. - Constraints always applied:
- one coder per code repo;
- the reviewer from a different vendor than the author;
- the Claude reserve (MCL §7);
- working hours;
- WIP limits.
5. Experience and learning¶
Recorded per assignment (state/ledger.jsonl):
- resource and project;
- planned versus actual units used;
- duration;
- outcome: accepted, rework or rejected;
- throttling or errors;
- waste: abandoned work, duplicates, idle claims.
Computed weekly:
| Metric | Use |
|---|---|
| Actual units per item type and resource | Corrects size estimates |
| Acceptance rate per resource and role (outputs accepted by Atul or the reviewer) | Quality; an ROI proxy |
| Cost per accepted output | ROI per agent (Atul's goal: each agent proves its ROI) |
| Utilisation per resource | Idle capacity versus overload |
| Waiting time per project and state | Where work stalls |
| Waste units (orphans, duplicates, rework) | What management saves |
| Throttle and limit events | Raises the limit-volatility discount |
Configuration proposals: when a metric drifts beyond a threshold set in policy.yaml, the engine writes a proposed change to the YAML as a PR or issue, with the evidence. Examples:
- lower a resource's nominal capacity after repeated throttling;
- move a role's primary to its fallback when acceptance is consistently higher;
- raise a project's WIP limit when its review queue stays empty.
Atul approves or rejects. The engine never edits its own configuration directly.
6. Outputs¶
- The daily capacity table per pool and project: usable, allocated, spare, parked for capacity.
- A weekly ROI and waste report per agent and project.
- Configuration proposals with evidence.
- Assumption rechecks that are due (from the assumptions register).
7. Where it runs¶
Inside MCL: stage S2 (rules and allocation, scripts in GitHub Actions), with S4 (Claude) reviewing exceptions and proposals. It needs no model for the calculation itself.
8. Open points¶
- Units per resource where vendors publish no meter (the Claude subscription, ChatGPT plans): counted as runs per day, calibrated by Atul's weekly reading of the usage pages.
- Size estimates for new item types: start with simple bands (S, M, L), corrected by experience.
- The first thresholds for configuration proposals: set conservatively, so proposals are rare until data accumulates.