Skip to content

Add structured local failure history for conductor jobs#525

Open
morluto wants to merge 6 commits into
repoprompt:mainfrom
morluto:agent/423-local-diagnostics
Open

Add structured local failure history for conductor jobs#525
morluto wants to merge 6 commits into
repoprompt:mainfrom
morluto:agent/423-local-diagnostics

Conversation

@morluto

@morluto morluto commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Why

Conductor preserves raw logs and terminal summaries, but contributors cannot group recent failures by cause without repeatedly parsing those logs. Storing raw output in a new aggregate would also duplicate sensitive data.

This PR adds a bounded local record containing safe job metadata and references to existing local artifacts.

Closes #423.

What changes

  • Adds a versioned FailureRecord schema.
  • Persists one structured record for terminal jobs.
  • Adds ./conductor diagnostics recent-failures with operation, class, age, and limit filters.
  • Starts with a bounded taxonomy: timeout, source mutation, compiler/test failure, process cleanup, heavy/lane wait, cancellation, infrastructure/RPC failure, and unknown.

Privacy boundary

Aggregate records exclude raw logs, source contents, prompts, transcripts, credentials, environment dumps, and arbitrary operation arguments. Only explicitly safe arguments and allow-listed toolchain metadata remain.

Persistence design

  • atomic temporary-file replacement;
  • serialized store access;
  • rollback-safe summary/record writes;
  • one write per ticket under status/wait races;
  • persistence owned by terminal-job lifecycle;
  • bounded retention matching terminal jobs;
  • safe defaults for older or partial records.

This is local developer diagnostics, not telemetry. No remote reporting path is added.

Review order

  1. schema/privacy projection
  2. atomic store and retention
  3. conductor terminal integration
  4. query filters/rendering
  5. concurrency, rollback, privacy, and compatibility tests
  6. architecture docs/preflight wiring

Verification

  • failure diagnostics tests
  • focused lifecycle queue tests
  • conductor self-tests
  • privacy and schema-compatibility tests
  • guardrails
  • contribution commit/push preflights

morluto added 3 commits July 12, 2026 02:36
Implement versioned, bounded failure records and a read-only query surface
for recent build/test failures. The store is thread-safe, writes atomically
via temp files + os.replace, and preserves schema-compatible defaults for
missing fields. Retention only considers *.failure.json and *.summary.json so
in-flight temp files are not deleted. Aggregate JSON output includes an explicit
privacy note stating that raw logs, source content, prompts, transcripts,
credentials, and environment dumps are excluded.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Comment thread Scripts/conductor.py
Comment on lines +2586 to +2589
with self.condition:
current.failure_record_pending = False
self._append_system_line_locked(job, f"failure record write failed: {exc}\n")
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The method _append_system_line_locked is called without holding the required self.condition lock in an exception handler, creating a race condition when modifying job.tail.
Severity: MEDIUM

Suggested Fix

The call to _append_system_line_locked within the except block of _refresh_output_summary should be moved inside the with self.condition: block that is already present for setting current.failure_record_pending = False. This will ensure the lock is held during the modification of the shared job.tail deque.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: Scripts/conductor.py#L2586-L2589

Potential issue: In the `_refresh_output_summary` method, if writing a failure record to
the `failure_store` throws an exception, the code enters an `except` block. Inside this
block, it calls `_append_system_line_locked` to log the error. However, this call is
made without acquiring the `self.condition` lock. The `_append_system_line_locked`
method modifies the shared `job.tail` deque, and doing so without synchronization in a
multi-threaded context can lead to race conditions and data corruption. The method's
name explicitly suggests a lock is required.

Did we get this right? 👍 / 👎 to inform future reviews.

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.

Explore policy-gated local developer diagnostics for build and test failures

1 participant