- On a Claude Code session/usage limit ('resets 7:10pm'), _call_claude_cli now
pauses IN PLACE until the stated reset time + CLAUDE_CLI_LIMIT_BUFFER_SECONDS
(default 60s past), then retries — up to CLAUDE_CLI_LIMIT_MAX_WAITS windows.
Parses 12-hour reset times to their next occurrence; falls back to a fixed
wait when no time is present. Makes long unattended runs survive reset windows.
- load_library() reports invalid capability-set JSON as a clean SystemExit
(line number + reason) instead of a traceback; fixed a trailing-comma typo in
data/capability_sets/dx02.json.
- Docs: USAGE.md + .env.example document the claude-cli provider and its knobs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capability targeting (new feature):
- loop --capability <SET|ALL> scopes which capability library the loop reasons
against. data/capability_sets/<name>.json (same schema as capabilities.json)
holds one-off targeted products; drop a file in and pass its name, no code
changes. First set: agentminder (Broadcom AgentMinder, agentic-AI identity).
- capabilities.set_active_set() swaps the active library; keyword pre-filter is
bypassed for small targeted sets so every signal is evaluated. New
'capability-sets' command lists them; run banner shows the active set.
LLM provider — the '429' was a disguised policy block:
- Anthropic rejects Claude Code OAuth tokens on /v1/messages for non-Claude-Code
traffic with a fake rate_limit_error (no anthropic-ratelimit-* headers). New
'claude-cli' provider runs inference through the sanctioned headless path
(claude -p --append-system-prompt --model), now the default provider.
- OAuth keychain token auto-refresh via headless claude when expired.
Resilience:
- STATE_DIR is overridable (macOS endpoint-security locked output/state via
com.apple.macl); load_memory tolerates PermissionError; exa usage counter
tolerates malformed files; run.py handles Ctrl-C cleanly (no traceback).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Relevance filter: evaluate all of an account's signals in one LLM call
(keyed array, chunked at 8) instead of one call per signal.
- Synthesizer: produce all of an account's briefs in one call (one object
per capability) instead of one call per capability. ~2 calls/account.
- llm: wrap JSONDecodeError in LLMError so callers fall back to mock instead
of crashing; disable Gemini thinking (thinkingBudget=0) to stop thinking
tokens truncating JSON; add 429 backoff.
- accounts: add Booz Allen, Dominion Energy, Hope Gas, Markel, GW Medical
Faculty Associates (verified domains; CRM tier captured in crmTier).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>