Skip to content

OODA: knowledge in decisions and starts; what fixed incidents taught (PR 4 of 5) - #203

Merged
hhff merged 11 commits into
mainfrom
ooda-knowledge
Nov 13, 2026
Merged

hhff merged 11 commits into
mainfrom
ooda-knowledge

Conversation

@hhff

@hhff hhff commented Nov 11, 2026

Copy link
Copy Markdown
Member

PR 4 of 5 for the inspectable OODA loop (spec and plan in #193). Stacked on #201 (base ooda-lineage).

Adoption gate: merge only when every instance has v0.37.0 or later

This PR adds two top-level log fields, decision.knowledge and act.knowledge. A kit older than v0.37.0 (#193, reader tolerance) refuses lines carrying them. Workers never write decisions or worker-slots acts, so a stale worktree doesn't matter; only a whole instance on an older kit does. On the Render box today:

instance upstream_base
stacks v0.39.0
website v0.39.0
mothership v0.37.1
stacksbot v0.33.2: must adopt v0.37.x first

What changes

  • A decision cites the knowledge it rests on. decide --on <k-…|p-…>… stores decision.knowledge. It is never copied into refs, and authorise never reads it, so it grants nothing. It is refused for:

    • an unknown id, or one that isn't knowledge or a problem
    • a candidate or retired lesson
    • an id that is also in --refs
    • a bare --on, or more than 60 ids

    The decision sidepeek lists what it rests on, in each record's own words. Lineage draws "rests on" edges.

  • A start records the lessons it was given. A fresh worker or planner start's worker-slots act carries knowledge: the ids knowledgeFor put in its prompt, newest first, at most 60. It is recorded only when the final resume is false, because a resumed session never reads the new prompt, and it is omitted when empty. The act sidepeek shows "What its instructions carried". Lineage draws lesson → start → ticket. This record is what makes a lesson's effect measurable (PR 5).

  • Orientation debt: what fixed incidents taught. ooda.debt.incidents lists incidents that are resolved within 30 days, have an outcome citing them, and aren't cited by any knowledge's evidence or by a live orient-noise ruling. Incidents whose status the owner set are excluded. orient prints each one with a suggested knowledge add --evidence <p> <d> <outcome> (values shell-quoted), and the Orient tab lists them under the signals. orient-noise now accepts a problem id ("nothing to keep").

  • Docs: supervisor.md §3 (--on, starts' knowledge, incident debt) and spec §3.

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

The review can read:

  • log --json → decision.knowledge and act.knowledge
  • dashboard-data → ooda.debt.incidents

orient --json is unchanged, because readers count its list as the recurring signals.

Tests

test/ooda-knowledge.test.mjs covers:

  • --on: each refusal, authority left unchanged by --on <owner standing rule>, and the lineage edge
  • real worker and planner starts in the fixture's private tmux: one lesson, none, a resume, 61 lessons capped to 60 (line under 4,096 bytes)
  • incident debt: listed, cleared by a lesson, cleared by a ruling, absent with no outcome

The G1 golden is re-recorded; only "incidents": [] was added. Full suite on Node 24: 416 of 417 passed, with 1 existing skip.

One-way doors

None. The two new fields are additive (constitution §4), behind the adoption gate above.

🤖 Generated with Claude Code

hhff and others added 8 commits November 11, 2026 13:56
A call that rests on a lesson, a fact or a problem left no trace of it:
the lineage couldn't draw knowledge into a decision, and the learning
record couldn't count it. --on stores the ids as decision.knowledge, a
new top-level field kept apart from refs (an act stays within refs) and
from approved_by (authority is unchanged). Only accepted knowledge
counts; a candidate, a retired lesson, an id in both lists or anything
but knowledge or a problem is refused. The decision's sidepeek lists
what it rests on in its own words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A lesson's effect can't be measured if nothing says which sessions were
told it. A fresh worker or planner start now records, on its
worker-slots act, the ids of the accepted knowledge its prompt carried
(act.knowledge, top-level, newest first, at most 60 so the line fits),
never in what, which LAUNCH_ACT parses. A resumed session reads no new
prompt, so its act records none; an empty list is omitted. The act's
sidepeek lists what its instructions carried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A fast fix verified quiet closed its incident and taught nothing: no
step asked what it showed. A resolved incident with an outcome citing
it, in the last 30 days, that no knowledge cites in its evidence and no
live noise ruling names, is now orientation debt: orient lists it after
the recurring signals with the lesson and the noise ruling it could
take (values quoted), dashboard-data carries it as ooda.debt.incidents,
and the Orient tab lists it under the signals. A noise ruling may now
name such a problem; a corrected one owes the lesson again, and an
incident whose status the owner set owes nothing. The G1 golden gains
only the empty incidents key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The supervisor's tick now says when to cite what a call rests on, what
a start records, and how to pay down a fixed incident's debt; the spec
notes where PR 4 differs from its first draft.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Incident debt in orient --json changed the list its readers count (the
kit chain counts it as the clusters). It stays in orient's text and in
dashboard-data's ooda.debt.incidents.

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

Review fixes: an incident resolved unverified (its outcome's valence 0) is no
longer listed as fixed and verified; a lesson the owner retired no longer
clears the debt; orient-noise names an observation or a resolved incident,
never an open problem; a lesson given to a start reads given in the lineage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hhff and others added 3 commits November 11, 2026 15:20
…authorise

Review fixes from the upstream loop: a decision's knowledge reads 'rests on'
in the lineage only for a problem or accepted knowledge (a hand-written line
citing anything else only cites it); a start's reads 'given' whatever became
of the lesson since. A peek's cited records carry their status, and the
sidepeek shows a lesson that isn't accepted as such, under 'What it drew on
(not its authority)'. --on is deduped before the cap; supervisor.md says
knowledge that isn't accepted is refused and grants nothing.

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

hhff commented Nov 13, 2026

Copy link
Copy Markdown
Member Author

Fable reviewed it and found no authority hole: nothing reads knowledge as authority, act refs are unchanged, and the new fields are top-level and supervisor-only. Findings fixed: an edge reads "rests on" only for accepted knowledge or a problem, a lesson's status is shown, "What it drew on (not its authority)", and --on is deduped. CI 9/9 at cfcd8d9 with main merged in.

@hhff
hhff merged commit 3a727e8 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