# Ticket #000020 — Capital-cost ledger: tying verifiable AGI to 8-capital queues

**Status:** closed · landed 2026-05-07
**Opened:** 2026-05-07
**Closed:** 2026-05-07
**Scope:** Schema + audit-event tag for a capital-cost ledger that
attributes every state-changing arborist op to one or more of the 8
forms of capital (Living, Material, Financial, Intellectual,
Experiential, Social, Cultural, Spiritual). Connects "patch the
planet" mission to mechanism. Doc + minimal code.
**Audience:** fox + future blackops shifts + downstream operators
running arborist as part of permacomputer infrastructure.
**Hard constraint:** ledger is advisory and additive. Capital-cost
records do NOT enter cache_key, do NOT enter audit_events.event_hash
preimage. Ledger exists in a sibling table; integrity is per-row, not
chained. (Reasoning below.)

---

## 1. Problem statement

BLACKOPS shard codifies the 8 forms of capital (Roland & Landua via
unturf.com/eight-forms-of-capital):

| # | Form | Destroyed by |
|---|---|---|
| 1 | Living | Food deserts, exhausted drivers, poisoned supply chains |
| 2 | Material | Planned obsolescence, deferred maintenance |
| 3 | Financial | Platform rent extraction, O(N²) transaction tax |
| 4 | Intellectual | Paywalls, patent moats, closed algorithms |
| 5 | Experiential | Gig economy churn, no apprenticeship |
| 6 | Social | Algorithmic isolation, surveillance capitalism |
| 7 | Cultural | Monoculture, platform homogenization |
| 8 | Spiritual | Infinite scroll, manufactured urgency |

The shard's stewardship rule:

> Before shipping any feature, ask: which of our 8 capital queues
> does this affect? Does it drain a workaholic to feed a glutton?
> Does it route throughput away from a food desert? Does it grow
> financial capital at the expense of living capital? If yes —
> stop.

arborist's audit chain commits *what happened* (state changes,
falsifications, ε-coverage). It does not commit *what it cost*.
Every cache_key, audit_event, ε-proof, ZK proof, distillation pass,
re-evaluation has a real cost in compute (financial + material +
living capital), storage (material), attention (experiential), and
trust (social). None of those are tracked.

### 1.1 Concrete failure modes today

- **Disclosure cost invisible.** A v7-Local ε-proof at a frontier-
  scale layer reveals all activations. The cost-to-the-querier is
  borne by the operator (storage, network, possibly privacy of the
  user whose query produced those activations). Not measured.
- **Recompute amplification.** A schema bump that invalidates prior
  cache forces re-running every prior query. Compute cost
  (financial + material + living) is real; ledger has no record.
- **Verifier latency tax.** Adding a verifier strategy slows every
  query. Slowed query = experiential capital cost (operator wait
  time). Not surfaced.
- **Capital-blind scheduling.** When two ops both need to run, no
  signal ranks them by total capital cost.

### 1.2 Why an additive sibling, not a fold

If capital-cost records entered audit_events.event_hash, then any
re-estimation of cost (which is empirical and changes with hardware,
energy prices, etc.) would invalidate the audit chain. That's wrong:
the audit chain commits what happened factually. Costs are
empirical attributions, retroactively re-estimable. Sibling table.

---

## 2. Design choices

### 2.1 Cost units

**A. Single normalized unit (e.g., "compute-second-equivalent").**
Simple. Forces every capital form into one scale. Loses
multi-dimensional truth.

**B. Per-capital-form units, with conversion table.** Each capital
form has its own native unit (kWh for material, USD for financial,
person-minutes for living, etc.). Conversion table is published
alongside the ledger.

**C. Per-capital-form units, no conversion.** Eight separate
columns. Operators view each independently.

**Recommendation:** C. Conversion is opinionated and politically
charged (USD-per-kWh, person-minute-per-USD). The ledger should
preserve dimensional truth; downstream tools convert if needed.

### 2.2 Cost estimation source

**A. Hardcoded constants per op type.** Cheap, brittle.

**B. Measured in real time during the op.** Accurate, expensive
(adds instrumentation everywhere).

**C. Estimated post-hoc from op signature + system telemetry.**
Cheaper than B, more accurate than A.

**Recommendation:** Start with A for rough attribution, evolve to C
as instrumentation maturity allows. Document the estimator
function so retroactive re-estimation is possible.

### 2.3 Op categorization

Every state-changing op gets a `capital_profile` declaration:

```python
@dataclass(frozen=True)
class CapitalProfile:
    living: float = 0.0          # person-minutes equivalent
    material: float = 0.0        # kWh equivalent
    financial: float = 0.0       # operator USD equivalent
    intellectual: float = 0.0    # +/- net contribution
    experiential: float = 0.0    # operator wait time minutes
    social: float = 0.0          # +/- trust units (named scale)
    cultural: float = 0.0        # +/- (named scale)
    spiritual: float = 0.0       # +/- (named scale)
```

Initial declarations live alongside the op (e.g., `ingest.py` declares
its profile, `evict.py` declares its profile). Defaults to all-zero
until measured.

### 2.4 Stewardship-rule check

The shard's "if yes — stop" rule could be enforced at policy time:

```yaml
governance_policy:
  stewardship_check:
    enabled: false       # default off; opt-in
    halt_on:
      - "drains_workaholic_feeds_glutton"
      - "routes_away_from_food_desert"
      - "grows_financial_at_expense_of_living"
```

When enabled, ops that hit any halt condition return a
`StewardshipBlocked` error and emit a `stewardship_halt` audit event.
The check runs against the predicted capital_profile of the op
before execution.

---

## 3. Recommendation

Land an additive `capital_ledger` table with 8 columns (one per
capital form), a `capital_profile` decoration on state-changing op
types, a per-op estimator function with hardcoded initial
constants, and a `stewardship_halt` audit-event tag (no event hash
impact — sibling table). Defer the runtime stewardship-check policy
flag to a follow-up; this ticket lays the substrate.

---

## 4. Implementation sketch

### 4.1 Schema

```sql
CREATE TABLE capital_ledger (
  ledger_id INTEGER PRIMARY KEY AUTOINCREMENT,
  audit_event_hash TEXT NOT NULL,     -- foreign key to audit_events
  op_type TEXT NOT NULL,
  living REAL NOT NULL DEFAULT 0,
  material REAL NOT NULL DEFAULT 0,
  financial REAL NOT NULL DEFAULT 0,
  intellectual REAL NOT NULL DEFAULT 0,
  experiential REAL NOT NULL DEFAULT 0,
  social REAL NOT NULL DEFAULT 0,
  cultural REAL NOT NULL DEFAULT 0,
  spiritual REAL NOT NULL DEFAULT 0,
  estimator_version TEXT NOT NULL,
  estimator_inputs_blob BLOB,         -- canonical-JSON of inputs to estimator
  recorded_at TEXT NOT NULL,
  FOREIGN KEY(audit_event_hash) REFERENCES audit_events(event_hash)
);

CREATE INDEX idx_capital_ledger_audit ON capital_ledger(audit_event_hash);
CREATE INDEX idx_capital_ledger_op ON capital_ledger(op_type);
```

### 4.2 Module layout

```
arborist/capital/
├── __init__.py
├── profile.py          # CapitalProfile dataclass + estimator interface
├── estimators/
│   ├── ingest.py
│   ├── distill.py
│   ├── evict.py
│   ├── qa.py
│   └── ... (one per state-changing op type)
└── store.py            # ledger CRUD
```

### 4.3 Wire-up

Each existing state-changing op (`store.append_audit`, `ingest.ingest`,
`distill.runner.distill`, `evict.evict_to_cold`, `qa.runner.ask`)
gets a one-line addition: after writing the audit_event, call
`capital.record(audit_event_hash, op_type, profile)`.

```python
# arborist/store.py — sketch
def append_audit(conn, body, capital_profile=None):
    event = ... # existing append logic
    if capital_profile is not None:
        capital.record(conn, event.event_hash, event.op_type, capital_profile)
    return event
```

`capital_profile` is None-default → existing call sites unchanged
unless they pass it. New call sites pass it. Greenfield landing.

### 4.4 CLI surface

```
arborist capital summary --shards-dir DIR [--since DATE]
arborist capital op-cost --op-type ingest
arborist capital top --form living --limit 10
```

### 4.5 Tests

- Unit: ledger row created when capital_profile passed.
- Unit: ledger row absent when capital_profile None (backward compat).
- Integration: ledger query returns expected per-op-type aggregates
  on a fresh shard.
- Audit chain: `make chain-check-shards` still reports 0 breaks.

### 4.6 Bumps

- New schema (`capital_ledger`). Additive.
- New CLI subcommand `arborist capital`.
- No `cache_key`, `governance_policy_hash`, or audit-chain bumps.

---

## 5. Out of scope

- Stewardship-halt runtime enforcement (`halt_on` policy
  evaluation). Follow-up ticket once ledger is populated and op
  profiles are tuned.
- Conversion tables between capital forms. Politically charged;
  separate discussion.
- Real-time instrumentation (option 2.2 B). Hardcoded constants
  (option 2.2 A) ship first.
- Cross-shard / cross-node ledger aggregation. Per-shard for now.
- Connection to undefect.com factory model DAG. Separate
  visualization concern.

---

## 6. Risks & open questions

- **Estimator drift.** Hardcoded constants will be wrong in detail.
  Mitigation: `estimator_version` field; retroactive re-estimation
  rebuilds ledger rows but keeps audit chain untouched.
- **Capital-form units aren't comparable.** Operators may want
  rolled-up reports. Conversion table is opinionated; defer.
- **Capital-blind ops opt out.** A new op author can pass
  `capital_profile=None` and the ledger stays empty for that op.
  Acceptable as default; v8 governance can promote
  `capital_profile` to required if/when stewardship-halt enforcement
  lands.

---

## 7. Status

**Closed 2026-05-07.** Scope delivered:

- Schema migration `_migrate_capital_ledger` adds `capital_ledger`
  table (8 capital-form columns, op_type, estimator_version,
  estimator_inputs_blob). Sibling table — does NOT enter
  `audit_events.event_hash` preimage.
- Module `arborist.capital`:
  - `profile.py` — `CapitalProfile` dataclass + `profile_for_op`
    estimator dispatch + per-op estimators (ingest, qa, distill).
    `ESTIMATOR_VERSION = "estimator-v1"` global pin.
  - `store.py` — `record(...)` writes one row keyed to an
    audit_event_hash; `summary(...)`, `top_by_form(...)`,
    `op_cost(...)` aggregate reads.
- Wire-up at three op sites:
  - `arborist/ingest.py` — one row per batch, attached to last
    audit event_hash; estimator inputs `doc_count` + `total_bytes`.
  - `arborist/qa/runner.py` — one row per cache-miss QA, attached
    to `providence_write` event; estimator inputs `answer_chars` +
    `llm_seconds`.
  - `arborist/distill/runner.py` — one row per distillation,
    attached to `derive` event; positive intellectual capital.
- CLI: `arborist capital summary|op-cost|top`.
- Tests: `tests/test_capital.py` — 13 cases covering profile
  defaults, estimator dispatch, ledger row write, summary
  aggregation, op-type filter, top-by-form ranking, sibling-table
  invariant (audit chain unaffected by capital writes). All pass;
  full suite 1025 passed, 36 skipped.

Out-of-scope items (deferred to follow-ups):

- Stewardship-halt runtime enforcement (`halt_on` policy
  evaluation). Schema supports it; runtime check is its own ticket
  once op profiles are tuned against real workloads.
- Conversion tables between capital forms.
- Real-time instrumentation (true measurement vs hardcoded
  constants). v1 ships heuristic estimators; v2 will calibrate.
- Cross-shard / cross-node ledger aggregation.
