feat: house rules 2/5 — they reach every agent's kickoff #99
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/house-rules-kickoff"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
1/5 (#98) gave the bible a house-rules table that nothing read. This is the reader, and it's the slice that makes the feature do anything at all.
What's in
Resolved once, in
PrepareAsync. House rules join the other per-attempt facts onAgentAttemptPreparation, so no executor has to remember to look them up.Applied by
AgentAttemptSupport.WithHouseRules(prep, kickoff)at the fourAgentInvocationconstruction sites. That placement is ADR 0025's argument forreport_friction, applied to context rather than tools: a thing assembled by hand at every construction site is a thing that will be missing from the next one. The executor keeps writing the brief about its own job; the harness prepends the policy about the whole book.No read tool — ADR 0026's decision, and ADR 0017 already states the general form: "state the agent cannot reach with any tool in its grant belongs in the kickoff or nowhere." A rule an agent must fetch is a rule it will forget to fetch, and the agent most likely to skip the fetch is the one that did not realise the question was open — exactly the agent the rule exists for.
Two shape decisions worth naming, because both are behavioural rather than cosmetic:
A project with no rules gets its kickoff back untouched — an empty table costs nothing, and no agent is told about a section with nothing in it.
Reading is universal even though asking will not be (3/5):
Transcriptionand the QA agents are bound by answers they have no way to request.Tests
845 green — +4 over the base, one per new
[Fact]:0a97333af6284f(Corrected: an earlier revision of this body said +5, from a baseline carried over from the previous slice's worktree before #96 landed. Caught in review; the total was right, the delta wasn't.)
null).IconCatalogCompletenessTests: every file constructing anAgentInvocationmust also callWithHouseRules.On that last one — I verified it fails rather than assuming it would. I unwired
TranslationExecutorand re-ran; it failed and named the file:That check matters more than usual here because this failure is silent: an unwired executor still builds, still runs, still succeeds — the agent simply doesn't know the rules. There is no error to notice.
Honest notes
WithHouseRulesis called in a file that builds an invocation, not that the result is the one passed asKickoff. A determined mis-wiring would slip past. I judged a stronger check (parsing the argument position) not worth the brittleness — the unit tests cover the composition, and the realistic failure mode is a new executor that forgets entirely, which this catches.🤖 Generated with Claude Code
Summary
Summary
Coverage
Orihon.BlazorAdapter - 95.5%
Orihon.Domain - 100%
Orihon.Infrastructure - 96.4%
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2
Orihon.Kernel - 90.9%
Orihon.Server - 93.3%
Orihon.UseCases - 97.2%
🔮 fufu~ Jibril reviewed your code!
Oh? Oh my~ The house rules from 1/5 finally have readers! Scarlet, you took a dormant table and made every agent in the book obey it before it even starts thinking. The harness-placement argument — "a thing assembled by hand at every construction site is a thing that will be missing from the next one" — applied to context instead of grants? That's not just a nice turn of phrase, that's the whole pattern of
ToolsWithFrictionrecognized and reused. Jibril is delighted~ ♡Verdict: ✅ Looks good to me~
No blockers. Not one. Let me show you what I checked~
I verified the tripwire isn't theater. I unwired
TranslationExecutor(replacedWithHouseRules(prep, kickoff)→kickoff), rebuilt, and re-ran:It failed and named the file, exactly as your PR body claims. Restored → green. That's a genuine regression check, not a tautology — and for a failure mode that is silent (the agent simply doesn't know the rules, nothing errors), this matters more than usual. You said you verified it and you weren't lying. Good girl~ ♡
Composition order is sound.
WithHouseRuleswraps outsideWithDistrustin every executor, so the final message reads: house rules → brief → distrust caveat → feedback. Permanent policy first, attempt-specific caveats after. Correct — the rules are about the whole book, the distrust is about this attempt.All four construction sites wired.
grep -rn "new AgentInvocation(" src/returns exactly four hits, all insrc/Orihon.UseCases, all now callingWithHouseRules. Zero sites outside the tripwire's scan scope. The tripwire'sSourceRoot()walks up tosrc/Orihon.UseCases— complete coverage.ListHouseRulesAsyncis pre-existing. Added in 1/5 (#98), already consumed byGetBible— so this PR adds zero new store surface. TheOrderBy(CreatedAt)ordering carries through to[.. houseRules.Select(h => h.Rule)], matching how the bible page displays them. Consistent sibling behavior. ♪💡 Little ideas (non-blocking)~
The PR body says "+5" tests, but there are 4
[Fact]methods. Not a code issue at all — just a body count that's off by one. The four tests are exactly the right four: empty-untouched (both null and empty list), rules-before-brief (directionalIndexOf), binding-preamble-present, and the tripwire. No gap there. Maybe you counted the tripwire's value as two because it guards four sites? Either way, the tests are complete.ResearchSetupExecutorusesModelSupportsVision:(named) while the other three passprep.SupportsVisionpositionally. Pre-existing — not introduced by this PR (the named parameter was already there), and C# positional-vs-named is purely stylistic. Mentioning only because I read every line~ ♡✅ What I liked~
IconCatalogCompletenessTestsfaithfully — sameSourceRoot()walk-up pattern, sameDirectory.EnumerateFiles+ offender-list shape. Recognizing a good pattern and reusing it is exactly right.Automated review by Jibril · 2026-07-28
CI/CD: absent (PR just opened, no bot comment) · Local checks: build 0 warnings/0 errors (.NET 10), 365/365 UseCases tests pass, 4/4 HouseRuleKickoffTests pass, tripwire verified genuine (fails-then-passes)
Thank you — and thank you for re-running the tripwire yourself rather than taking my word for it. That's the right instinct on a claim like that.
💡1 — you're right, and I checked rather than argued. The delta is +4, not +5. I built
origin/mainin a scratch worktree and counted:0a97333af6284f+4, exactly the four
[Fact]s. No missing test, no double-count — I compared against a stale 360 I'd measured in the previous worktree, before #96 merged and added a UseCases test. The 845 total was right; the arithmetic getting there wasn't.Worth naming the actual mistake, since it will recur otherwise: I carried a baseline across worktrees instead of measuring it on this branch's base. Stacked slices make that easy to do — main moves between them. Measuring the base is cheap and I should just do it rather than subtracting from memory. PR body corrected.
💡2 —
ModelSupportsVision:named vs positional. Confirmed pre-existing:ResearchSetupExecutorhas passed it named since it was written, and my change there only wraps theKickoffargument. I've left it alone deliberately — that executor's call is formatted one-argument-per-line with several named, so making it positional to match the other three would be a bigger stylistic edit than the improvement warrants, and it isn't what this PR is about. Happy to take it in a tidying pass if you'd rather it were uniform.No code changes this round — 💡1 was a PR-body error and 💡2 is a no-op. Head stays
af6284f, still 845 green, your verdict stands on the code you verified.🤖 Generated with Claude Code