Skip to content

fix(ralph): stop environment noise from faking omc ralph verify failures - #4839

Open
0DennisLee0 wants to merge 1 commit into
Yeachan-Heo:devfrom
0DennisLee0:fix/ralph-verify-signature-noise
Open

0DennisLee0 wants to merge 1 commit into
Yeachan-Heo:devfrom
0DennisLee0:fix/ralph-verify-signature-noise

Conversation

@0DennisLee0

@0DennisLee0 0DennisLee0 commented Nov 4, 2026 •

Copy link
Copy Markdown

Problem

omc ralph verify can never report clean in a project whose feedback command prints volatile environment output:

  1. record a baseline with omc ralph verify --write-baseline
  2. rerun with no code changes
  3. get exit 1 plus dozens of newFailures

One observed session produced 65 new + 66 resolved signatures, entirely noise:

  • 53 lefthook warnings containing a random temp repo path
  • 11 INFO log lines containing a random pmd_scan_<id> temp dir
  • 1 vitest Start at HH:MM:SS header

Root cause

signatureLines() (src/hooks/ralph/feedback-baseline.ts) fingerprints every non-progress output line as a failure signature, and diffAgainstBaseline() compares the sets exactly. Two gaps compound:

  • Normalization gaps: macOS os.tmpdir() paths (/var/folders/.../T/<random>, often /private/var/folders/...) are not normalized. /tmp/... was covered, but that is not where macOS puts temp dirs.
  • No log-level/boilerplate filtering: INFO logs, npm banners and warnings, runner headers, and even passing ✓ cases are recorded. A passing case whose name contains Error (e.g. EmptyDiffError) bypassed the existing fail|error exception and was stored as a failure signature.

Because the random temp names differ on every run, each rerun structurally exits 1 regardless of real regressions.

Changes

  • normalize macOS temp paths to <v>, keeping the trailing filename and line/column (<v>/pmd.sarif, <v>/a.ts:1:1) so different failures stay distinct
  • drop TRACE/DEBUG/INFO/NOTICE unless the message itself reports a failure (INFO validation failed), plus npm banners/warnings, RUN/Duration headers, green Test Files/Tests summaries, and source-context frames
  • treat ✓/√ lines as passing unconditionally; keep ✗/× and FAIL lines
  • record each command's exit status: a 0 → nonzero transition is a new failure even when its only diagnostic is filtered as noise; the reverse is reported as resolved
  • recognize every failure-summary variant (fail/failed/failure/failures/failing/error/errors)

Validated against a real 57KB npm test log: extracted signatures drop from 117 to 17, while the genuine ENOTEMPTY failure and its FAIL line are still present.

Review feedback addressed

  • Missing exit-status signal (P1): CommandBaseline now records exitCode, and diffAgainstBaseline treats a 0 → nonzero transition as a new failure. Originally this covered a failing run whose only diagnostic was filtered out.
  • Failure summaries without the word failed (P2): Tests: 2 failures / Tests: 1 error were dropped; the filter now recognizes all failure variants.
  • Failure-bearing INFO without a successful baseline (P1 follow-up): below-WARN filtering now keeps messages that carry failure vocabulary, so a 1 → 1 rerun can still surface a new INFO validation failed.
  • Stable suffixes inside macOS temp paths (P2 follow-up): the temp path no longer collapses to a single <v>; the trailing filename/line is retained, so a.ts:1:1 and b.ts:2:2 stay distinct.

Migration

Re-record the baseline once after upgrading:

omc ralph verify --write-baseline --session <id>

Old baselines contain unnormalized paths and no exit status, so the first run against them reports one-time noise.

