Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save parolkar/81a6f4cbae86600a5a61fd6b3cf879d3 to your computer and use it in GitHub Desktop.

Select an option

Save parolkar/81a6f4cbae86600a5a61fd6b3cf879d3 to your computer and use it in GitHub Desktop.
Cost Model for incremental change in Rails based apps via FOSM-rails

The Big Idea: Why the Cost of Change Is Finally Measurable

The Structural Prerequisite: FOSM via fosm-rails

Everything in this gem rests on one foundational constraint: FOSM (Finite Object State Machine) — the discipline of building business software as a finite set of objects, each governed by an explicit lifecycle of states, events, guards, and side effects.

Without FOSM, a codebase is an unbounded wilderness. "Add a feature" could mean anything — touch any file, introduce any abstraction, create any dependency. Estimation in that world is guesswork. Every software estimate in history that was wildly wrong was wrong because the change space was unbounded and unknowable.

FOSM changes this. When business software is modelled as a finite set of objects with explicit lifecycles, the universe of possible changes becomes enumerable. Every change to the system maps to one or more typed primitives:

  • Add a state to an object's lifecycle
  • Add a transition between states
  • Add a guard that controls who can trigger a transition
  • Add a field to an object
  • Add a relationship between objects
  • Add a side effect when a transition fires

There are roughly 30 of these primitives. That's it. The entire change space of a FOSM application is a combination of these building blocks. This is what makes cost estimation programmable rather than subjective — the same structural discipline that makes the software evolvable also makes the evolution measurable.

This is not a coincidence. FOSM constrains development to evolve aligned with business processes and their rate of change. A business doesn't change randomly — it evolves through structured process changes (new approval stages, new compliance rules, new integrations). FOSM mirrors this structure in code, and the cost model mirrors it in economics.


The Compounding Intelligence: Git History as a Cost-of-Change Model

Here is the real breakthrough.

Every commit in a FOSM-instrumented repository carries a Cost-Primitive: trailer — a structured declaration of what type of change was made, to which business object, for which ticket. Over time, this transforms the git history from a log of "what happened" into a living, self-calibrating cost-of-change model.

Consider what accumulates in the git history of a FOSM application after 6 months, after 2 years, after 5 years:

  • "Adding a state to Invoice averaged 12 WU across 47 instances"
  • "Integration primitives on the Payment object cost 2.3× more than on Contact"
  • "The codebase health multiplier has drifted from 1.0 to 1.4 as complexity grew"
  • "Spike-complexity tasks on the Order module now take 3× the base WU — up from 2×"

This is compounding intelligence — domain-specific, repository-local knowledge about the true cost of change for this business, this subdivision, this codebase. It cannot be transferred from one company to another because it encodes the unique structural complexity, team velocity, and accumulated technical decisions of that specific system.

This is the aha moment: why did changing a search button label take 1 minute when Google was a startup, and why could the same change take months now?

It's not because the button is harder to find. It's because the button now exists inside a system with:

  • Internationalization across 100+ languages
  • A/B testing infrastructure with statistical significance requirements
  • Accessibility compliance across 12 regulatory frameworks
  • Performance budgets measured in milliseconds across 4 billion users
  • Legal review for trademark implications in 190 countries
  • Design system consistency checks across 400+ surfaces

The FOSM cost model captures this complexity evolution automatically. Early in a repository's life, VIEW_MODIFY might average 5 WU. Three years later, the same primitive on the same object might average 35 WU — not because the team got slower, but because the system got more complex. The calibration tracks this drift, and the health scorer quantifies it.

The git history becomes the economic memory of the codebase. Every shipped feature teaches the system what things actually cost in this specific context. No other estimation approach has this property — story points reset every sprint, hourly estimates come from gut feel, and AI-generated estimates have no memory of your codebase's unique complexity profile.


The Effort-Cost Separation: Work Units and Billing Multipliers

With the structural foundation (FOSM) and the intelligence layer (git-calibrated cost model) in place, the billing model can finally be honest about something the industry has always conflated: effort is not cost.

The Problem with Direct Pricing

Traditional billing maps effort directly to money: 1 hour = $150. This worked when all effort was human. But when AI enters the picture, direct pricing creates a perverse incentive.

If the client sees:

Human coding:  30 minutes × 1.5 credits × $16.67/credit = $750
AI coding:     30 operations × 0.5 credits × $16.67/credit = $250

They will inevitably say: "Why am I paying $750 for a human when the AI can do it for $250?" — and push every task toward AI, including tasks where human judgment is critical (code review, architecture decisions, security audits). The pricing structure accidentally devalues the most important work.

The Solution: Two Layers

Layer 1: Work Units (WU) — measure effort, perception-neutral.

Work Units are like story points in Agile. They measure relative effort contribution, not dollar value. When a human codes for 30 minutes and an AI performs 30 operations, and both contributed meaningfully to the outcome:

Human: 30 WU
AI:    30 WU
Total: 60 WU — equal effort contribution

The client sees a 50/50 effort split. Neither worker type looks "expensive" or "cheap." The WU rate varies by task type (architecture earns more WU/minute than operations work) and by complexity (Hard = 1.5×, Spike = 2.0×), but it does not vary by whether the worker is human or AI.

Layer 2: Billing Multiplier — converts WU to dollars at invoice time.

Each worker type has a dollar-per-WU rate that reflects the real economic cost of that type of labour:

Worker Kind $/WU Why
Senior PM $12.00 Scarce expertise, prevents building the wrong thing
PM $8.00 Coordination and requirement clarity
Senior Engineer $10.00 Architecture and judgment prevent 10× downstream cost
Engineer $6.00 Implementation under guidance
AI Code Agent $1.00 Compute is cheap, scales infinitely
AI Review Agent $0.75 Moderate model cost
AI Test/Deploy Agent $0.50 Cheapest compute tier

The invoice then reads:

Human:  30 WU × $10.00/WU = $300
AI:     30 WU × $1.00/WU  = $30
Total:  $330

The client understands: equal effort, different cost per unit — because human time is scarce and AI compute is abundant. They don't push human work to AI because the effort receipt shows comparable contribution. The dollar difference is understood as an economic reality, not a value judgment.

The Uber Analogy

Distance is distance whether you're in an UberX or an Uber Black. The same 12 km trip is the same 12 km regardless of vehicle class. The price per kilometre differs — but the distance (effort) is the same.

Work Units are the distance. The billing multiplier is the vehicle class.


The Complexity Scale: Normal / Hard / Spike

When a developer picks up a task, they don't calculate Work Units. The FOSM decomposition already provides a base WU estimate from the calibrated primitive catalog. The developer's only job is to flag the difficulty:

Level Multiplier When to Use
Normal 1.0× "Straightforward — I've done this before"
Hard 1.5× "Edge cases, unclear requirements, or messy code area"
Spike 2.0× "Never done this — requires research and experimentation"

One tap. Zero cognitive load. The system handles the math.

Why only three levels? More options create decision paralysis. And the calibration system will learn the actual effort over time regardless — the complexity flag is a quick directional signal, not a precise measurement.


Task Types: Not Just Engineering

Software delivery involves more than coding. The task type system recognises four groups of work:

Product Management (8 types)

Discovery, requirement definition, prioritization, scope negotiation, acceptance testing, client communication, stakeholder alignment, sprint planning.

PM work is often the highest-WU-per-minute work because it has the most leverage. A 30-minute scope negotiation that saves 500 WU of engineering is worth premium WU rates.

Engineering (9 types)

Coding, code review, prompt engineering, testing, UI/frontend, integration, deployment, architecture, debugging.

Architecture and code review earn premium WU rates because they have outsized impact — a 20-minute design decision can prevent a week of refactoring.

Cross-Role (6 types)

Advisory calls, alignment calls, training (conducting), training (attending), operations, pair sessions (Human+AI).

Training (attending) and operations are non-billable by default — they're internal costs, not client-facing work.

AI (5 types)

Code generation, AI code review, AI testing, AI deployment, AI research.

AI task types earn comparable WU per operation because the effort contribution is real — the dollar difference comes from the billing multiplier, not the WU rate.


How the Gem Implements This

The Estimation Pipeline

Feature Request
     ↓
OntologyScanner — reads the FOSM universe (objects, states, events, fields)
     ↓
Decomposer — breaks the request into typed primitives (STATE_ADD + EVENT_ADD + ...)
     ↓
Estimator — prices each primitive from the calibrated catalog, applies health multiplier
     ↓
Developer taps Normal/Hard/Spike
     ↓
CostEstimate created — "~58 WU, confidence 72%"

The Tracking Pipeline

Developer starts clock → WorkSession begins
     ↓
proofofpresence middleware activates (keyboard/mouse/camera attestation)
     ↓
AI usage auto-correlated to the session (tokens tracked via ModelPricing)
     ↓
Developer stops clock → presence attestation finalized
     ↓
Git commit with Cost-Primitive trailer → CostCommit recorded
     ↓
CostActual recorded → Calibrator adjusts the primitive catalog

The Billing Pipeline

Feature ships → CostActual recorded
     ↓
Each work session line item:
  WU = wu_per_unit × units × complexity_multiplier
  Dollars = WU × worker_type.billing_multiplier_usd
     ↓
DeliveryReceipt generated (the "Uber receipt")
     ↓
Invoice: Σ(Dollars per line item)

The Calibration Loop

