Skip to content

fix(cesar): remove the no-project-brief warning nudge - #291

Merged
cukas merged 5 commits into
mainfrom
fix/remove-no-brief-nudge
Aug 17, 2026
Merged

fix(cesar): remove the no-project-brief warning nudge#291
cukas merged 5 commits into
mainfrom
fix/remove-no-brief-nudge

Conversation

@cukas

@cukas cukas commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

The once-per-session 'No project brief found' warning was noisy and its message text was stale — the brief cascade accepts AGENTS.md and CLAUDE.md (not just AGENTS.md/.agon/project.md as the message claimed), and the cwd-only check misfired in subdirectories. Removed the nudge block, the _noBriefNudged WeakMap, and the now-unused hasProjectBrief import; the core hasProjectBrief export and the verify-before-done gate subsystem are untouched.

⚔️ Forged by Agon

The once-per-session 'No project brief found' warning was noisy and its
message text was stale — the brief cascade accepts AGENTS.md and
CLAUDE.md (not just AGENTS.md/.agon/project.md as the message claimed),
and the cwd-only check misfired in subdirectories. Removed the nudge
block, the _noBriefNudged WeakMap, and the now-unused hasProjectBrief
import; the core hasProjectBrief export and the verify-before-done
gate subsystem are untouched.

⚔️ Forged by [Agon](https://github.com/KERNlang/agon)

Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
The one-time 'agon now runs engines in workspace-pure mode' startup
banner claimed dispatched engines no longer get your CLAUDE.md — stale
since the project-context scanner injects AGENTS.md/CLAUDE.md into
every dispatch, and noisy when the config latch failed to persist.
Removed the banner, its now-dead isolationMigrationNotified config
field (loadConfig tolerates the stale key in existing configs), and
the TUI-probe fixture lines. The workspace-pure default and its
--impure / engineIsolation escape hatch are now documented durably
in the README instead of a runtime nag.

⚔️ Forged by [Agon](https://github.com/KERNlang/agon)

Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
…tive engines

API/native engines are the normal Cesar brains, but the native tool
loop had no notion of earned progress and no mid-loop steering channel:
a read-only mapping spiral ran 29/30 steps for 31 minutes (Bash cat/grep
bypassed the Read/Grep/Glob-only search counter, every tool event counted
as progress, budget grew on 'didn't fail'), and steering typed mid-turn
sat undelivered until Esc.

Now every step is classified by effect (read/verify/mutate/other; Bash
via isReadOnlyCommand + discovered-gate matchers), with one canonical
step signature shared by all ledgers:
- Bash reads join the searchToolCount ledger, so the CODEBASE-BRIEF
  advisory fires for shell-readers.
- Budget growth is earned only by mutate/verify/novel-read/other steps;
  read-repeats never grow the budget (spirals stall at base 15).
- Intent-aware one-shot read-spiral note: edit turns get 'summarize,
  then implement or ask'; investigate turns are never told to implement
  and only trip on read-repeat volume.
- No-progress signature counts novelty (novelStepCount) plus a monotonic
  substantive-answer latch instead of raw tool events, so re-read rounds
  strike toward the existing checkpoint while real mapping and real
  answers count as progress.
- Steering: session-resume gains an optional shouldYield hook polled at
  every completed tool-pair boundary; pending steering ends the cycle
  cleanly (done reason steering-yield, in-flight calls never aborted),
  is delivered as a real user turn with its images, refunds the
  continuation slot, and never strikes no-progress.
- Thresholds are config policy (cesarSearchNudgeThreshold /
  cesarReadSpiralThreshold / cesarReadRepeatThreshold), defaults 40/25/12.

Design ran the full ladder: nero killed the count-based v1 (FLAWED),
a 6-engine brainstorm converged on effect classification + earned
budget with steering as a genuine user turn, and the 6-engine role
review's 10 findings were verified — 8 fixed with discriminating
tests, 2 dismissed with evidence. Spec:
.claude/specs/cesar-native-loop-guards/spec.md

⚔️ Forged by [Agon](https://github.com/KERNlang/agon)

Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
Four verified findings from the pre-push branch review, all fixed with
discriminating tests (+17, now 4732):
- Continuation sends (steering delivery, auto-continue, closure,
  confirmation) ignored native tool_call chunks, so steered writes
  executed without mutation/verification/progress/display tracking and
  could dodge the verify-before-done gate. One shared
  _forwardContinuationToolCall helper now records them at all 7 sites,
  gated on hasNativeTools to avoid double-counting on XML engines.
- Read step signatures now carry offset/limit (and Grep/Glob their
  scope args), so paging a large file earns budget instead of counting
  as read-repeats.
- A zero-text steering-yield on the initial send now always reaches the
  delivery loop instead of waiting for a later turn.
- Successful unclassifiable ('other') Bash steps now suppress the
  edit-intent read-spiral note via a separate shellWorkStepCount —
  shell work we can't prove read-only must not draw a "you haven't
  implemented" nudge; effectfulStepCount keeps its strict
  mutate/verify meaning for gate logic.

Dismissed with evidence: the reported block-scope ReferenceError in
the steering drain (typecheck-proven in-scope), the "gate matchers
never assigned" claim (assigned at turn start, read lazily), and the
stale-signature strike after a yield refund (all signature components
are monotonic — a stale baseline can only read as progress).

⚔️ Forged by [Agon](https://github.com/KERNlang/agon)

Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
The plan-approval selector rendered ABOVE the plan markdown in the
pinned lower panel, so a multi-screen plan buried the question the
user had to answer. Now the plan body is committed as a normal
scrollable transcript block at proposal time and a compact 5-row
PlanApprovalPrompt is pinned directly above the composer; the bottom
chrome row budget accounts for exactly those 5 rows, and tall plans
seal into scrollback instead of inflating the fixed region.

Review of the change surfaced that rejecting a Cesar proposal was
entirely broken: both the keyboard '3. Reject' and /cancel routed to
the legacy plan runner's handleCancel, which reads ctx.currentPlan,
answered 'No active plan to cancel.' and left the proposal pinned.
New cancelPendingCesarPlan mirrors the approve path: cancels + saves
the plan, rewrites the on-disk record, releases the prompt, and
appends a [plan rejected] note to the chat session so Cesar can't
silently re-propose. plan-dismiss now carries an outcome and the
transcript appends a one-line record for superseded plans, so the
committed 'Status: awaiting_approval' snapshot can no longer lie
about the final state.

⚔️ Forged by [Agon](https://github.com/KERNlang/agon)

Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
@cukas
cukas merged commit e56f5f4 into main Aug 17, 2026
2 checks passed
@cukas
cukas deleted the fix/remove-no-brief-nudge branch August 17, 2026 16:16
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.

2 participants