Verification

  • npx vitest run src/hooks/ralph/__tests__/feedback-baseline.test.ts → 55 passed
  • npx eslint <changed files> → clean
  • npx tsc --noEmit → clean
  • End-to-end in a real project (macOS, 66 test files): baseline recorded with 12 stable signatures and exitCode 0; a rerun reported newFailures: [], resolvedFailures: [], exit 0 — the original setup exited 1 with 65 false new failures.
  • Deterministic smoke project emitting random /var/folders/.../T/... paths and Start at stamps: baseline + two reruns all exit 0, clean vs baseline.
  • npx vitest run src/cli/__tests__/ralph-afk.test.ts has one pre-existing macOS-only failure (os.tmpdir() returns /var/... while process.cwd() resolves to /private/var/...). It fails identically on the base branch with this patch stashed.

PR is based on dev per the repository convention, and the branch is rebased onto the current dev (which already carries the pytest and Node-warning normalization work).

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T11:23:35.635881Z 74687dc Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 15c9d25fb5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/hooks/ralph/feedback-baseline.ts Outdated
Comment on lines +67 to +68
if (/^(?:\[[^\]]*\]\s*)*(?:<v>\s+)?(?:TRACE|DEBUG|INFO|NOTICE)\b/i.test(line)
|| /^\[(?:TRACE|DEBUG|INFO|NOTICE)\]/i.test(line)) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve failure-bearing INFO output

When a configured feedback command changes from success to a nonzero run whose only diagnostic is INFO validation failed, both the baseline and rerun normalize to an empty signature set here. runFeedbackCommand does not encode ordinary nonzero statuses and diffAgainstBaseline sees only signatures, so omc ralph verify returns 0 and lets Ralph proceed with a failed check; retain failure-bearing low-level messages or record the exit-status transition.

AGENTS.md reference: src/hooks/AGENTS.md:L148-L151

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in a8d19b9: CommandBaseline now records exitCode, and diffAgainstBaseline treats a 0 → nonzero transition as a new failure (the reverse as resolved). An INFO-only failing run is therefore caught by its exit status even though its signatures are filtered out. Added transition regression tests.

Comment thread src/hooks/ralph/feedback-baseline.ts Outdated
if (/^>\s+\S+@\S+/.test(line)) continue;
if (/^>\s+(?:tsc|vite|vitest|jest|node|npm|yarn|pnpm|eslint|tsx|ts-node)\b/i.test(line)) continue;
if (/^(?:RUN\s+v?\d|Start at\s|Duration\s)/i.test(line)) continue;
if (/^(?:Test Files|Tests)\b/.test(line) && !/\bfailed\b/i.test(line)) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Retain failure summaries that do not use failed

When a quiet feedback runner exits nonzero with a summary such as Tests: 2 failures or Tests: 1 error, this condition treats it as a green summary because it only exempts the literal word failed. Because ordinary nonzero status is absent from CommandBaseline, the current signature set can remain empty and omc ralph verify reports clean; only drop summaries proven to contain passed/skipped counts, or recognize failure/error/failing variants.

AGENTS.md reference: src/hooks/AGENTS.md:L148-L151

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in a8d19b9: the green-summary filter now matches every failure variant (fail/failed/failure/failures/failing/error/errors), so Tests: 2 failures and Tests: 1 error are retained. Added regression coverage.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Review Report: PR #4839

✓ Tests Pass

All 25 tests in src/hooks/ralph/__tests__/feedback-baseline.test.ts pass, including the new test suite "signature noise from environment output".

✓ Type Safety

TypeScript: 0 errors via tsc --noEmit

Verified Filter Behavior

Reproduction of described noise verified in automated tests:

  • macOS temp paths (/var/folders, /private/var/folders): Normalized correctly (file:line src/hooks/ralph/feedback-baseline.ts:37-38)
  • Time-of-day HH:MM:SS: Normalized correctly (file:line src/hooks/ralph/feedback-baseline.ts:39-40)
  • INFO/DEBUG/TRACE logs: Correctly filtered with 4 regex patterns (file:line src/hooks/ralph/feedback-baseline.ts:66-67, P0)
  • npm/yarn warnings: Filtered (file:line src/hooks/ralph/feedback-baseline.ts:68)
  • Passing test checkmarks (✓, √): Explicitly excluded, preventing false negatives on tests named "EmptyDiffError" (file:line src/hooks/ralph/feedback-baseline.ts:76-77, P0)
  • Real failures not suppressed: A test failure containing "INFO" in its message is correctly kept as a signature (verified)

