Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/maintainer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ reader-question-chain) while leaving those rows' every other ruling intact.
| Deletion-first answer obligations (#830, 2026-08-20) | Supersedes the answer-shape portions of the whitelist era — #479 Wave B cut 2's single `must_state` list, #823's placement-only D-series, and #825's "relevance is governed, placement and form are free" — while leaving every integrity gate those rows built exactly where it was. `engine/evaluation_challenge.py` emits three lists instead of one: `must_state` (the floor), `may_state` (the concentration family and cash — computed, addressed, owed by default on no call), and `machine_state` (`basis.state_version`, never rendered in any register). Its readers: `schemas/evaluation-challenge.schema.json` (additive; new keys are required because the block is computed fresh per call and never stored, and the `must_state` topic enum narrows to match `TOPICS` because `tests/test_evaluation_challenge.py` holds those two as an ordered equality) ↔ `references/trade-consequence.md` "What the answer owes" (which now states a reason per keep and per delete, and defines *stated*: the fact appears with its correct anchor — inline number, table cell, or end-block line all qualify, so fifteen obligations are not fifteen sentences) ↔ `SKILL.md`'s answer shape ↔ `references/freeform-answers.md` rule 4 ↔ `docs/expression-contract.md` D7 ↔ `tools/ux_receipt.py` ↔ `tests/test_evaluation_challenge.py` / `test_consider.py` / `test_expression_contract.py` / `test_interaction_trajectory.py` / `tests/agent/check_expression.py` / `evals/trade_answers/`. **The deletion is of obligations, never of data**: every number is still computed, still anchorable, still citable, and the user can ask for any of it — which is what makes not saying a number this decision does not turn on different from hiding it. **The two silences that could hurt stayed machine-enforced**: `rule_effects` and `required_coverage` are untouched, so a rule the *user* wrote is still named and still refused-for-dropping while the engine's own default threshold became a may-state. **Volume distribution became expression's business** (D7: a fact lives on exactly one floor — opening body, parenthetical beside its number, one end-block line, or not rendered), which §2 had disclaimed and nothing else had claimed; that gap is why fifteen owed facts became fifteen body sentences with every D rule satisfied. The reading-budget rule proposed as V10 in the issue is **not** adopted: a length cap is what #827 had just deleted. The named risk is the other direction — a deciding consequence omitted — and its backstops are the two hard mandates above plus the owner-live `comprehension` verdict, never a checker. |
| Cross-route research baseline (#716, 2026-08-23) | `skills/fomo-kernel/references/research-priors.md` is the single catalogue and the single statement of how far a prior may travel. Its readers: `references/decision-framing.md` (the route that already had it — the baseline is its top sentence) ↔ `references/trade-consequence.md` ("The research baseline, and why it may not fill a gap") ↔ `references/freeform-answers.md` ("The research baseline is available here too") ↔ `docs/expression-contract.md` §6 ↔ `tests/test_research_priors.py`. Four rules. **The catalogue is reachable from every route that answers a decision, not only from the one with no book.** Before this row it was linked by exactly one file, and the user-visible consequence was inverted evidence value: a user with nothing recorded heard that broad diversification is the baseline and that an index label alone does not establish breadth, and the same user, after handing over a book, got weights and concentration and could no longer reach that baseline at all. `test_b_the_catalogue_is_reachable_from_every_route` is what fails when a route's link is dropped, and it walks `SKILL.md → route file → catalogue` rather than asserting the catalogue exists, because a reference nothing names is text nothing loads (the `profile.md` precedent). **An engine fact dominates a prior, and that boundary has one home.** `research-priors.md`'s own "An engine fact dominates a prior" section owns it: a prior may interpret a deterministic result, never replace, substitute for, or fill a gap in one, and it may not invent a cap, an allocation, or a threshold the user has no rule for and the engine did not compute. The two book-bearing routes carry that sentence **verbatim, not paraphrased**, and name the section it comes from: a paraphrase is how five independent phrasings of answer-first happened (#832), and a pointer alone is a boundary the agent has to open a second file to learn. This is #834's answer applied to a rule instead of an exemplar — the same text in three places, made mechanical rather than forbidden, with `test_e_the_engine_fact_boundary_is_one_sentence_in_three_places` failing on any drift and `test_f_reachability_and_boundary_mutations_are_caught` proving it fails. `decision-framing.md`'s "A missing number is never replaced by a general rule" red line stays where it is and gains a pointer: it is the *no-book* form (no computed weight exists at all), and the new section is the form for the routes that do have one. **It is a claim authority, not a derivation.** It adds no shape parameter to any surface, so `expression-contract.md` §6's derivation column is deliberately **unchanged** and the catalogue appears in the last column instead; `freeform-answers.md`'s empty derivation (#832) stays empty and says so in the new section itself. A prior enters an existing block, is subject to §3's increment gate like any other, and a standing paragraph on the value of diversification is the `default_as_insight` ban with a citation stapled to it. **No runtime surface moved**: no engine file, schema, `.json` payload contract, new field, or new engine vocabulary — #716 §1 says the first version needs no runtime schema, and `SKILL.md` is untouched because it already routes to all three route files, which is the whole point of #507's byte budget on the always-loaded pair. Why the row exists: #716's title is "Cross-route evidence-backed decision priors" and the shipped implementation (#727) wired exactly one route, so the issue's own §4 — the boundary that makes the other routes safe — had never been written down anywhere. |
| The six non-negotiable boundaries reach the installed host (#838, 2026-08-23) | `README.md` installs the product by symlinking `skills/fomo-kernel/` alone, so `AGENTS.md` — and any rule stated only there — does not exist on an installed host. The floor's six boundaries therefore live twice: `AGENTS.md` "## Non-negotiable boundaries" (the checkout floor) ↔ `skills/fomo-kernel/SKILL.md` (each boundary stated in the section that exercises it; the privacy boundary as its own "Private data stays local" section, key sentences verbatim — except the anything-public example list, deliberately re-cast for the installed audience as "a shared card, an example, a bug report" where the floor names the maintainer's issues/PRs/fixtures/receipts) ↔ `skills/fomo-kernel/references/agent-boundaries.md` (the routed may/may-not contract `SKILL.md` names as holding throughout; carries the CLI whitelist, the hand-assembly ban, and the third-party/cloud privacy sentence). No text runtime surface under `skills/fomo-kernel/` (every `.md`/`.json`/`.html`/`.txt`) may cite `AGENTS.md` for a rule — its reader may not have the file; `references/freeform-answers.md` stating the card-privacy default instead of citing "AGENTS.md invariant 4" is the pattern. `.py` comments under `engine/` and `tools/` sit outside that scan deliberately: boundary 1 keeps an installed agent out of engine internals, so those citations are maintainer-facing rationale, not instructions an installed reader follows. `tests/test_installed_skill_tree.py` reads **only** `skills/fomo-kernel/` and fails when a boundary's statement retreats to the repository root — every other suite reads the checkout, which is exactly why #838 shipped unseen. The #507 byte budget split with it: `SKILL.md` has its own ceiling (the whole always-loaded surface of an installed host) and `AGENTS.md` its own (the checkout-only floor), because one budget over a pair that exists only in a checkout let the floor's bytes squeeze the installed contract to zero headroom — the pair sat at exactly 16384 bytes when #838 was found. |
| The installed tree names its authorities and links to none of them (#839, 2026-08-23) | #838's class, second instance: nine files under `skills/fomo-kernel/` linked `../../docs/expression-contract.md`, `docs/output-contract.md`, `docs/output-voice.md`, or `evals/episodes/README.md` — seventeen relative links that resolve to nothing on an installed host. All seventeen were provenance, not routes: the answer shape is `SKILL.md`'s own §3 projection, each surface reference opens with its exemplar (#834), card structure is enforced by `engine/card_renderer.py`, and `ux-receipt.md` already handles the vendored-without-`evals/` case explicitly — so no in-tree rule depended on out-of-tree content. The ruling that keeps it that way: **the installed tree may *name* an authority ("the repository's `docs/expression-contract.md`") but may never *link* out of the tree** — a citation is provenance, a relative link is a promise the file is right there, and on an installed host that promise is false. Distinct from the `AGENTS.md` rule above deliberately: `AGENTS.md`'s content had to move in-tree (the boundaries bind every answer), while the expression/output authorities stay in `docs/` and the tree carries their projections, so naming them is required by the projection discipline ("this is its projection" must say of what). Gated by `tests/test_installed_skill_tree.py::test_no_reference_escapes_the_installed_tree`: every extracted target (inline markdown links with or without titles, reference-style definitions, HTML href/src) and every upward-relative path token in any other syntax must resolve inside the tree — resolution decides, not a directory name list, so in-tree upward hops (`../schemas/`, `../evals/`) stay legal; site-root and absolute targets count as escapes because the tree cannot promise where it is mounted; scanned over every text runtime surface, the same scope as the `AGENTS.md` citation ban. `engine/review.py`'s comment mis-citing "ledger-derived current holdings stay canonical" as boundary 6 was corrected to boundary 2 in passing; the other `.py` AGENTS.md mentions stay, per the scan-scope rationale in the #838 row. |

Date product assumptions when using them for prioritization. Reconfirm assumptions that are several weeks old or contradicted by new evidence.

Expand Down
2 changes: 1 addition & 1 deletion skills/fomo-kernel/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ The engine computes portfolio consequence; it is not a company-research service.

## Shape of the answer

One shape, every answer (`../../docs/expression-contract.md` §3 owns it; this is its projection, not a second wording). **A fact lives on exactly one floor, and twice is a bug.** *Top:* one sentence — the stance and the reason that decides it (proceed, resize, delay, collect evidence, choose one candidate, no trade). *Middle:* only blocks that add a new decision-relevant fact or judgment — delete one; if the decision does not change, delete it. There live the numbers that would flip the call, every `rule_effects` entry (never optional), a truth-critical denominator, unit, or pricing set beside its number, and a falsifier on any directional call — the counter-case needs no section. *Bottom:* the rest of the inventory stays in the data layer; say once you can expand it. *End:* one compact block for other material limitations; machine anchors and engine narration nowhere.
One shape, every answer (§3 of the repository's expression contract, `docs/expression-contract.md`, owns it; this is its projection, not a second wording). **A fact lives on exactly one floor, and twice is a bug.** *Top:* one sentence — the stance and the reason that decides it (proceed, resize, delay, collect evidence, choose one candidate, no trade). *Middle:* only blocks that add a new decision-relevant fact or judgment — delete one; if the decision does not change, delete it. There live the numbers that would flip the call, every `rule_effects` entry (never optional), a truth-critical denominator, unit, or pricing set beside its number, and a falsifier on any directional call — the counter-case needs no section. *Bottom:* the rest of the inventory stays in the data layer; say once you can expand it. *End:* one compact block for other material limitations; machine anchors and engine narration nowhere.

Never manufacture a scenario nobody asked for, restate a system default as insight, hedge in couplets, or make one point twice. Ask only decision-changing questions, then stop. `references/trade-consequence.md` holds the rest. Each reference opens with its exemplar; follow it.

Expand Down
2 changes: 1 addition & 1 deletion skills/fomo-kernel/card-spec.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Review card content specification

> Structure authority is [docs/output-contract.md](../../docs/output-contract.md);
> Structure authority is the repository's `docs/output-contract.md`;
> execution is `engine/card_renderer.py` plus `references/card-policy.md`. This
> file records what the card is for and how to word the honesty sentences the
> agent owns. Agents do not assemble or redact cards manually.
Expand Down
2 changes: 1 addition & 1 deletion skills/fomo-kernel/engine/review.py
Original file line number Diff line number Diff line change
Expand Up @@ -8231,7 +8231,7 @@ def _positions_diagnosis(rows, canonical_held, weights, last_px, max_pos_overrid
weights for the same ticker at the same instant depending on which
entry point answered -- 28.6% from the FIFO route this function used to
read, 37.5% from `consider`'s canonical one, and weight is the number
this product's own rules are built on. `AGENTS.md` boundary 6 --
this product's own rules are built on. `AGENTS.md` boundary 2 --
ledger-derived current holdings stay canonical -- settles which one
wins, and issue #456 already owns the general tension (a considered
trade reasons on a different basis than a review's own CSV/FIFO path);
Expand Down
2 changes: 1 addition & 1 deletion skills/fomo-kernel/references/card-policy.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Card policy

> Section order and section set are governed by
> [docs/output-contract.md](../../../docs/output-contract.md) (keynote + four
> the repository's `docs/output-contract.md` (keynote + four
> blocks), which also owns every rule about which figures render as tiles
> versus prose. This file keeps only what the agent decides: wording,
> redaction, and narrative.
Expand Down
10 changes: 5 additions & 5 deletions skills/fomo-kernel/references/decision-framing.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ falsifier they could write down themselves. Read it before writing one.

It is copied verbatim from `tests/agent/expression-witnesses.json`, scene
`no_book_single_name` — the corpus that
[expression-contract.md](../../../docs/expression-contract.md) §3.5 makes the
§3.5 of the repository's expression contract (`docs/expression-contract.md`) makes the
binding statement of this shape. Every issuer in it is invented, and
`tests/test_expression_contract.py` fails if the two copies disagree.

Expand Down Expand Up @@ -43,9 +43,9 @@ when it could change the recommendation or unlock the portfolio claim.

## Voice and expression authority

Apply the global [expression contract](../../../docs/expression-contract.md):
the answer's shape through its §3 mother chapter, voice through the
[output-voice contract](../../../docs/output-voice.md) (V1–V9), disclosure
Apply the repository's global expression contract (`docs/expression-contract.md`):
the answer's shape through its §3 mother chapter, voice through its
output-voice contract (`docs/output-voice.md`, V1–V9), disclosure
relevance and placement through D1–D7, provenance labelling through C1–C4.
They own universal output semantics; this reference owns the no-book facts,
questions, and route order below.
Expand Down Expand Up @@ -198,7 +198,7 @@ Three rules follow, and the third is the one that keeps the first two honest:
1. Select material portfolio facts by salience, not as a checklist. State them
as limitations or ask about them according to whichever form best advances
the recommendation.
2. A limitation that cannot be turned into a question is stated plainly and once — "I have secondary reporting, not the filing" — when it could change the framing or prevent a false impression of coverage. Put a truth-critical denominator, unit, or pricing set beside its number; place other material limitations where they make the answer clearest ([expression contract](../../../docs/expression-contract.md) D1–D2).
2. A limitation that cannot be turned into a question is stated plainly and once — "I have secondary reporting, not the filing" — when it could change the framing or prevent a false impression of coverage. Put a truth-critical denominator, unit, or pricing set beside its number; place other material limitations where they make the answer clearest (expression contract D1–D2, `docs/expression-contract.md`).
3. A material limitation may never simply disappear. Dropping the narration is a change of shape, not permission to leave a decision-relevant gap unsaid.

> **History:** this rule once required per-claim placement, then #823 replaced
Expand Down
4 changes: 2 additions & 2 deletions skills/fomo-kernel/references/freeform-answers.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and one end block. Read it before writing one.

It is copied verbatim from `tests/agent/expression-witnesses.json`, scene
`freeform_positions_view` — the corpus that
[expression-contract.md](../../../docs/expression-contract.md) §3.5 makes the
§3.5 of the repository's expression contract (`docs/expression-contract.md`) makes the
binding statement of this shape. Every issuer in it is invented, and
`tests/test_expression_contract.py` fails if the two copies disagree.

Expand Down Expand Up @@ -180,7 +180,7 @@ calculate, interpolate, or silently widen them.

## Rule 4 — limitations follow relevance, not a template

Use [expression-contract.md](../../../docs/expression-contract.md) D1–D7 for
Use the expression contract's D1–D7 (`docs/expression-contract.md`) for
every limitation. Keep truth-critical denominator, unit, or pricing-set
qualifiers inline. Include other limitations only when they materially qualify
the answer; no marker or numeric line cap is required.
Expand Down
2 changes: 1 addition & 1 deletion skills/fomo-kernel/references/research-priors.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ this file states.

A prior is a claim authority, not a block, a question, or a standing paragraph:
it adds no shape parameter to any surface, so the increment gate in
[expression-contract.md](../../../docs/expression-contract.md) §3 governs it
the repository's expression contract (`docs/expression-contract.md`) §3 governs it
like every other block. One that changes nothing about what the user should do
is deleted, not shortened.

Expand Down
Loading
Loading