os-sdlc autocorrect pre-pass fails cryptically when target project lacks .rubocop.yml #229

Closed
opened 2026-08-01 21:44:24 +00:00 by jared · 6 comments
Owner

os-sdlc autocorrect --dir <project> resolves its rubocop config as <root-or-project>/.rubocop.yml unconditionally (lib/os_sdlc/autocorrect_prepass.rb). On a project without one, rubocop exits 2 with Configuration file not found: ...; because TestRunner uses Open3.capture2e, that stderr line lands in front of the JSON and the harness dies with rubocop json report was not parseable: unexpected character: 'Configuration' at line 1 column 1 — never mentioning the missing config.

By contrast bin/lint-worklist builds a merged config via LintWorklistRubocopConfig that skips missing files, so the worklist works on the same project while the pre-pass fails.

Suggested fixes (either/both):

  1. Reuse the merged-config chain (plugin config first, project's if present) in AutocorrectPrepass, matching lint-worklist.
  2. Use capture3 and surface stderr in the HarnessError, so config failures name the real cause.

Workaround today: run os-sdlc lint-init <project> first.


Discoverer: /home/jared/dev/ruby-gems/caldotcom-api, session 640995ae-717a-443c-9430-772546887b90, 2026-08-01. Hit during an /os-sdlc:fix-lints residual phase on a project with no .rubocop.yml.

`os-sdlc autocorrect --dir <project>` resolves its rubocop config as `<root-or-project>/.rubocop.yml` unconditionally (`lib/os_sdlc/autocorrect_prepass.rb`). On a project without one, rubocop exits 2 with `Configuration file not found: ...`; because `TestRunner` uses `Open3.capture2e`, that stderr line lands in front of the JSON and the harness dies with `rubocop json report was not parseable: unexpected character: 'Configuration' at line 1 column 1` — never mentioning the missing config. By contrast `bin/lint-worklist` builds a merged config via `LintWorklistRubocopConfig` that skips missing files, so the worklist works on the same project while the pre-pass fails. Suggested fixes (either/both): 1. Reuse the merged-config chain (plugin config first, project's if present) in `AutocorrectPrepass`, matching lint-worklist. 2. Use `capture3` and surface stderr in the HarnessError, so config failures name the real cause. Workaround today: run `os-sdlc lint-init <project>` first. -------- **Discoverer:** /home/jared/dev/ruby-gems/caldotcom-api, session 640995ae-717a-443c-9430-772546887b90, 2026-08-01. Hit during an /os-sdlc:fix-lints residual phase on a project with no .rubocop.yml.
Author
Owner

Pipeline blocker cleared: the --target threading bug that stopped the os-sdlc run on this ticket is fixed in 235c330 (SELECTED_TARGET now passed to shard-plan/workspace-housekeeping; 4 CLI regression tests). This ticket's own bug (autocorrect pre-pass without .rubocop.yml) is still open and unaddressed.

Pipeline blocker cleared: the --target threading bug that stopped the os-sdlc run on this ticket is fixed in 235c330 (SELECTED_TARGET now passed to shard-plan/workspace-housekeeping; 4 CLI regression tests). This ticket's own bug (autocorrect pre-pass without .rubocop.yml) is still open and unaddressed.
Author
Owner

This was generated by AI during triage.

Agent Brief

Category: bug
Summary: Autocorrect pre-pass should tolerate a target project without a .rubocop.yml, using the same merged-config approach as the lint worklist

Current behavior:
AutocorrectPrepass resolves its rubocop config to a single path — the root's .rubocop.yml if it exists, otherwise the project's .rubocop.yml unconditionally, with no existence check. On a project without one, rubocop exits 2 with Configuration file not found on stderr; because the test runner merges stderr into stdout, that line lands ahead of the JSON payload and the harness raises rubocop json report was not parseable: unexpected character: 'Configuration' — never naming the real cause. LintWorklistRubocopConfig already solves this for the worklist path by building an inherit_from: chain that filters to only the config files that exist (plugin config first, then the target's if present), so bin/lint-worklist works on the same project where the pre-pass dies.

Desired behavior:
The autocorrect pre-pass runs successfully on a project with no .rubocop.yml, using the plugin's shipped config. On a project that has one, behavior is unchanged (both configs apply, project's layered on the plugin's, matching the worklist). If rubocop still fails for a config-related reason, the raised harness error includes rubocop's own stderr message rather than only the JSON parse failure.

Key interfaces:

  • AutocorrectPrepass config resolution — should reuse or mirror the merged-config chain that LintWorklistRubocopConfig builds, rather than pointing rubocop at one possibly-missing file
  • The harness error raised on unparseable rubocop output — should surface the leading non-JSON output (rubocop's actual complaint) in its message

Acceptance criteria:

  • os-sdlc autocorrect --dir <project> completes on a project with no .rubocop.yml (regression test with a fixture project lacking the file)
  • On a project with a .rubocop.yml, the effective config includes both the plugin config and the project's, same as the worklist path
  • A rubocop failure that produces non-JSON output raises an error whose message includes that output, not just "json report was not parseable"
  • Existing autocorrect and lint-worklist tests stay green

Out of scope:

  • Changing bin/lint-worklist or LintWorklistRubocopConfig themselves
  • The lint-init workaround (remains valid but should no longer be required)
  • Switching the test runner from capture2e to capture3 for its own sake — only if it falls out naturally of surfacing stderr
> *This was generated by AI during triage.* ## Agent Brief **Category:** bug **Summary:** Autocorrect pre-pass should tolerate a target project without a `.rubocop.yml`, using the same merged-config approach as the lint worklist **Current behavior:** `AutocorrectPrepass` resolves its rubocop config to a single path — the root's `.rubocop.yml` if it exists, otherwise the project's `.rubocop.yml` unconditionally, with no existence check. On a project without one, rubocop exits 2 with `Configuration file not found` on stderr; because the test runner merges stderr into stdout, that line lands ahead of the JSON payload and the harness raises `rubocop json report was not parseable: unexpected character: 'Configuration'` — never naming the real cause. `LintWorklistRubocopConfig` already solves this for the worklist path by building an `inherit_from:` chain that filters to only the config files that exist (plugin config first, then the target's if present), so `bin/lint-worklist` works on the same project where the pre-pass dies. **Desired behavior:** The autocorrect pre-pass runs successfully on a project with no `.rubocop.yml`, using the plugin's shipped config. On a project that has one, behavior is unchanged (both configs apply, project's layered on the plugin's, matching the worklist). If rubocop still fails for a config-related reason, the raised harness error includes rubocop's own stderr message rather than only the JSON parse failure. **Key interfaces:** - `AutocorrectPrepass` config resolution — should reuse or mirror the merged-config chain that `LintWorklistRubocopConfig` builds, rather than pointing rubocop at one possibly-missing file - The harness error raised on unparseable rubocop output — should surface the leading non-JSON output (rubocop's actual complaint) in its message **Acceptance criteria:** - [ ] `os-sdlc autocorrect --dir <project>` completes on a project with no `.rubocop.yml` (regression test with a fixture project lacking the file) - [ ] On a project with a `.rubocop.yml`, the effective config includes both the plugin config and the project's, same as the worklist path - [ ] A rubocop failure that produces non-JSON output raises an error whose message includes that output, not just "json report was not parseable" - [ ] Existing autocorrect and lint-worklist tests stay green **Out of scope:** - Changing `bin/lint-worklist` or `LintWorklistRubocopConfig` themselves - The `lint-init` workaround (remains valid but should no longer be required) - Switching the test runner from `capture2e` to `capture3` for its own sake — only if it falls out naturally of surfacing stderr
Author
Owner

This was generated by AI during triage.

Agent Brief

Category: bug
Summary: Autocorrect pre-pass should tolerate a target project without a .rubocop.yml, using the same merged-config approach as the lint worklist

Current behavior:
AutocorrectPrepass resolves its rubocop config to a single path — the root's .rubocop.yml if it exists, otherwise the project's .rubocop.yml unconditionally, with no existence check. On a project without one, rubocop exits 2 with Configuration file not found on stderr; because the test runner merges stderr into stdout, that line lands ahead of the JSON payload and the harness raises rubocop json report was not parseable: unexpected character: 'Configuration' — never naming the real cause. LintWorklistRubocopConfig already solves this for the worklist path by building an inherit_from: chain that filters to only the config files that exist (plugin config first, then the target's if present), so bin/lint-worklist works on the same project where the pre-pass dies.

Desired behavior:
The autocorrect pre-pass runs successfully on a project with no .rubocop.yml, using the plugin's shipped config. On a project that has one, behavior is unchanged (both configs apply, project's layered on the plugin's, matching the worklist). If rubocop still fails for a config-related reason, the raised harness error includes rubocop's own stderr message rather than only the JSON parse failure.

Key interfaces:

  • AutocorrectPrepass config resolution — should reuse or mirror the merged-config chain that LintWorklistRubocopConfig builds, rather than pointing rubocop at one possibly-missing file
  • The harness error raised on unparseable rubocop output — should surface the leading non-JSON output (rubocop's actual complaint) in its message

Acceptance criteria:

  • os-sdlc autocorrect --dir <project> completes on a project with no .rubocop.yml (regression test with a fixture project lacking the file)
  • On a project with a .rubocop.yml, the effective config includes both the plugin config and the project's, same as the worklist path
  • A rubocop failure that produces non-JSON output raises an error whose message includes that output, not just "json report was not parseable"
  • Existing autocorrect and lint-worklist tests stay green

Out of scope:

  • Changing bin/lint-worklist or LintWorklistRubocopConfig themselves
  • The lint-init workaround (remains valid but should no longer be required)
  • Switching the test runner from capture2e to capture3 for its own sake — only if it falls out naturally of surfacing stderr
> *This was generated by AI during triage.* ## Agent Brief **Category:** bug **Summary:** Autocorrect pre-pass should tolerate a target project without a `.rubocop.yml`, using the same merged-config approach as the lint worklist **Current behavior:** `AutocorrectPrepass` resolves its rubocop config to a single path — the root's `.rubocop.yml` if it exists, otherwise the project's `.rubocop.yml` unconditionally, with no existence check. On a project without one, rubocop exits 2 with `Configuration file not found` on stderr; because the test runner merges stderr into stdout, that line lands ahead of the JSON payload and the harness raises `rubocop json report was not parseable: unexpected character: 'Configuration'` — never naming the real cause. `LintWorklistRubocopConfig` already solves this for the worklist path by building an `inherit_from:` chain that filters to only the config files that exist (plugin config first, then the target's if present), so `bin/lint-worklist` works on the same project where the pre-pass dies. **Desired behavior:** The autocorrect pre-pass runs successfully on a project with no `.rubocop.yml`, using the plugin's shipped config. On a project that has one, behavior is unchanged (both configs apply, project's layered on the plugin's, matching the worklist). If rubocop still fails for a config-related reason, the raised harness error includes rubocop's own stderr message rather than only the JSON parse failure. **Key interfaces:** - `AutocorrectPrepass` config resolution — should reuse or mirror the merged-config chain that `LintWorklistRubocopConfig` builds, rather than pointing rubocop at one possibly-missing file - The harness error raised on unparseable rubocop output — should surface the leading non-JSON output (rubocop's actual complaint) in its message **Acceptance criteria:** - [ ] `os-sdlc autocorrect --dir <project>` completes on a project with no `.rubocop.yml` (regression test with a fixture project lacking the file) - [ ] On a project with a `.rubocop.yml`, the effective config includes both the plugin config and the project's, same as the worklist path - [ ] A rubocop failure that produces non-JSON output raises an error whose message includes that output, not just "json report was not parseable" - [ ] Existing autocorrect and lint-worklist tests stay green **Out of scope:** - Changing `bin/lint-worklist` or `LintWorklistRubocopConfig` themselves - The `lint-init` workaround (remains valid but should no longer be required) - Switching the test runner from `capture2e` to `capture3` for its own sake — only if it falls out naturally of surfacing stderr
Author
Owner

Work started in worktree branch worktree-issue-229-autocorrect-config (2026-08-02).

Work started in worktree branch worktree-issue-229-autocorrect-config (2026-08-02).
Author
Owner

Fixed in worktree branch worktree-issue-229-autocorrect-config, commit aeb1a9e: pre-pass now uses the LintWorklistRubocopConfig merged inherit_from chain (ADR-0082), and the JSON-parse HarnessError includes a 500-char rubocop output excerpt. Suite green (571 runs, 0 failures). Awaiting merge + sign-off.

Fixed in worktree branch worktree-issue-229-autocorrect-config, commit aeb1a9e: pre-pass now uses the LintWorklistRubocopConfig merged inherit_from chain (ADR-0082), and the JSON-parse HarnessError includes a 500-char rubocop output excerpt. Suite green (571 runs, 0 failures). Awaiting merge + sign-off.
Author
Owner

Closed via session 6c82f3a7-3b99-4353-8f3b-4f9f6a2e7656. Fix merged to main: aeb1a9e (route autocorrect pre-pass through merged rubocop config), merge commit 762591f, status leaf updated in 332a32b.

Closed via session 6c82f3a7-3b99-4353-8f3b-4f9f6a2e7656. Fix merged to main: aeb1a9e (route autocorrect pre-pass through merged rubocop config), merge commit 762591f, status leaf updated in 332a32b.
jared closed this issue 2026-08-02 19:49:35 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#229
No description provided.