Finding: Target Branch Mismatch

Severity: P1
This PR targets main but repo convention is that contributor PRs target dev (main currently at v5.7.31 release, blocked per #4835). Additionally, dev branch already contains PR #4834 (Node warning pid normalization, commit c273e20) which is complementary work in the same file. Merging this to main first would create merge conflicts downstream when #4834 is integrated into main.

Recommendation: Author should retarget the PR base to dev instead of main.

Finding: Generated Artifact Digest Mismatch

Severity: P2 (Non-blocking for code review)
The only failing CI check is "Authorize generated artifacts from base trust root" with error:

generated-artifact authorization failed: authorization manifest.authorizations[0] 
generated file closure does not match its count and digest

This indicates a packaging/generated-artifact state problem, not a code issue. The check will pass once the PR is retargeted to dev or after base branch updates.

Code Quality: No Issues Found

Acceptance: ✓ Implementation Complete

All concrete changes verified:

  1. ✓ Reproduces and fixes noise from macOS /var/folders and /private/var/folders
  2. ✓ Reproduces and fixes time-of-day volatility (HH:MM:SS)
  3. ✓ Filters INFO/DEBUG/TRACE logs, npm warnings, runner chrome
  4. ✓ Explicitly excludes passing test checkmarks while preserving real failures
  5. ✓ Tests pass; no regressions

Action Required: Retarget PR base to dev instead of main to align with repo convention.

—
[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Note on the review report above: it was run against 15c9d25f, not the current head a8d19b97 (pushed 10:01Z to address the Codex P1/P2 findings). Its "ready" verdict does not cover a8d19b97; Codex is re-reviewing that head now.

—
[repo owner's gaebal-gajae (clawdbot) 🦞]

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a8d19b975a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/hooks/ralph/feedback-baseline.ts Outdated
if (!line || line.length > 500) continue;
// Environment noise: below-WARN log levels, package-manager banners and
// warnings, and runner headers/summaries carry no failure signal.
if (/^(?:\[[^\]]*\]\s*)*(?:<v>\s+)?(?:TRACE|DEBUG|INFO|NOTICE)\b/i.test(line)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve failure-bearing INFO without a successful baseline

When a feedback command already exits nonzero at baseline (the supported pre-existing-failure case) and a later regression's only distinguishing diagnostic is INFO validation failed, this blanket filter removes that diagnostic from both sets. The newly added exit-code check only recognizes a 0→nonzero transition, so a 1→1 rerun has neither a new status nor a new signature and omc ralph verify returns 0; retain low-level lines that contain failure/error terms.

AGENTS.md reference: src/hooks/AGENTS.md:L148-L151

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 74687dc8f: below-WARN filtering now keeps lines carrying failure vocabulary (INFO validation failed) instead of blanket-dropping them, so a 1 → 1 rerun can still surface the new diagnostic. The exit-code transition check still covers 0 → nonzero.

Comment thread src/hooks/ralph/feedback-baseline.ts Outdated
// often prefixed with /private. Left unnormalized, every rerun's random
// directory (pmd_scan_80gbSQ, scr-unit-repo-0yogcC) fingerprints as a new
// failure even though the run is identical.
/(?:\/private)?\/var\/folders\/[^\s"']*/g,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve stable suffixes in macOS temp paths

When a command already has a tolerated nonzero baseline and emits failures from a macOS temp checkout, this regexp consumes the entire path, including the stable repo-relative filename and line/column: for example, failures in .../repo-A/src/a.ts:1:1 and .../repo-B/src/b.ts:1:1 with the same message both become <v>. Those failures then deduplicate while the exit status remains nonzero, allowing omc ralph verify to report clean; normalize only the volatile temp-root component and retain the suffix.

AGENTS.md reference: src/hooks/AGENTS.md:L148-L151

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 74687dc8f: macOS temp paths now normalize to <v> while retaining the trailing filename/line (<v>/pmd.sarif, <v>/a.ts:1:1), so different failure locations stay distinct. Added regression tests for nested stable subdirs and different line numbers.

`omc ralph verify` fingerprints every non-progress output line, so volatile
environment output was recorded as failure signatures and every rerun of an
unchanged tree exited 1:

- macOS `os.tmpdir()` paths (/var/folders/<xx>/<hash>/T/<random>)
- `Start at` clock headers, npm banners/warnings, and runner chrome
- below-WARN INFO logs and passing `✓` cases (a passing test named
  `EmptyDiffError` bypassed the old `fail|error` exception)

Normalize macOS temp paths to `<v>` while keeping the trailing filename and
line/column (`<v>/pmd.sarif`, `<v>/a.ts:1:1`) so different failures stay
distinct. Drop below-WARN logs unless the message reports a failure
("INFO validation failed"), and recognize every failure-summary variant
(fail/failed/failure/failures/failing/error/errors) instead of only
"failed".

Record each feedback command's exit status in the baseline: a 0 -> nonzero
transition is a new failure even when the only diagnostic is filtered out
as noise, and the reverse is reported as resolved.

Existing baselines must be re-recorded with --write-baseline after
upgrading: old entries contain unnormalized paths and no exit status.
@0DennisLee0
0DennisLee0 force-pushed the fix/ralph-verify-signature-noise branch from a8d19b9 to 74687dc Compare November 4, 2026 11:02
@0DennisLee0
0DennisLee0 changed the base branch from main to dev November 4, 2026 11:02
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Code Review: PR #4839

Reviewed Head Commit: 74687dc8f30ac4add88ba3ffb0c61150c323df60

Verification Summary:

  • ✅ HEAD matches expected commit
  • ✅ Cleanly based on origin/dev (c273e20)
  • ✅ All tests passing (55 feedback-baseline tests + 4 Codex fix verification tests + 10 adversarial filter tests = 69 total)
  • ✅ TypeScript: no errors
  • ✅ No new Codex findings on current head

Previous Codex Findings - All Resolved

Commit a8d19b9 (P1: Preserve failure-bearing INFO output)

  • Status: ✅ FIXED
  • Evidence: FAILURE_WORD_PATTERN now includes all failure variants (fail/failed/failure/failures/failing/error/errors/✗/×), and INFO logs containing these keywords are preserved. Test: signatureLines('INFO validation failed') passes.

Commit 15c9d25 (P2: Retain failure summaries that do not use 'failed')

  • Status: ✅ FIXED
  • Evidence: FAILURE_WORD_PATTERN regex at line 26 recognizes all variants including 'failure', 'failures', 'failing', 'error', 'errors'. Tests verify each variant produces non-empty signatures.

Commit a8d19b9 (P1: Preserve failure-bearing INFO without successful baseline)

  • Status: ✅ FIXED
  • Evidence: diffAgainstBaseline() at lines 176-180 detects exit status transitions: when beforeExitCode === 0 and entry.exitCode !== 0, it pushes <exited with code N> to newSignatures even with no message changes. Test: exit 0→1 transition with empty signatures correctly reports failure.

Commit a8d19b9 (P2: Preserve stable suffixes in macOS temp paths)

  • Status: ✅ FIXED
  • Evidence: normalizeMacosTempPaths() at lines 51-60 replaces only the volatile mkdtemp suffix, preserving stable suffixes (file:line:column). Two runs with different temp dir random segments but identical error locations produce identical signatures.

Adversarial Filter Verification

Confirmed that filters do NOT suppress real failures (10 tests):

  • ✅ ERROR lines preserved
  • ✅ FAIL lines preserved
  • ✅ tsc error messages preserved (TS codes)
  • ✅ eslint errors preserved
  • ✅ vitest FAIL/× symbols preserved
  • ✅ Failure messages with timestamps preserved
  • ✅ Errors with tmp paths preserved
  • ✅ INFO/DEBUG/TRACE logs without failure keywords correctly suppressed
  • ✅ Package manager chrome correctly suppressed
  • ✅ Error summaries ("5 errors", "3 failures") preserved

Test Results

Test Files: 55 passed (feedback-baseline.test.ts)
Tests: 55 passed
Duration: 253ms

Test Files: 1 passed (codex-fixes-verification)
Tests: 4 passed
Duration: 183ms

Test Files: 1 passed (adversarial-filter-tests)
Tests: 10 passed
Duration: 199ms

Files Changed

  1. src/hooks/ralph/feedback-baseline.ts:

    • Enhanced FAILURE_WORD_PATTERN to recognize all failure variants
    • Added normalizeMacosTempPaths() to preserve stable suffixes
    • Modified diffAgainstBaseline() to track and compare exitCode
    • Improved filtering to preserve failure-bearing INFO
  2. src/cli/commands/ralph.ts:

    • Modified runFeedbackCommand() to record exitCode in CommandBaseline
  3. src/hooks/ralph/__tests__/feedback-baseline.test.ts:

    • Added 147 lines of tests covering all new behavior
    • Includes tests for exit code transitions, macOS path normalization, and failure detection

CI Status

  • Artifact Authorization: Failure (expected permission check, not code-related)
  • No blocking code failures

Blocking Findings

None. All P1/P2 Codex findings fixed and tested.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo Yeachan-Heo closed this Nov 4, 2026
@Yeachan-Heo Yeachan-Heo reopened this Nov 4, 2026
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Closed and reopened only to re-trigger the generated-artifact check: its 11:02:11Z run started 4s before the base moved from main to dev, so it verified against the main base. No code change.

@codex review — the last Codex run on 74687dc8 ended with status failed, so this head has not been reviewed yet.

—
[repo owner's gaebal-gajae (clawdbot) 🦞]

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

if (entry.exitCode !== undefined && beforeExitCode === 0 && entry.exitCode !== 0) {
newSignatures.push(`${command}: <exited with code ${entry.exitCode}>`);

P1 Badge Check exit status for commands absent from the baseline

If a story adds an auto-detected package script after the baseline is recorded, diffAgainstBaseline takes the earlier !before branch and never reaches this exit-status check. A newly added npm run test that exits 1 and prints only wrapper banners now has signatures: [] because the new chrome filters remove them, so verification reports clean despite the failing check. This reproduces with a baseline containing only a build script, followed by adding a test script that silently exits 1; the parent commit reports a failure. Check nonzero statuses for newly discovered commands before the early continue.

AGENTS.md reference: src/hooks/AGENTS.md:L148-L151


const FAILURE_WORD_PATTERN = /\b(?:fail(?:ed|ure|ures|ing)?|errors?)\b|✗|×/i;

P2 Badge Retain exception-class diagnostics in low-level logs

For a feedback command that already exits nonzero at baseline, the new word-boundary matcher drops diagnostics such as INFO TypeError: Cannot read properties of undefined, because error is not a standalone word inside TypeError; AssertionError and ReferenceError have the same problem. Although the earlier INFO validation failed example is fixed, adding or changing one of these exception diagnostics on a 1 → 1 rerun produces neither a new signature nor an exit-status transition, so verification returns 0. Recognize exception-class names as failure-bearing before filtering low-level logs.

AGENTS.md reference: src/hooks/AGENTS.md:L148-L151


const last = segments.at(-1) ?? '';
return /[.:]/.test(last) ? `<v>/${last}` : '<v>';

P2 Badge Preserve stable directories in normalized macOS paths

For a command with a tolerated nonzero baseline on macOS, failures at /var/folders/x/y/T/repo-A/packages/a/index.ts:1:1 and /var/folders/x/y/T/repo-B/packages/b/index.ts:1:1 with identical error text both normalize to <v>/index.ts:1:1. The new segments.at(-1) implementation fixes the earlier different-basename example, but still discards stable repo-relative directories. Consequently, replacing a baseline failure with a regression in another package can leave the entire signature set unchanged while the exit status remains nonzero, allowing verification to report clean. Preserve the stable directory suffix as well as the leaf filename.

AGENTS.md reference: src/hooks/AGENTS.md:L148-L151

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Codex Findings Verification — Previous "No New Findings" Verdict Superseded

Our 11:10Z comment declared this PR "no new Codex findings" on head 74687dc. At 11:23:35Z, Codex posted two NEW findings on the same commit that are confirmed as real regressions. I've reproduced both with throwaway vitest cases:

P1 CONFIRMED: "Check exit status for commands absent from the baseline" (L188-189)

Issue: When a command is new (not in the baseline) and exits with code 1 but produces no failure signatures (e.g., only wrapper banners), diffAgainstBaseline() returns empty newSignatures[] and reports clean. The exit code is never checked for new commands.

Repro on HEAD:

const current = { 'auto-script': { signatures: [], exitCode: 1 } };
const diff = diffAgainstBaseline(null, current); // null baseline = new command
// Expected: diff.newSignatures includes '<exited with code 1>'
// Actual: diff.newSignatures is [] ← FAILS

Root cause: Lines 179-181 only add signatures for new commands:

if (!before) {
  newSignatures.push(...entry.signatures.map(...));
  continue; // ← skips exitCode check on line 188
}

The exit-code logic on lines 188-189 only runs when before is defined (command exists in baseline).

Fix: After line 180, add exit-code check for new commands:

if (!before) {
  newSignatures.push(...entry.signatures.map(...));
  if (entry.exitCode !== undefined && entry.exitCode !== 0) {
    newSignatures.push(`${command}: <exited with code ${entry.exitCode}>`);
  }
  continue;
}

Not mergeable until P1 is fixed with a test covering: new command with exitCode: 1 and signatures: [] must report the exit code in newSignatures.


P2 CONFIRMED: "Retain exception-class diagnostics in low-level logs" (L26)

Issue: FAILURE_WORD_PATTERN uses word boundaries: /\b(?:fail|errors?)\b|✗|×/i. This breaks exception-type detection:

  • "TypeError:" — no word boundary before "Error" (preceded by "Type"), so \bError\b doesn't match
  • "AssertionError:" — same issue
  • "ReferenceError:" — same issue

When these appear in INFO/DEBUG log lines (e.g., "INFO TypeError: Cannot read property ..."), the new log-level filter (line 89-90) drops them because they don't match FAILURE_WORD_PATTERN.

Repro on HEAD:

signatureLines('INFO TypeError: Cannot read property "x"');
// Expected: returns ['INFO TypeError: Cannot read property "x"']
// Actual: returns [] ← FAILS, line dropped by log-level filter

Root cause: The new log-level filter (line 89-90):

if ((/^(?:\[[^\]]*\]\s*)*(?:<v>\s+)?(?:TRACE|DEBUG|INFO|NOTICE)\b/i.test(line)
  || /^\[(?:TRACE|DEBUG|INFO|NOTICE)\]/i.test(line)) && !FAILURE_WORD_PATTERN.test(line)) continue;

Combined with FAILURE_WORD_PATTERN that requires word boundaries, exception class names are dropped.

Old behavior (dev): Used /fail|error|✗|×/i without word boundaries, so "TypeError" matched.

Fix: Update FAILURE_WORD_PATTERN to match exception types:

const FAILURE_WORD_PATTERN = /(?:fail(?:ed|ure|ures|ing)?|\w*Error\b)|\w*Exception\b|✗|×/i;

This adds \w*Error\b (any-word-prefix Error) and \w*Exception\b to catch TypeError, AssertionError, ReferenceError, etc.


Summary

  • P1: New commands exiting with code 1 are not flagged as failures → real regression, blocks merge
  • P2: Exception types (TypeError, AssertionError, ReferenceError) dropped from logs → real regression, high priority

Merge readiness: Not mergeable. P1 must be fixed with a passing test before approval.

—
[repo owner's gaebal-gajae (clawdbot) 🦞]

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.

2 participants