Shipped feature → actual WU recorded → Calibrator runs
     ↓
Incremental: EMA (new = old × 0.8 + actual × 0.2)
     ↓
Periodic: Trimmed mean across all actuals (removes outliers)
     ↓
CostPrimitive catalog updated → next estimate is more accurate
     ↓
HealthScorer adjusts codebase multiplier (test coverage, accuracy drift, complexity)

Every shipped feature makes the next estimate better. The system requires no manual calibration — it learns from its own history, compounding intelligence with every commit.


The Delivery Receipt

The client sees an "Uber receipt" for every shipped feature:

┌──────────────────────────────────────────────────────────────┐
│                     DELIVERY RECEIPT                         │
│                                                              │
│  #347  Add disputed state to Invoice                         │
│                                                              │
│  JOURNEY                                                     │
│  Reported     Apr 01, 2026                                   │
│       ↓                                                      │
│  Delivered    Apr 03, 2026                                   │
│  Duration     2d 4h                                          │
│                                                              │
│  EFFORT                                                      │
│  Senior PM     × Discovery          30 min × 1.5  = 45 WU   │
│  Senior Eng    × Coding             40 min × 1.0  = 40 WU   │
│  Senior Eng    × Review             15 min × 1.5  = 22 WU   │
│  AI Coder      × Code Generation    20 ops × 1.0  = 20 WU   │
│  AI Runner     × Testing             8 ops × 1.0  =  8 WU   │
│                                                              │
│  TOTAL EFFORT  135 WU                                        │
│  Human: 107 WU (79%)    AI: 28 WU (21%)                     │
│                                                              │
│  BILLING                                                     │
│  Human WU: 107 × $10.40 avg  = $1,112.80                    │
│  AI WU:     28 × $0.88 avg   = $24.64                       │
│  TOTAL                         $1,137.44                     │
│                                                              │
│  Codebase health: 72/100 (1.28× multiplier)                 │
│  Estimate accuracy: 93%                                      │
│                                                              │
│  Complexity: Normal                                          │
│  Git: 6 commits, +142 / -38 lines, 2 contributors           │
│  Attestation: SHA-256 a7f3c2...                              │
└──────────────────────────────────────────────────────────────┘

Point A (Reported) → Point B (Delivered). Effort breakdown. Dollar conversion. Verifiable attestation. Every line item traceable to a git commit with a Cost-Primitive trailer.


Why This Changes Everything

The conventional wisdom in software estimation is that "estimates are always wrong." This is true — when the change space is unbounded and there is no feedback loop.

FOSM + git-instrumented cost tracking changes both conditions:

  1. The change space is bounded. Every modification maps to one of ~30 typed primitives. Estimation is classification, not imagination.

  2. The feedback loop is automatic. Every shipped feature feeds actual WU back into the catalog. The system self-corrects with every commit.

  3. The intelligence compounds locally. The git history of this repository, for this business, encoding this team's velocity against this codebase's complexity — that's knowledge no external benchmark can provide.

  4. Effort and cost are separated. Clients see contribution without price distortion. Human judgment is valued for its leverage, not penalised for its cost.

The result: a cost model that starts with reasonable defaults on day one and becomes statistically precise over months — not because someone calibrated it manually, but because the development workflow itself produces the calibration data as a byproduct of building software.

That is the big idea.


Quick Reference

Key Formulas

WU = wu_per_unit × units × complexity_multiplier
Dollars = WU × worker_type.billing_multiplier_usd
Total Invoice = Σ(Dollars per line item)
Calibration (incremental) = old_wu × 0.8 + actual_wu × 0.2
Health multiplier = 2.0 − (health_score / 100), clamped [1.0, 2.0]

Worker Types

Code Kind Label $/WU
pm_senior human Senior Product Manager $12.00
pm human Product Manager $8.00
human_senior human Senior Engineer $10.00
human_junior human Engineer $6.00
ai_coder ai AI Code Agent $1.00
ai_reviewer ai AI Review Agent $0.75
ai_runner ai AI Test & Deploy Agent $0.50

Complexity Scale

Level Multiplier When
Normal 1.0× Straightforward, done it before
Hard 1.5× Edge cases, unclear requirements, messy code
Spike 2.0× Never done this, requires research

Primitive Categories

Category Examples Typical Base WU
Object New FOSM object, Retire object 40–80
State Add/remove/rename state 5–15
Event Add/remove/modify transition 8–12
Guard Add/modify/remove business rule 3–10
Side Effect Add/modify/remove automated action 5–15
Field Add/remove/modify data attribute 3–8
Relationship Add/remove/modify association 12–25
View New page, modify UI, new component 15–35
Integration Webhook, API endpoint, external service 15–80
Policy Add/modify access control rule 6–8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment