cyberine notice: scoped owner rulings, knowledge and plans at session start (2026-11-10)
A full rulings file loaded into every session and grew without bound, and Claude Code saves hook output over 10,000 characters to a file without telling anyone. Since k8380 (owner ruling D7-A) a session gets one gist line per in-scope ruling instead, under a hard cap, and reads a ruling in full only when it needs it.
Run recipe:
cyberine noticeprints the notice for the current directory, for example2026-11-09 kab12: Owner: decide the queue - D1-A: keep the queue local ..., one line per ruling as<date> <id>: <title> - <gist>, with the choice cut to 160 characters. It prints nothing and exits 0 when there is nothing to say.cyberine notice --jsonprints{ text, sections, truncated, omitted }; each section is{ id, title, lines: [{ text, rank }], total, more }with the lines that fit the cap.cyberine notice --max-chars 600sets the cap for one call.cyberine rulings show <ref|task-id> [--json]prints one ruling in full: choice, rejected, reason, merged refs, ref and state (active, retired or merged). A task id prints every ruling on that task.- The plugin's SessionStart hook (the handoff-pointer mode of
plugin/hooks/board-hooks.mjs) runscyberine handoff pointerandcyberine noticeside by side and prints both on startup, resume, clear, compact and fork, so the notice comes back after a compaction.cyberine noticeis a light entry of the CLI shim; measured on this repo's board, the notice takes about 0.25 s and the whole hook about 0.3 s, well inside its 5 s timeout. A repo whose own hook settings already runcyberine noticeis skipped, as for the handoff pointer.
Scope: a ruling's scope is the path: of its task, read from the manifest, then TASKS_ARCHIVE.md. A ruling made with --run, or on a task with no path, is hub-wide. Inside a submodule of a hub board the notice lists the rulings whose path is in that submodule plus every hub-wide one, and ranks the submodule's own above the hub-wide ones; at the hub root it lists them all.
Cap: --max-chars N, else CYBERINE_NOTICE_MAX_CHARS, else "notice": { "maxChars": N } in .cyberine/config.local.json, then .cyberine/config.json (read from the current repo's own root), else 2000. A value that is not a positive whole number falls through. Lines are dropped lowest rank first (oldest first within a section), knowledge and plans lines before any ruling line (k88et: every in-scope ruling outranks every knowledge and plans line, and a ruling line is dropped only when the rulings alone exceed the cap), each section that lost lines ends with +N more: <command> (+N more: cyberine rulings for rulings), and the cap includes those lines and the final newline. The default sits far below Claude Code's 10,000-character hook limit.
Knowledge and plans (k493v, 2026-11-10): after the rulings the notice carries two more sections under the same cap.
- Knowledge: the entries of
cyberine knowledgein scope for this repo (repo, matched groups, global; retired, stale and merged entries left out), one line each as<kind> <id>: <title> - <when, or the first sentence of the body>, read in full withcyberine knowledge show <id>; a cut section ends with+N more: cyberine knowledge search <words>. Ranking needs no model: scope tier (repo, then group, then global), then path relevance (evidence paths that match files touched by the last 20 commits), then recency, confirmations and kind (pref and lesson, then fact, then pointer). - Plans: the plans of
cyberine planswhose status is draft or decided, newest first, one line each as<created> <slug>: <title> [<status>, N open decisions], read withcyberine plans show <slug>; a cut section ends with+N more: cyberine plans list. - Pointer file: the knowledge lines come from
$CYBERINE_HOME/knowledge/pointers/<identity hash>.json(schemaknowledge-pointer/1:repo,groups,ledgerHead,stamp,generatedAt,counts,linesof{ id, kind, title, when | gist, read },omitted,search; the hash is the first 16 hex characters of the sha256 of the repo identity). Everycyberine knowledgecommand that appends to the ledger rewrites it once at exit, andcyberine noticerewrites it when itsstamp(repo identity, groups,HEADand the size and mtime of every ledger file) no longer matches, so the 10,000-event fold runs only after a change. The file is disposable: deleting it costs one regeneration and nothing else. Measured on a 10,000-entry fixture (2026-11-10, m3max): the light entrycyberine noticetook 0.4 to 0.65 s, cold or warm, against about 0.4 s on an empty store; throughsrc/cyberine.tsunder tsx it took 1.5 to 2 s either way, dominated by start-up. - Codex and Muse:
cyberine initandcyberine syncappend the notice as a## Session noticeblock after the policy blocks of the generatedAGENTS.override.md(see "Policies for Codex and Muse" below), and write that file when Codex or Muse is found even with no policy installed, as long as the notice is not empty. It stays listed in.git/info/exclude, andAGENTS.mdis never touched. - Workers: a
claude -p,codex execormuse execworker Cyberine spawns gets the notice for its working directory prepended to its prompt when the notice is not empty, so it needs no file. Raw-API loop workers do not get it.
Budget recipe (k88et): cyberine knowledge budget reports, for the current repo, what the notice injects and drops, from the same result cyberine notice builds (no second ranking). Text mode prints one line per section (rulings: 412 chars, 2 lines, 0 dropped) and a total line with the pointer freshness. --json prints { cap, used, sections: [{ id, used, lines, dropped }], omitted, pointer: { path, fresh } }: cap follows CYBERINE_NOTICE_MAX_CHARS / notice.maxChars like the notice, used equals the length of the cyberine notice text, the section dropped counts sum to omitted, and pointer.fresh says whether the pointer file matched its stamp before the call. Acceptance check: node .cyberine/accept/k88et.mjs.
Known Limitations and Deferred Work: the AGENTS.override.md copy of the notice is as old as the last cyberine init or cyberine sync, while the hook and the worker prepend are built fresh each time. Whether Muse reads AGENTS.override.md is unmeasured, so a Muse session may not see the notice (a Muse worker still gets it in its prompt). Sections share one cap and lines drop by rank across sections, so a board with many rulings can push every knowledge line out, leaving only the +N more line (rulings themselves are never pushed out by knowledge or plans). Path relevance reads committed history only, not uncommitted edits. A tracked .claude/rules/cyberine-rulings.md still loads in full until the owner commits its untrack (task karvp). The budget nudge (CYBERINE_RULINGS_BUDGET_BYTES) still measures the full rendered ledger, which no session loads any more; it now only says when consolidation would tidy the ledger. Acceptance check: node .cyberine/accept/k8380.mjs.
cyberine rulings: keep the owner rulings file from growing (2026-11-06)
.claude/rules/cyberine-rulings.md loads into every session of a repo, and before this change it only grew: every owner decision stayed in it forever unless the owner reverted it. A test repo...
Agent policies (cyberine init --policies)
cyberine init installs a public policy core: eight short, generic rules for how an agent works in any repo, one file each under .claude/rules/, written from the bundled templates in...