Skip to content

fix: treat pending gh pr checks as pending (#132) - #134

Merged
lukemaj merged 2 commits into
mainfrom
fix/132-gh-pr-checks-pending
Oct 19, 2026
Merged

lukemaj merged 2 commits into
mainfrom
fix/132-gh-pr-checks-pending

Conversation

@lukemaj

@lukemaj lukemaj commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What: gh pr checks exit 8 is stored as pending, including scripts whose status comes from that command, and excluded from failure diagnostics and report counts.
Why: Native command status marks pending checks as failed; the first fix also missed real scripts with preceding commands, redirects, and AND chains.
So what: Round-2 behavior is preserved on current main with version 1.4.1; the primary agent can assess the rebase evidence, and merging remains a Human Gate that triggers release publication.

Closes #132.

Behavior

One shared predicate owns the exception at ingest and during existing-ledger correction. It lexes shell words and operators without executing input, preserving quoting and skipping heredoc bodies. It chooses the final command list after newline/semicolon separators and removes redirections before identifying gh pr checks.

In an && chain, any failing stage can produce the final status. Classification therefore requires every possible stage to be gh pr checks or one of the observed gates that cannot explain exit 8: the supported git rev-parse HEAD / git status forms and gh pr view without jq/template/browser execution. Ambiguous gates, including pytest, remain failed. Pipelines, OR lists, substitutions, and unsupported syntax in the final list remain unclassified as pending. gh pr checks 353; pytest, gh pr checks 353 | cat, and plain pytest exit 8 remain failed; exit 1 remains failed.

Pending is neither a failure nor a passing result. diagnose, compare, task reporting, and publishing share the failure predicate.

The next writable ledger initialization during sync runs correction version 2, including ledgers already marked version 1. It uses stored commands and exit codes, so it needs no native replay and covers ledger-only events.

Contribution to the Objective: trustworthy behavior evidence without false failure counts from ordinary CI polling.

Rebase and exact candidate

Conflicts and resolution:

  1. VERSION: selected main's 1.4.0 as the input, then versionctl prepare patch generated 1.4.1.
  2. .claude-plugin/plugin.json: selected main's manifest, then versionctl updated only the declared version mirror to 1.4.1.
  3. .codex-plugin/plugin.json: same resolution.
  4. .grok-plugin/plugin.json: same resolution.
  5. CHANGELOG.md: retained the complete 1.4.0 entry from main, then versionctl generated this fix's entry under 1.4.1. The obsolete 1.3.1 entry was not retained.
  6. agent_observer/privacy.py: combined this PR's pending tool-result status with main's attempted and pending read/skill-read statuses. Retained all other upstream parser/privacy changes, including privacy version 10.

analysis.py and ingest.py merged automatically. Their upstream successful-read filtering and duration correction remain intact. The status predicate, marker-2 correction, tests and fixtures are byte-identical to the reviewed head.

There are no authored behavior changes beyond versioning and conflict resolution. The second task commit's patch is identical; the first differs only in version values/changelog location and the privacy conflict's upstream context. Zero-context implementation/test patch IDs match exactly:

$ git diff --unified=0 1fbbb0f..7f79f2c -- agent_observer tests | git patch-id --stable
962eca11be57dce9bbdeaacecaeda9896e618814 0000000000000000000000000000000000000000
$ git diff --unified=0 eda2c8d..090e87c -- agent_observer tests | git patch-id --stable
962eca11be57dce9bbdeaacecaeda9896e618814 0000000000000000000000000000000000000000
Full git range-diff
1:  7e53f4e ! 1:  36e275f fix: classify pending gh pr checks without false failures (#132)
    @@ .claude-plugin/plugin.json
     @@
      {
        "name": "agent-observer",
    --  "version": "1.3.0",
    -+  "version": "1.3.1",
    +-  "version": "1.4.0",
    ++  "version": "1.4.1",
        "description": "Measure agent work across Codex, Claude Code, OpenCode and Grok Build from native records, and compare behavior by model and AgentsMD version.",
        "author": {
          "name": "toolboxmd",
    @@ .codex-plugin/plugin.json
     @@
      {
        "name": "agent-observer",
    --  "version": "1.3.0",
    -+  "version": "1.3.1",
    +-  "version": "1.4.0",
    ++  "version": "1.4.1",
        "description": "Measure agent work across Codex, Claude Code, OpenCode and Grok Build from native records, and compare behavior by model and AgentsMD version.",
        "author": {
          "name": "toolboxmd",
    @@ .grok-plugin/plugin.json
     @@
      {
        "name": "agent-observer",
    --  "version": "1.3.0",
    -+  "version": "1.3.1",
    +-  "version": "1.4.0",
    ++  "version": "1.4.1",
        "description": "Measure agent work across Codex, Claude Code, OpenCode and Grok Build from native records, and compare behavior by model and AgentsMD version.",
        "author": {
          "name": "toolboxmd",
    @@ CHANGELOG.md
     @@
      # Changelog
      
    -+## [1.3.1] - 2026-10-19
    ++## [1.4.1] - 2026-10-19
     +
     +### Changed
     +
     +- Treat gh pr checks exit 8 as pending and correct existing ledgers
     +
    - ## [1.3.0] - 2026-10-19
    + ## [1.4.0] - 2026-10-19
      
      ### Added
     
      ## VERSION ##
     @@
    --1.3.0
    -+1.3.1
    +-1.4.0
    ++1.4.1
     
      ## agent_observer/analysis.py ##
     @@ agent_observer/analysis.py: def _changed_paths(event) -> set:
    @@ agent_observer/privacy.py: _COMMON_STATUS = frozenset({
          "tool_call": _COMMON_STATUS | frozenset({"cancelled"}),
     -    "tool_result": _COMMON_STATUS | frozenset({"cancelled"}),
     +    "tool_result": _COMMON_STATUS | frozenset({"cancelled", "pending"}),
    -     "read": _COMMON_STATUS | frozenset({"cancelled"}),
    -     "skill_read": _COMMON_STATUS | frozenset({"cancelled"}),
    +     "read": _COMMON_STATUS | frozenset({"cancelled", "attempted", "pending"}),
    +     "skill_read": _COMMON_STATUS | frozenset({"cancelled", "attempted", "pending"}),
          "lifecycle": frozenset(
     
      ## tests/fixtures/codex-pr-checks-pending.jsonl (new) ##
2:  7f79f2c = 2:  090e87c fix: classify status-producing gh checks in stored scripts

Proof on the rebased head

  • python3 -m unittest tests.test_pr_checks_pending: all 7 tests passed.
  • python3 -m unittest discover -s tests: 918 tests passed in 145.371s on the rebased head. Existing ResourceWarnings were emitted; there were no failures.
  • python3 -m compileall -q agent_observer tests scripts: passed.
  • git diff --check origin/main..HEAD: passed.
  • bin/agent-observer --version: 1.4.1.
  • versionctl release-check: passed on the new head.

Historical red/green evidence is retained: before the round-2 fix, the regression ran 6 tests with 6 assertion failures (five sampled real target subcases and the marker-1 ledger case); after the fix, all 7 passed. Real sanitized targets cover 860917, 145983, 288772, 90306 and 894845, plus native record 363608. No transcript/private text is committed.

Fresh ledger-copy correction after rebase

PYTHONPATH="$PWD" python3 /tmp/observer-132-copy-proof.py used SQLite backup from a read-only live connection, then called db.init_db() twice on the private temporary copy. No sync ran against the live ledger or the copy.

Fresh snapshot: 579,894 events across 40 tables, with no prior correction marker. First pass set marker 2 and changed 23 event statuses from failed to pending:

90306, 119998, 145983, 155128, 206254, 207060, 288772, 306957, 318056, 354690, 363608, 860810, 860917, 862876, 894783, 894845, 894850, 911037, 924461, 930102, 930205, 939267, 942377.

All original 19 supplied rows are pending; none remain failed. The four additional rows also have gh pr checks as the status-producing command and exit code 8. The only other logical change was creating the marker with value 2. Hash comparisons over every table, every event column except status, and the complete SQLite schema confirmed no unrelated changes or changed event identities/counts.

Second pass: zero status changes, all table/schema values unchanged, marker still 2. The private copy was deleted after verification. The live ledger was opened read-only and never synced or corrected.

Version, review and delivery

versionctl prepare patch --reason 'Treat gh pr checks exit 8 as pending and correct existing ledgers' prepared 1.4.0 -> 1.4.1 after resolving the old version against current main. All three plugin mirrors and the changelog agree. Version 1.4.2 is reserved for #135 after this PR, per the current instruction.

Round-2 review passed on the previous head. No review status is transferred to the rebased SHA, and no reviewers were dispatched. No merge, tag, release, plugin installation or live-ledger correction was performed. The existing low notes (unobserved early set -e termination and unsupported &> redirects) remain unchanged, as requested.

Website/SEO impact: none; internal evidence classification changes no public command, URL or website content.

The Observer cost comment is republished after the lease push. Measurement/pricing gaps remain explicit.

Elon record

  • Requirements and who asked: Luke requested Treat pending gh pr checks (exit 8) as pending, not failed #132 and now a rebase onto released v1.4.0, preserving reviewed behavior, preparing 1.4.1 and repeating proof on a fresh ledger copy.
  • Deleted: new behavior, new dependencies, extra version transitions, live-ledger sync and reviewer dispatch; this continuation only integrates the reviewed fix with current main.
  • Bottleneck: main moved after review, causing version/changelog and status-enum conflicts; rebase and prove the same task patch against the released base.
  • Checked myself: inspected current Git/GitHub state, resolved all six conflicts, compared range-diff and equal implementation/test patch IDs, reran tests, and corrected a fresh read-only-source ledger copy twice with table/schema checks.

@lukemaj

lukemaj commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Agent work on this PR

Estimated cost unknown · 18 responses · 22 sessions · 2.1 h wall time

Model Responses Tokens Estimated cost
grok-4.7 (grok, medium) 18 >=30,814,330 (lower bound) unknown

Flags: 1 human correction · 1 large tool output · 5 repeated commands · 2 repeated failures · 57 repeated reads · 8 repeated skill loads · 5 tests edited after a failure · 1 session without usage records · 18 unpriced responses

Details: snapshot, prices, coverage, counters
  • Task toolboxmd/agent-observer#132: outcome unknown (recorded acceptance only; a finished process never implies it).
  • Proof: Treat pending gh pr checks (exit 8) as pending, not failed #132
  • Snapshot 0f99c16c73ca841075ca3459f2cc8dcc80aa8148baf88031148de39e1d7185f7, records up to 2026-10-19 15:16 UTC.
  • 22 sessions on claude, codex, grok; AgentsMD 17.3.1.
  • The total includes work shared with 11 other tasks, counted whole in each, so sums across PRs overlap.
  • Not counted: 726 responses (at least $77.66) in sessions shared with other PRs that worked in no single PR's checkout.
  • 61 responses in these sessions worked on other PRs and are counted there.
  • Totals reconcile with the measured sessions: yes. Evidence complete: no.
  • Prices: list-price estimate from T3 local rate table (path withheld) as of 2026-10-18, schedule 414551dda4c47258113dcfa46a5dfa5aa512406e3dfcadcca3381421595c5588. Unknown prices stay unknown, never zero.
    • T3 LiteLLM rate table when present; bundled schedule covers the rest.
    • Model price sources: T3 local rate table (path withheld).
    • Unpriced: unknown model (18).
  • Native session usage or worker ownership is unavailable.
  • Harness-reported cost: none reported.
  • Usage totals are not billing. Subscription spending is separate and is never posted as spend.
  • Crashed runs are counted separately: 0.

Token counters by model (native counter semantics; never added across semantics):

  • grok-4.7 (grok, medium), grok counters: input includes cached, output includes reasoning: input >=30,192,455 (lower bound); cache-read >=28,293,504 (lower bound); cache-write >=0 (lower bound); output >=621,875 (lower bound); reasoning >=420,622 (lower bound); harness total >=30,814,330 (lower bound).

Generated tokens (reasoning and other output are disjoint; other output includes code, tool calls and replies):

Model Reasoning Other output Reasoning share Split known for
grok-4.7 (grok, medium) unknown unknown unknown 0 of 18

Selected rates (USD per million tokens). These rates value the report at the selected schedule date; they do not establish historical prices or subscription spending.

Model Input tier Input Cache read Cache write Other output Reasoning
grok-4.7 all unknown unknown unknown unknown unknown

Other output and reasoning are priced without double counting inclusive native output. Missing rates remain unknown.

Local measurement from native records; usage totals are not billing. Updated in place by agent-observer publish.

@lukemaj

lukemaj commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Independent review of exact head 7e53f4e (round 1)

  • Grok 4.7 (medium): FAIL.
    1. Blocking: pending_pr_checks() (agent_observer/command_status.py:16, :25) rejects any script with a newline, ; or &&. Codex stores the bash -lc script itself as target. On a copy of the bestia ledger the one-time correction (db.py:720) changed only 4 of the 19 exit-8 gh pr checks events in 2026-10-12..19 (363608, 860810, 894783, 911037). The other 15 are compound scripts whose status-producing last command is gh pr checks (e.g. 860917 tail …; gh pr checks 114 …, 145983, 288772, 306957; 90306 ends with a redirect). db.py:723 then sets pr_checks_pending_version=1, so a later fix would never revisit them.
      Cleared: version bump consistent; _failed/_passed handle pending; report, diagnose, compare and publish go through _failed; health and availability do not read status; no other column changed on the copy; tests fail before and pass after.
  • Muse Spark 1.3 (xhigh): still running; its findings will be folded into round 2.

Coordinator adjudication: finding 1 accepted (acceptance criterion: existing ledgers corrected; the real events are the target, not only the fixture). I confirmed the 19 rows and their compound shapes on the live ledger read-only.

@lukemaj

lukemaj commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Round 1, second reviewer (same head 7e53f4e): Muse Spark 1.3 (xhigh): PASS. It confirmed the stored Codex shape for standalone gh pr checks, fail-before/pass-after, every status consumer handling pending, and migration idempotence. Non-blocking: wrappers and redirections (2>&1, > file, env, time) stay failed; a load-dependent failure of test_hung_scan_tools_are_unavailable on head and base (filed as #136, unrelated).

Adjudication: the round stays FAIL. Muse treated rejecting compound scripts as safe, but the acceptance criterion is correcting the real events, and 15 of 19 real ones are compound scripts ending in gh pr checks (Grok's finding, confirmed on the live ledger). Muse's redirect note is folded into the fix (event 90306).

@lukemaj

lukemaj commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Independent review of exact head 7f79f2c (round 2)

  • Grok 4.7 (medium): PASS. On a copy of the bestia ledger all 21 exit-8 rows (the 19 window ids plus 930102, 930205) became pending and nothing else changed; each row's status-producing command checked individually. False-positive probes (; pytest, | tee, || true, && pytest, if, heredocs, quotes, subshells) stay failed. Residual: a set -e script whose earlier command exits 8 would be marked pending; no stored script does this.
  • Muse Spark 1.3 (xhigh, cavallo): PASS. On a copy of the cavallo ledger 127 of 137 exit-8 gh pr checks events became pending; the 10 that stay failed have ambiguous && stages, correct per the rule. 30+ false-positive probes clean. Low: &> / &>> redirects stay failed (safe direction; none stored). Pre-existing flaky health test is Flaky test: test_hung_scan_tools_are_unavailable fails under load #136.

Coordinator adjudication: round-1 blocking finding resolved; no open required findings. Both low notes accepted as not required. Ready for merge approval. Version note: PR #135 also takes 1.3.1; whichever merges second rebases to 1.3.2.

@lukemaj
lukemaj force-pushed the fix/132-gh-pr-checks-pending branch from 7f79f2c to 090e87c Compare October 19, 2026 15:34
@lukemaj

lukemaj commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Independent review of the rebased head 090e87c (onto v1.4.0, version 1.4.1)

  • Opus 5.5 (medium) (replacing Grok, whose Build sessions fail on a provider 402; see lukemaj/promachos#9): PASS. git range-diff shows the implementation commit identical to the round-2-passed 7f79f2c; non-version diffs against the base are identical; privacy.py only adds pending to tool_result and keeps main's read/skill_read statuses; VERSION, manifests and CHANGELOG at 1.4.1 with 1.4.0 kept; 918 tests OK; on a ledger copy 23 rows became pending (the 19 reviewed window ids, identical list, plus 930102, 930205, 939267, 942377, each a standalone or last-command gh pr checks 131 exit 8), marker 2, nothing else changed.

Coordinator: the 19 ids match the round-2 list exactly. Ready for merge approval.

@lukemaj

lukemaj commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Dispatch rule for every remaining round on this PR (Luke, 2026-10-19 17:55 Warsaw): launch no new threads on cavallo. Run Muse Spark 1.3 xhigh (Muse Code) and every other reviewer or worker on bestia, or on rocky. Muse Code is available on bestia (login present since 16:59). Already-running cavallo reviewers may finish; nothing new starts there.

@lukemaj
lukemaj merged commit ed90f95 into main Oct 19, 2026
2 checks passed
@lukemaj
lukemaj deleted the fix/132-gh-pr-checks-pending branch October 19, 2026 16:26
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.

Treat pending gh pr checks (exit 8) as pending, not failed

1 participant