---
title: Effort ledger
summary: "How the development time was split between core capability, verification and logistics: the measured numbers, how they are measured, and how far they can be trusted. The split does not meet the 70 / 25 / 10 target cleanly, and a large part of the record is an estimate."
section: engineering
order: 9
level: 1
audience: [contributors, reviewers]
keywords: [effort, ledger, worklog, time, balance, delegated, uncertainty]
---
<!-- gyre docs: expanded Markdown of engineering/effort-ledger.md (generated tables, verification numbers and chart data are written out). Base level of this page: L1 Essentials; passages at another level are bracketed by 'begin level N' / 'end level N' comments and start with [LN Name]. Built from revision ceb1f4b0be. -->

The project brief asked for the work to be balanced: about **70 %** core capability
development, **25 %** testing and verification, **10 %** development logistics and tooling.
Those targets sum to **105 %**, so they are read here as proportions: 66.7 / 23.8 / 9.5 %.

**What the ledger shows** (snapshot of `devlog/time.jsonl` up to the entry of `2026-11-12T12:07:53-05:00`;
regenerate with `python3 tools/effort_page.py`, which writes this table, the conclusions
below and the full report from `tools/worklog.py`):

| Basis | Core | Verification | Logistics | Hours |
|---|---:|---:|---:|---:|
| Target as given | 70 % | 25 % | 10 % | |
| Target as a share of 105 | 66.7 % | 23.8 % | 9.5 % | |
| Lead, every closed interval in full | 63.0 % | 24.1 % | 12.9 % | 21.11 |
| Lead, without the 4 long intervals | 43.0 % | 34.4 % | 22.5 % | 12.04 |
| Delegated agents and workflows (12.15 h of them estimated) | 46.2 % | 52.2 % | 1.6 % | 12.28 |
| Lead plus delegated | 56.8 % | 34.4 % | 8.7 % | 33.39 |

**What can and cannot be concluded** (a category counts as at its share within 3 points of
the target read as a share of 105 %).

* **Core is below its share** on the combined basis: 56.8 % against 66.7 % (lead alone 63.0 %, lead without the long intervals 43.0 %, delegated 46.2 %).
* **Verification is above its share** on the combined basis: 34.4 % against 23.8 % (lead alone 24.1 %, lead without the long intervals 34.4 %, delegated 52.2 %).
* **Logistics is at its share** on the combined basis: 8.7 % against 9.5 % (lead alone 12.9 %, lead without the long intervals 22.5 %, delegated 1.6 %).
* **The core share of the lead's time is known only as a range**, 43 % to 63 %, depending on
  how the 4 long intervals are treated: they hold 544 of the lead's 1267 minutes.
* The target was therefore **not met within 3 points** on the combined basis (core below, verification above its share).

<!-- begin level 2 (Practice) -->
**[L2 Practice] How the ledger works**

`tools/worklog.py` appends one JSON line per event to `devlog/time.jsonl`; the file is never
rewritten.

| Command | Records |
|---|---|
| `start <core\|verify\|logistics> "<note>"` | the lead switched category now (stamp with seconds) |
| `stop "<note>"` | the lead stopped working; closes the current interval |
| `backfill <ISO time> <category> "<note>"` | a switch typed in afterwards; stored with `"backfilled": true` and counted as an estimate |
| `delegate <category> <minutes> "<note>"` | wall-clock minutes of a background agent or workflow: an estimate |
| `delegate <category> --from <ISO> --to <ISO> "<note>"` | the same from two time stamps: measured |
| `idle <ISO from> <ISO to> "<note>"` | a gap inside an interval in which the lead did not work; subtracted from that interval |
| `report [--json \| --markdown \| --summary] [--until <ISO time>]` | the integration shown on this page; `--until` integrates the ledger as it stood at that stamp |

The report follows four rules, each of which replaces a weaker one in the first version of the
tool:

1. **Nothing is capped.** Every closed interval counts in full, less recorded idle gaps
   (gaps that overlap each other are merged first, so no minute is subtracted twice). (The
   first version cut every interval at 45 minutes, which hid two long intervals.) Intervals
   longer than 45 minutes without a recorded switch are listed individually, and the split is
   also shown without them.
2. **An open interval is not counted.** If the last entry is not `stop`, the report names the
   open interval and leaves it out, so the numbers do not depend on when the report is run.
   (The first version closed the last interval at the current time.)
3. **Backfilled stamps are estimates.** New ones are marked. Entries from before the marker
   existed are recognised by a whole-minute stamp, since `start` writes seconds; this can
   mislabel about one live entry in sixty.
4. **Delegated time is kept separate.** It is wall-clock time of agents that ran in parallel
   with the lead, often several at once. Adding it to the lead's hours adds two different
   kinds of time; the combined table is labelled as indicative.
**Workflows of many agents.** A workflow is booked with its wall-clock time, split between
the categories; for the workflows of the first day the split was a judgement. The review of
the 0.3.0 candidate (132 agents, 245.8 minutes of wall-clock on 2026-11-11) had every agent
report when it started and finished, and its wall-clock is split by those measured
agent-minutes: 230 of implementers (core) and 868 of reviewers and of the second readers
who tried to refute each finding (verification). Booked in agent-minutes instead, the same
workflow would be 3.8 hours of core and 14.5 hours of verification. Either way it is the
main reason why the combined split shows more verification than the target: the review was
sized for thoroughness, not for the ratio, and the fixes it led to were then made by the
lead. The lead's own record is the row to read for how the directed work was divided.

<!-- end level 2 -->

<!-- begin level 2 (Practice) -->
**[L2 Practice] The full report**

Ledger from 2026-11-10T09:18:00-05:00 to 2026-11-12T10:22:11-05:00; 85 closed lead intervals, 14 delegated streams.

**Lead, closed intervals as recorded (nothing capped)**

| Category | Minutes | Share | Target as given | Target as a share of 105 | Share minus normalised target | Of which between backfilled stamps (min) |
|---|---:|---:|---:|---:|---:|---:|
| Core capability | 798.4 | 63.0 % | 70 % | 66.7 % | -3.6 | 212.8 |
| Testing and verification | 305.3 | 24.1 % | 25 % | 23.8 % | +0.3 | 134.7 |
| Logistics and tooling | 162.8 | 12.9 % | 10 % | 9.5 % | +3.3 | 98.0 |
| **Total** | **1266.5** (21.11 h) | 100 % | 105 % | 100 % | | |

Recorded idle gaps subtracted: 1583.2 min.

**Long intervals** (more than 45 minutes with no recorded switch; counted in full above)

| From | To | Minutes | Category | Note |
|---|---|---:|---|---|
| 15:05:39 | 16:31:44 | 86.1 | core | documentation accuracy fixes, integrating review fixes |
| 16:31:44 | 20:59:58 | 268.2 | core | external mesh import (Gmsh/NPZ), reference quantities, file-mesh cases; orchestrating fix + docs-sync workflows |
| 20:59:58 | 21:56:33 | 56.6 | verify | full tests, clean verification run, redeploy + smoke |
| 21:56:33 | 06:16:45 | 133.4 | core | phase 2: turbulence closure, 3-D, MDO contract, audit fixes (orchestration) |

**Lead, long intervals left out (sensitivity)**

| Category | Minutes | Share | Target as given | Target as a share of 105 | Share minus normalised target |
|---|---:|---:|---:|---:|---:|
| Core capability | 310.6 | 43.0 % | 70 % | 66.7 % | -23.7 |
| Testing and verification | 248.8 | 34.4 % | 25 % | 23.8 % | +10.6 |
| Logistics and tooling | 162.8 | 22.5 % | 10 % | 9.5 % | +13.0 |
| **Total** | **722.2** (12.04 h) | 100 % | 105 % | 100 % | |

**Delegated agents and workflows** (wall-clock time, parallel to the lead; kept separate)

| Category | Minutes | Share | Target as given | Target as a share of 105 | Share minus normalised target | Of which estimated (min) |
|---|---:|---:|---:|---:|---:|---:|
| Core capability | 340.4 | 46.2 % | 70 % | 66.7 % | -20.5 | 332.4 |
| Testing and verification | 384.4 | 52.2 % | 25 % | 23.8 % | +28.4 | 384.4 |
| Logistics and tooling | 12.0 | 1.6 % | 10 % | 9.5 % | -7.9 | 12.0 |
| **Total** | **736.8** (12.28 h) | 100 % | 105 % | 100 % | | |

**Lead plus delegated** (two different kinds of time added; indicative only)

| Category | Minutes | Share | Target as given | Target as a share of 105 | Share minus normalised target |
|---|---:|---:|---:|---:|---:|
| Core capability | 1138.8 | 56.8 % | 70 % | 66.7 % | -9.8 |
| Testing and verification | 689.7 | 34.4 % | 25 % | 23.8 % | +10.6 |
| Logistics and tooling | 174.8 | 8.7 % | 10 % | 9.5 % | -0.8 |
| **Total** | **2003.3** (33.39 h) | 100 % | 105 % | 100 % | |

Open interval, not counted: `logistics` since 2026-11-12T10:22:11-05:00 (freeze of 0.4.0, verification run on a clean checkout).

<!-- end level 2 -->

<!-- begin level 2 (Practice) -->
**[L2 Practice] Uncertainties, largest first**

* **4 long intervals carry 43 % of the lead's recorded time** (544.4 of
  1266.5 minutes). They are listed in the report above. During the longest the lead was
  partly waiting for delegated agents, partly reviewing their results (which is
  verification work) and partly idle; no switch and no idle gap was recorded then, and
  none has been added afterwards because it would be a guess. The two tables "as
  recorded" and "long intervals left out" bracket the truth.
* **729 of the 737 delegated minutes are estimates.** Workflows were entered as round
  figures after they finished and split between the categories by judgement (implementers
  and writers to core, reviewers and auditors to verification). The parallel groups of the
  second evening were not recorded by the session that ran them at all: their wall-clock
  window was reconstructed from file modification times in the following session.
* **35 % of the lead's minutes lie between backfilled stamps** (445 of 1267; the last
  column of the first table). A backfilled entry places work after the fact: the work
  exists, the minutes are an estimate.
* **Documentation is booked as core.** Writing the documentation content and building the
  documentation engine are counted as core capability, because served documentation is one
  of the deliverables. A reader who regards documentation as logistics should move those
  minutes.
* **Categories are coarse.** An interval has one category; a session that mixed debugging a
  study (verification) with fixing the code it exposed (core) is booked to whichever was
  entered.
* The ledger records 3 calendar days (2026-11-10, 2026-11-11, 2026-11-12), with a recorded idle gap of
  1583 minutes where a session ended without a `stop`. It is evidence of how
  those days were spent, not a time-and-motion study.

<!-- end level 2 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Checking the tool**

`tests/test_worklog.py` builds small ledgers in a temporary directory and asserts the rules
above: long intervals counted in full and listed, an open interval left out and reported, a
report that does not change with the clock, idle gaps subtracted, backfilled entries marked
or inferred, delegated time kept out of the lead's figures, targets shown as given and
normalised, refusal of malformed input, and a snapshot (`report --until`) that leaves out
everything stamped later. The numbers on this page are not typed in:
`tools/effort_page.py` writes the table, the conclusions and the full report from the ledger
for the stamp named at the top, and `tests/test_docs_content.py` fails when the page is not
what that generator would write for that stamp.

<!-- end level 3 -->
