Skip to content

feat(cron): skip background review on cron + usage audit logger (salvage of #18255) - #81254

Merged
kshitijk4poor merged 4 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/pr-18255
Aug 7, 2026
Merged

kshitijk4poor merged 4 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/pr-18255

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Contributor

Summary

Salvages the worthwhile portions of PR #18255 (cron token-leak mitigation): adds a skip_background_review flag on AIAgent to skip the _spawn_background_review fork on cron sessions, and a usage_audit.jsonl logger for per-fire cron token spend instrumentation.

The HERMES_CRON_MAX_TOKENS env var portion was dropped (conflicts with the no-user-facing-max-tokens policy). The docs/wave-2-deferred.md was also dropped (not appropriate for the repo).

What was salvaged

Three commits from @0xarkstar, cherry-picked onto current main:

  1. feat(agent): add skip_background_review flag to AIAgent constructor — new boolean flag threaded through init_agentAIAgent.__init__. Default False (unchanged behavior for CLI/gateway). Cron sets True.
  2. feat(cron): set skip_background_review=True — cron scheduler constructs AIAgent with the flag.
  3. feat(cron): add usage_audit.jsonl logger — append-only JSONL audit log per cron fire (tokens, duration, model, deliver target, error). Fail-safe (exceptions swallowed).

Follow-up fixes (our commit)

  • Fixed _usage_audit_path() to use _get_hermes_home() instead of hardcoded Path.home() / ".hermes" — profile-safe resolution (sweeper finding).
  • Rewrote skip_background_review tests to exercise finalize_turn() directly instead of duplicating the guard expression — catches divergence between production guard and tests (sweeper finding).
  • Added test verifying _usage_audit_path does NOT call Path.home().
  • Cleaned up "Phase 0.5" instrumentation comments.

What was dropped

  • HERMES_CRON_MAX_TOKENS env var — adds a user-facing max_tokens knob, conflicting with the standing policy that .env is for secrets only and behavioral config belongs in config.yaml.
  • docs/wave-2-deferred.md — internal planning doc, not appropriate for the repo.

Validation

Before After
Tests N/A (new) 14/14 pass
E2E N/A 6/6 pass
Lint clean clean
Cron suite 502 pass 502 pass (4 pre-existing failures in test_monitor_kind.py unrelated)

Closes #18255

0xarkstar and others added 3 commits August 7, 2026 23:37
Phase 8 of the Hermes Agent token leak mitigation plan
(ralplan-hermes-token-leaks.md §3.9). Adds a boolean kwarg
`skip_background_review` (default False) to AIAgent.__init__ that
suppresses the end-of-turn _spawn_background_review fork.

Each background review fork instantiates a new AIAgent with its own
~15K input tokens + up to 8 LLM iterations, accumulating ~30K tokens
per event in the worst case. On cron sessions there is no
human-in-the-loop benefit from the review (no skill-creation pressure,
nobody curating MEMORY.md), so the cost is pure waste.

The end-of-turn guard now reads:

    if (final_response and not interrupted
            and not getattr(self, "skip_background_review", False)
            and (_should_review_memory or _should_review_skills)):

skip_memory=True already disables the memory-review trigger; this
flag is the explicit single-switch off for both review paths.

Defaults to False, so behavior is unchanged for gateway/CLI callers
that omit the kwarg.

Tests: 5 new unit tests in tests/agent/test_skip_background_review.py
covering the default value, flag persistence, the gate short-circuit,
the gate fall-through, and a source-text assertion that the cron
scheduler sets the flag to True (separate commit).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-presence

Phase 8 wire-in + Vector 8 doc comment from
ralplan-hermes-token-leaks.md.

(1) Phase 8 wire-in: cron AIAgent construction now passes
    skip_background_review=True. This suppresses the end-of-turn
    skill/memory review fork (~30K tokens/event, ≤30K typical and
    ≤150K worst-case daily on bluenode) which has no human-in-the-loop
    value for cron sessions.

(2) Vector 8 doc comment: a one-line comment immediately above the
    AIAgent(...) construction documenting the verified-negative
    finding that title generation does not run on the cron path
    (maybe_auto_title is gateway/CLI-side only). Future contributors
    won't accidentally introduce title-gen here without realizing it
    would add ~600-1000 tokens/fire on a path that explicitly opts out
    of memory/review/title overhead.

No new tests required for the doc comment (no behavior change). The
skip_background_review wiring is covered by the existing source-text
assertion in tests/agent/test_skip_background_review.py.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ntation

Phase 0.5 of the Hermes Agent token leak mitigation plan: append a single
JSONL line to ~/.hermes/cron/usage_audit.jsonl after every cron LLM
invocation, capturing prompt/completion/total tokens, model, duration_ms,
deliver target, and error (when raised). Read from agent.session_*_tokens
which run_conversation already returns in its result dict.

Without this, we have no measured baseline to attribute token deltas to
subsequent mitigation phases. The plan's hard gate: observability lands
before any mitigation phase.

Writer NEVER raises — wrapped in a single try/except that logs a warning
on any json.dumps / mkdir / open failure so an audit-log bug cannot
break a cron job. Failure-path audit guard via locals() check covers
exceptions that fire before the fire_id is assigned.

No new dependencies, no new env vars (the plan rejected one in v2).

Tests: 7 new unit tests in tests/cron/test_usage_audit_logger.py covering
the success path, missing token info, swallowed writer exception, parent
dir creation, multiple appends, and unicode preservation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alt-glitch alt-glitch added type/perf Performance improvement or optimization P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management labels Aug 7, 2026
- Fix _usage_audit_path() to use _get_hermes_home() instead of hardcoded
  Path.home() / '.hermes' (profile-safe resolution, sweeper finding)
- Rewrite skip_background_review tests to exercise finalize_turn() directly
  instead of duplicating the guard expression (sweeper finding)
- Fix response_silent audit field to use _is_cron_silence_response()
  instead of the buggy SILENT_MARKER substring check it was meant to
  replace (simplify-code review finding)
- Remove dead 'model' in locals() guard — model is always in scope
  before the try block (simplify-code review finding)
- Extract _stub_agent_for_finalize() helper to eliminate ~40 lines of
  copy-pasted agent stubbing in tests (simplify-code review finding)
- Clean up 'Phase 0.5' instrumentation comments
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) August 7, 2026 18:33
@kshitijk4poor
kshitijk4poor merged commit 7307f88 into NousResearch:main Aug 7, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have type/perf Performance improvement or optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants