Skip to content

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_allowed blocks 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

  1. Demand comes from open work items: type, size estimate, required role, data class, and priority score (MCL §6).
  2. Allocation, each cycle:
  3. take items by score;
  4. for each, choose the cheapest resource that has the role, is allowed the item's data class, and still has usable capacity;
  5. otherwise fall back along fallback_for;
  6. otherwise park the item (state:blocked, reason "capacity") and report it.
  7. Constraints always applied:
  8. one coder per code repo;
  9. the reviewer from a different vendor than the author;
  10. the Claude reserve (MCL §7);
  11. working hours;
  12. 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

  1. 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.
  2. Size estimates for new item types: start with simple bands (S, M, L), corrected by experience.
  3. The first thresholds for configuration proposals: set conservatively, so proposals are rare until data accumulates.