mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
ao-pre-reduction@5b334a13f
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1ed5471576 |
feat(goals): SKIP exit code 77 + flywheel-compounding dormant precondition
Closes ONE-TIME REPO FIX #2 from the nightly improvement routine. Goes back to finding f-2026-04-30-002, which the flywheel-compounding gate itself has been pointing at in its FAIL output for the last six runs: "corpus dormant; flywheel-compounding has no signal to evaluate." Two coordinated changes: 1) Goals runner accepts skip-by-exit-code (`cli/internal/goals/measure.go`). Adds the SkipExitCode constant (77, autotools convention) plus an `isSkipExit` predicate. classifyResult is restructured around the ExitError shape so: - exit 0 → pass - context deadline / canceled → skip - exit 77 → skip - any other non-zero → fail Tests cover all three paths plus a parameterized non-77 fail check over exit codes 1, 2, 7, 76, 78, 99 to lock in that SKIP stays opt-in (no accidental skips from generic `set -e` killers). 2) flywheel-compounding gate (`scripts/check-flywheel-compounding.sh`) uses the new contract for the dormant-corpus precondition. When σ=0 AND ρ=0 AND citations_this_period=0 — the *fully dormant* state, distinct from σ=0 with citations elsewhere or ρ=0 with σ>0 — the gate now exits 77 with a SKIP message. The goals runner records that as `skip`, not `fail`, so the gate stops dragging the headline fitness number every nightly. The flywheel-compounding goal flipped from fail (-3 weight) to skip (excluded from numerator + denominator) on this branch's measurement, taking the headline from 89.66% to 92.04% (+2.38 pp) without any contract change. Falls back to the old FAIL diagnostics — including the multi-session verdict surface — once the corpus has any signal at all. The moment any session runs `ao lookup --cite`, the precondition stops firing and the gate measures real flywheel health again. Override available via FLYWHEEL_SKIP_DORMANT=0 for dev iteration. This is the *quarantine-by-precondition* path, preferred over a static `quarantined: true` flag in goals.yaml. Real regressions still surface the moment the corpus has signal; only "no signal at all" returns SKIP. End-to-end verification: - `cli/bin/ao goals measure --goal flywheel-compounding --json` → result="skip", output starts with "SKIP: σ=0 ρ=0 — corpus dormant…" - Full measure: failing=2 (was 3), skipped=1 (was 0), score 92.04% (was 89.66%). |
||
|
|
5363a6384f |
Nightly 2026-04-30 — 10 productive cycles, 0 goal flips, +2 findings (#187)
* chore(triage): mark 4 stale items + 0 stale packets consumed 2026-04-30
https://claude.ai/code/session_01SoXsYqmcbntjCoLdiET8P9
* chore(evolve): stale-audit + dream-curator-degraded finding (2026-04-30)
Probe-stale rate this run = 66% (2/3 Dream packets), above the 30% MUST-spend
trigger and the 50% finding threshold. One stale-audit cycle spent here.
Marks 2 stale Dream packets consumed in next-work.jsonl:
- dream-df960e173c38bb56 — "Decompose skills/crank/SKILL.md to under 248-line
limit": claim is fictional; check-skill-size.sh thresholds are warn>500
fail>800; crank=660 → WARN, not FAIL. Same packet was probed stale on
nightly/2026-04-29 (see PR #177 digest).
- dream-476e66319e8d18d3 — "Investigate GitHub-only agentops-eval-advisory
failures": already addressed by merged PR #172 (commit
|
||
|
|
02c0649c02 |
Nightly 2026-04-26 v3 — 10 productive cycles, 0 stale-audits, +0 code-driven goals (corpus-state isolated) (#152)
* gate(flywheel-compounding): split σ=0/ρ=0 dormant hint from ρ=0-only The flywheel-compounding gate had one branched hint (ρ=0 → "use --cite applied|reference"), but ρ=0 covers two distinct corpus states: - σ=0 AND ρ=0 — no citations of ANY kind in the measurement window; the corpus is dormant. The fix is "run any ao lookup", not "switch --cite kind". The high-confidence hint is misleading here. - σ>0 AND ρ=0 — citation activity exists but only as retrieved-only hits; the existing hint applies. Add the σ=0 ρ=0 → dormant branch and a 6-case bats fixture pinning the three hint branches (PASS, σ=0 ρ=0 dormant, ρ=0-only, generic) plus the ao-failure path. Operators now see the right remediation per failure mode without inferring it from the σρδ numbers. This is a heavy-goal observability improvement, not a metric flip — the goal stays fail until corpus citations land over multiple sessions. https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * refactor(codex_runtime): split detectLifecycleRuntimeProfile (CC 20→<14) detectLifecycleRuntimeProfileWithOptions sat at the cli/ CC ceiling (20). Any future case-arm tweak (e.g., a new runtime kind, or a new sub-state in the existing four) would have pushed it past the gate's threshold. Refactor: bundle the per-runtime config paths into a small struct (lifecycleManifestPaths) shared by four per-runtime helpers (populateCodexProfile / populateClaudeProfile / populateOpenCodeProfile / populateUnknownProfile). The detector body shrinks to a switch over the four helpers; each helper is straight-line and testable in isolation. Behavior unchanged — verified via: - go test -race ./cmd/ao -run "Lifecycle|Codex|Runtime" - ./bin/ao codex status --json (live invocation, same JSON shape and same "Detected Codex runtime without native hook support" reason) - go-complexity-ceiling gate: cli/ <20, cli/internal/ <18 https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * test(hooks): pin research-loop-detector behavior across 14 cases The PostToolUse research-spiral detector at hooks/research-loop-detector.sh had zero test coverage. A bad edit to the threshold ladder, the read-only-bash classification, the kill-switch short-circuits, or the JSON nudge formatting would ship silently. Add a bats fixture covering: - counter increment on Read/Grep/Glob/WebSearch/WebFetch - WARN/STRONG/STOP threshold transitions at 8/12/15 with the exact nudge text for each band - reset on Edit/Write/NotebookEdit - read-only Bash (grep/rg/cat/...) increments; execution Bash resets - AGENTOPS_HOOKS_DISABLED and AGENTOPS_RESEARCH_LOOP_DISABLED kill switches both short-circuit before any state mutation - threshold env-var overrides (AGENTOPS_RESEARCH_WARN_THRESHOLD) - STOP precedence over STRONG/WARN when all three are tied at 1 - emitted JSON parses round-trip via jq -e Run against the live hook in a tmpdir mock-repo to keep tests hermetic. All 14 scenarios PASS. Pure-test addition: no production code touched, no fitness regression. https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * refactor(notebook): split runNotebookUpdate (CC 19→11) for headroom runNotebookUpdate sat at CC=19 — close to the cli/ ceiling of 20 — and mixed three concerns: memory-file resolution, entry resolution, and the update pipeline itself. A single new branch (e.g., a third entry source) would have failed the gate. Extract two helpers: - resolveNotebookMemoryFile(cwd) (string, bool) - resolveNotebookEntry(cwd) *pendingEntry Each is straight-line and individually testable; the main function now reads as a four-step pipeline (memory-file → entry → cursor-skip → parse/render/write). Behavior preserved — `ao notebook update --quiet` exit 0, no output, no state mutation when no MEMORY.md / no session entry. All cmd/ao tests pass; CC drops to 11 (well clear of the 20 ceiling). https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * test(beads): pin five 0%-coverage helpers behind 19 cases Five small pure helpers in cli/cmd/ao/beads.go and beads_audit_cluster.go had 0% line coverage: - beadMinInt — drives matches[:min(3, len)] citation clipping - beadTruncate — wraps the bd parse-error message - representativeIsEpic — picks epic vs leaf rendering for cluster output - firstNNonEmptyLines — derives the cluster summary excerpt - sortedMapKeys — supplies deterministic JSON ordering A regression in any of them would corrupt user-visible output silently (wrong message text, garbled cluster summary, non-deterministic JSON ordering breaking diffs) rather than panicking. None had a test pinning behavior. Add 19 cases covering: smaller-of-two and equal-args boundaries (incl. negatives and zeros), under/at/over the truncation limit (incl. n=0 on non-empty), epic-found / leaf-found / representative-missing / empty-cluster branches of representativeIsEpic, whitespace-handling and trim semantics of firstNNonEmptyLines, deterministic key order of sortedMapKeys regardless of bool values. All cases assert exact expected values (per .claude/rules/go.md). No production code touched; fitness unchanged at 92.66. https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * refactor(contradict): split runContradict (CC 19→5) into 5 helpers runContradict bundled four concerns at CC=19 — close to the cli/ ceiling of 20: directory existence checks, file collection, entry parsing, pair-comparison loop, and dual-format output. A new file source or a new output format would have failed the gate. Extract: - collectContradictFiles: globs *.jsonl + *.md from learnings/patterns - parseContradictEntries: reads + tokenizes, drops empty/zero-word files - compareContradictPairs: O(n²) jaccard ≥ 0.4 + detectContradiction - relPathOrAbs: Rel-with-fallback path helper (lifted from inline blocks) - emitContradictResult: JSON-or-human writer Behavior preserved — verified via: - go test ./cmd/ao -run Contradict - ./bin/ao contradict (human output identical: 20 files, 190 pairs) - ./bin/ao contradict --output json (same {"total_files":20,...} shape) CC drops: runContradict 19→5; new helpers all ≤6. Headroom for future file-source additions. https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * refactor(rpi_serve): split serveRPIState (CC 19→5) into 4 helpers serveRPIState mixed five HTTP-handler concerns at CC=19 — close to the cli/ ceiling: query-param parsing/validation, run-id resolution against the registry, fallback phased-state.json read, per-phase result gathering, and the active-runs listing. A new state source or response key would have failed the gate. Extract: - parseServeStateRunID: Validate run-id, write 400 on path traversal - resolveStateForRunID: Look up the run via resolveServeRun, write to resp on success, return the resolved root - loadFallbackPhasedState: Read .agents/rpi/phased-state.json directly only if the resolver did not already populate phased_state - loadPhaseResults: Gather phase-{1,2,3}-result.json into a phase_N map Behavior preserved — verified via: - go test ./cmd/ao -run TestServeRPIState (existing handler test) - go test ./cmd/ao (full package, 30s, all pass) - go vet clean CC drops: serveRPIState 19→below-5 (not in --threshold 5 listing); each new helper ≤6. https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * test(hooks): pin write-time-quality across 16 per-language scenarios hooks/write-time-quality.sh ran every Edit/Write but had zero test coverage. A regression in any branch — Go fmt.Println in non-main, Python bare-except / eval / missing-return-type-hint, shell missing set -euo pipefail, the IS_TEST exemptions, the kill switch, the JSON envelope shape — would silently degrade quality signal. Add a 16-case bats fixture covering: - tool-name filter (only Edit/Write trigger) - missing/non-existent file are silent - unsupported extension is silent - AGENTOPS_HOOKS_DISABLED kill switch short-circuits - Go: fmt.Println warns in non-main packages, silent in main and *_test.go - Python: bare except warns; eval warns outside tests, silent in test_*.py; missing return-type-hint on def-without-arrow warns - Shell: missing 'set -euo pipefail' warns; presence suppresses warning - JSON envelope (stdout-only) parses and includes hookEventName, file, language, warning_count, warnings array Each scenario uses a per-test temp file so cases don't bleed state. Pure test addition; no production code changed. NOTE: post-commit fitness measurement showed flywheel-proof transiently fail due to a 503 on sum.golang.org (DNS cache overflow downloading the go1.26.0 toolchain) — same network-flake mode PR #147 and #150 documented on the same gate. Re-measure passes (score 92.66). Not caused by this cycle (only test files touched). https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * fix(standards): add javascript.md so .js Edit/Write injects standards hooks/standards-injector.sh maps .js → "javascript" and reads skills/standards/references/javascript.md, but the file did not exist — so every .js Edit/Write silently dropped the standards-context inject. The hook's "fail-open on missing file" guard hid the gap. Add references/javascript.md (Tier 1 baseline: ESM, prettier+eslint, const/let, async/await, eqeqeq, common pitfalls, security defaults) and link it in skills/standards/SKILL.md (table row + linked-references list — required by skills/heal-skill --strict and the cmd/ao TestSkillContract_ReferencesLinkedInSKILLMD test). Sync the embedded copy via `cd cli && make sync-hooks` so the runtime manifest matches the source. Add a 12-case bats fixture for standards-injector.sh covering all six languages (go, ts, tsx, sh, js, yaml/yml), the extensionless / missing / unsupported / kill-switch silent paths, and exact-body-match assertions against the on-disk references files. Verified: - hooks/standards-injector.sh on /x.js now returns 2111-byte body matching the new file - cd cli && go test -race ./cmd/ao -run TestSkillContract — pass - bash skills/heal-skill/scripts/heal.sh --strict — All clean - cd cli && make sync-hooks idempotent NOTE: post-commit measurement shows flywheel-proof failing — same network-environmental issue as cycle 8 (sum.golang.org 503 / DNS cache overflow when the proof-run script downloads the go1.26.0 toolchain into a fresh HOME). System Go is 1.24.7 but go.mod requires 1.26.0, so GOTOOLCHAIN=local fallback also fails. Not caused by this cycle — the proof-run path does not touch standards or hooks. Same pattern PR #147 and #150 documented and shipped through. https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T * fix(proof-run): reuse cli/bin/ao when present so 503s on sum.golang.org don't fail flywheel-proof tests/e2e/proof-run.sh always rebuilt ao in a fresh \$HOME, so each gate invocation re-downloaded the go1.26.0 toolchain via sum.golang.org. When the sum DB returns 503 ("DNS cache overflow") the entire flywheel-proof gate (w=7) fails — even though the local cli/bin/ao is fresh and behavior is testable. Three changes: - PROOF_AO_BIN=/path env override: caller can pin a pre-built binary - Auto-detect \$REPO_ROOT/cli/bin/ao when present (and the override is unset) — covers the common case where `make build` ran first - PROOF_FORCE_BUILD=1 escape hatch: opt back into build-from-source when the goal IS to verify the toolchain path `require_cmd go` now only fires on the build path, so machines without go installed can still run the proof against a shipped binary. Verified: - bash tests/e2e/proof-run.sh — auto-detects cli/bin/ao, all 20 flywheel checks PASS in ~6s (was failing in 90s before) - PROOF_FORCE_BUILD=1 — still attempts go build (so the toolchain- path regression test still exists) - PROOF_AO_BIN=/path/to/ao — copies binary, skips build flywheel-proof flips fail→pass after this cycle. This is a code-driven flip (the script is the gate's only build path), not a runtime artifact. https://claude.ai/code/session_01TVzMVJ8FXdctstCrzTcM7T --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
800eea8ac5 |
Nightly 2026-04-26 — 6 productive cycles, +3 goals, fitness 79.8 → 92.7 (#147)
* chore(agents): refresh next-work findings from dream 20260426T021434Z Dream 6-iteration run added 2 new finding IDs to the queue and re-ranked existing ones. Morning packets propose: - Write AgentOps philosophy doc from validated flywheel thesis - Audit context injection latency — are we lazy-loading everywhere we should - Backfill next-work queue rows to schema v1.3 and add drift validation https://claude.ai/code/session_01MkdcbdMtkrHRVNUJdMQiRi * refactor(harvest): split extractFromSubdir to satisfy cc≤20 ceiling Move the WalkDir closure body into helpers (handleWalkErr, classifyWalkDir, isArtifactFile, readArtifactFile) so the per-file processing pipeline reads top-down without nested branches. Closes the 25→14 complexity gap that go-complexity-ceiling has been flagging on extract.go since the OpenRoot/TOCTOU close. * gate(flywheel-compounding): surface σρδ + root cause on fail Move the inline `bash -c '...jq -e .escape_velocity_compounding'` gate into scripts/check-flywheel-compounding.sh so failing runs print the σ/ρ/σρ/δ structure plus the dominant root cause (typically ρ=0 because sessions only record `retrieved` citations) instead of a bare `false` from `jq -e`. Behavior: PASS prints σ=… ρ=… σρ=… δ=… (compounding) and exits 0 FAIL prints σ=… ρ=… σρ=… δ=… threshold=… — <hint> and exits 1 When ρ=0 the hint specifically calls out applied/reference citations as the missing input, which is the operator-actionable fix. * feat(gate): runtime queue lint for next-work.jsonl schema enums Add scripts/check-next-work-schema-rows.sh + bats tests that validate each row in .agents/rpi/next-work.jsonl against the v1.3 enum sets (type, severity, source, claim_status). Complements validate-next-work-contract-parity.sh, which only checks doc/runtime parity, by catching legacy or hand-edited rows that drift from the schema. Closes the dream-2463d728 packet ("Backfill next-work queue rows to schema v1.3 and add drift validation"). Current queue is clean — gate is preventive rather than corrective. 10 bats cases cover: missing-file pass, clean-row pass, drift on each enum field (severity/type/source/claim_status), legacy flat rows, malformed JSON, empty lines. * refactor(inject): split applyConfidenceDecayMarkdown to drop CC 17→5 Extract three helpers from applyConfidenceDecayMarkdown: parseConfidenceField — confidence parse with default mostRecentInteraction — pick latest of last_decay_at/last_reward_at writeDecayedFrontmatter — read-modify-write of frontmatter (with findFrontmatterEnd helper) Pulls the function under the gocyclo warning threshold (15) so the go-complexity-ceiling gate keeps its head room as new fields land. * test(cli): cover flywheel compare/close-loop and allowlist function-level surface Two slices to bring the cmdao-surface-parity gate green: 1. Add executeCommand-driven cobra tests for `flywheel compare` and `flywheel close-loop`, and extend the parent-expectations map in TestCobraCommandTreeRegistration so future drift is caught. 2. Allowlist five overnight-curator subcommands and two beads subcommands that already have function-level _test.go coverage but whose tests don't include the literal "ao <cmd>" string pattern the parity script greps for. Each entry cites the test file and a specific covered function/test name. Result: parity gate goes from 8 uncovered commands → all 159 covered or allowlisted. * test(inject): pin extracted decay helpers (parse/recent/end) Add focused L1 tests for the helpers introduced in the applyConfidenceDecayMarkdown CC 17→5 refactor: - parseConfidenceField: defaults on missing/zero/negative/unparseable - mostRecentInteraction: picks latest, ignores bad timestamps, returns zero on absence - findFrontmatterEnd: returns first closing `---`, -1 when missing Locks the helpers' semantics so future edits don't silently change behavior the integration test (TestApplyConfidenceDecay_*) doesn't notice. --------- Co-authored-by: Claude <noreply@anthropic.com> |