Skip to content

OODA: the weekly learning record and the Loop's chart (PR 5 of 5) - #204

Merged
hhff merged 8 commits into
mainfrom
ooda-learning
Nov 13, 2026
Merged

hhff merged 8 commits into
mainfrom
ooda-learning

Conversation

@hhff

@hhff hhff commented Nov 11, 2026

Copy link
Copy Markdown
Member

PR 5 of 5 for the inspectable OODA loop (spec and plan in #193). Stacked on #203 (base ooda-knowledge). It closes the owner's question: is the loop making the system better informed, more autonomous and more trusted, week by week?

Adoption gate: same as #203

This PR adds two top-level observation fields, week and figures. Merge it only when every instance has v0.37.0 or later. Today stacksbot is on v0.33.2.

What changes

  • The weekly learning record. Each week, observe-metrics writes one observation for the past week, and on first run it back-fills one per past week. Each record has kind: learning, source: metrics, subject: project, its week (yyyy-Www) and source_key: learning:<week>. Its figures are counts, never shares. Its refs hold up to 60 of the records it counted, and its detail is one sentence. Records can't be back-dated, so each one carries today's at and its figures come from replaying the log up to the end of its week (withLogAt).
    • Informed: accepted knowledge; recurring signals formed and explained; starts, and starts given a lesson.
    • Autonomous: ladder calls, and how many were made on trust; owner questions; merged tickets.
    • Trusted: answers with a recommendation, and how many agreed; calls, and corrections.
    • The definitions are in the plan's "PR 4 and 5 review fixes", item 5. Only observe-metrics writes these records; reading the dashboard never does.
  • The chart at the top of the Loop. Six small charts, two per column, with weekly points:
    • Informed: accepted knowledge; share of signals explained, and of starts given a lesson.
    • Autonomous: share of ladder calls made on trust; questions per merged ticket.
    • Trusted: agreement; corrections per 100 calls.
    • A point whose denominator is under 5 is drawn hollow, titled "too few to say".
    • Retros and rung changes appear as dashed vertical marks.
    • Each point opens its week's learning sidepeek.
    • With fewer than three records, the Loop shows tiles and a sentence saying trends need a few weeks.
    • lineChart gains hollow and linked points and xmarks; its existing callers draw exactly as before.
  • The learning sidepeek: the week's figures, every record it counted, and lesson efficacy. For each lesson given to a start, it lists the observations on its evidence's keys in the four weeks before the lesson was first given and since then. This is a list with ids, not a score.
  • Docs: supervisor.md §3, and a note in operator.md's daily review.

For the operator's review (#190 follow-up)

The review can read:

  • log --type observation --json: the learning records, with figures and week
  • dashboard-data: ooda.learning
  • peek learning <id> --json: the counted records and lesson efficacy

Tests

  • test/ooda-learning.test.mjs:
    • back-fill over three weeks, with figures counted by hand
    • writing twice adds nothing
    • dashboard-data never writes a record
    • the peek's lists and efficacy rows
    • the chart code run in vm: tiles, six charts, hollow points, links, marks, unchanged old output
  • One Chrome check in test/dashboard.test.mjs.
  • log-tolerance.test.mjs now uses a different made-up field (insights), since figures is real.
  • G1 golden re-recorded; only ooda keys were added.
  • Full suite on Node 24: 427 passed, 0 failed, 1 existing skip.
  • Speed: on a 14,000-line, 45-week log, the first back-fill adds about 1.3 s, once.

One-way doors

None. Additive fields, behind the adoption gate.

🤖 Generated with Claude Code

hhff and others added 8 commits November 11, 2026 14:50
observe-metrics now writes one learning observation per ended ISO week, with the week's counts in
a new top-level figures field and its week in week, back-filled from the log as it stood at each
week's end (withLogAt folds only the lines up to the cut). Counts, never shares, so the views
divide and a small denominator can be shown as too few to say. The dashboard reads the records
and never writes one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Six small charts above the Loop's tabs, two per column (Informed, Autonomous, Trusted), one point
per weekly learning record, hollow where the denominator is under five, each opening its week;
retros and rung changes are dashed vertical marks. lineChart takes an optional third element per
point and xmarks, so its other callers draw as before. Under three records the Loop shows totals
since the log began instead, since a trend from two points means nothing. The learning sidepeek
shows the figures with every record each counted (recomputed from the log as it stood at the
week's end, since the line's refs are capped) and lesson efficacy as lists and counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
supervisor.md §3 says when observe-metrics writes a week's record, what its three columns count,
and where to look at what a week counted; operator.md's daily review points at the same records
for judging each supervisor. The log-tolerance test's stand-in for a newer kit's field moves off
figures, which an observation now has; the G1 golden gains only the Loop's new keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s written once

- refs are trimmed from the end until the line fits LINE_MAX (writer names are unbounded), so
  the corrections, first, survive and appendLog never dies before observeFindings
- the back-fill reaches back at most LEARN_BACKFILL_WEEKS (104)
- writeLearning runs under a lock in run/ and reads the log afresh; the dashboard keeps the
  earliest record per week
- only the supervisor's own record holds a week, as the dashboard counts them
- the schema's figures objects are open to counts a later kit adds (spec §8)
- the dashboard leaves out a record whose three columns aren't objects
- questions per merged ticket is hollow on its merges, "no ticket merged" at none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hhff
hhff changed the base branch from ooda-knowledge to main November 13, 2026 18:37
@hhff

hhff commented Nov 13, 2026

Copy link
Copy Markdown
Member Author

The weekly learning record and the Loop's chart, OODA part 5 of 5. Review fixes from the author's pass: the line fits LINE_MAX, the back-fill is capped at 104 weeks, writeLearning runs under a lock with a dedupe on read, nested figures are left open for forward compatibility, malformed figures are guarded, and only the supervisor's records count as written. Its CI flake was the dashboard refresh stall diagnosed separately, not this code. CI 9/9 at df1cc9c.

@hhff
hhff merged commit 04e59f1 into main Nov 13, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant