Skip to content

Harness/brownfield adoption - #2

Open
0xjgv wants to merge 2 commits into
mainfrom
harness/brownfield-adoption
Open

Harness/brownfield adoption#2
0xjgv wants to merge 2 commits into
mainfrom
harness/brownfield-adoption

Conversation

@0xjgv

@0xjgv 0xjgv commented Jul 26, 2026

Copy link
Copy Markdown
Owner

No description provided.

0xjgv added 2 commits July 25, 2026 23:46
The harness gated the whole codebase, not the change, so a large existing
repo was red on day one and got deleted rather than adopted. Two mechanisms
now split by whether a finding has a natural count: findings without one are
diff-scoped to changed lines; findings with one get a floor that starts where
the repo already is.

Verified by adopting into scratch clones of two real repos:

  fusion    OK 11 passed    62k lines, no pyproject.toml
  doghouse  OK 11 passed    208k lines Django, config-only pyproject

Runner (python/harness.py):
- line-level diff scoping via ruff/basedpyright JSON mapped to changed hunks;
  --whole-file opts out. I001 deliberately excluded from WHOLE_FILE_CODES: fix
  cannot resort an import block without touching untouched lines, so including
  it deadlocks the gate.
- fix reverts any file whose edits reached outside the changed ranges. Weaker
  guarantee than lint by design: never rewrites a line you did not touch,
  rather than always fixing what it could.
- five ratcheted floors (coverage, complexity, CRAP, deadcode, suppressions).
  --update-baseline is all-or-nothing and fails loudly rather than recording a
  floor it could not measure.
- _tool() resolver so the runner works without uv; TEST_COMMAND so a pytest
  repo needs a one-line edit, not two rewritten functions.
- ci/pre-push are actually read-only now: four hardcoded `uv run` sites created
  a .venv mid-gate. A source-grep test prevents a fifth.
- sync-agents-md refuses to clobber symlinks and case-variant filenames. It
  destroyed 277 lines of a real repo's agents.md before this.

Docs (skills/harness/, skills/ratchet/):
- adoption manifest rewritten by executing it until both repos went green, not
  by reasoning about it. The previous version was written from a code read and
  had 17 defects when followed literally.
- keep the adopter's ruff config: overwriting doghouse's yields 19,581
  findings, keeping it yields 390.
- new /ratchet skill: raises one floor per run, writing only tests and
  .harness-baseline.

Known limitation: `test` is the one gate with no adoption ramp. Neither repo's
suite runs out of the box.

Note: the working tree already contained uncommitted changes to bun/, go/,
rust/, monorepo/, .github/, scripts/ and others from before this work. They
are included here because they overlap the same files and could not be
cleanly separated.

@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: 507e9b650c

ℹ️ 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".

Comment thread .github/workflows/ci.yml
Comment on lines +63 to +64
- name: Run each template's CI gate
run: make ci

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 Install template dependencies before running CI

On a fresh GitHub runner, this invokes every template's CI without first running uv sync in python/ or bun install --frozen-lockfile in bun/, although the individual template workflows perform those steps. Consequently the Bun architecture gate tries to execute the absent ./node_modules/.bin/depcruise and fails, while Python's _audit_gate_or_warn sees no .venv and silently skips the dependency audit; install both templates' dependencies before dispatching make ci.

AGENTS.md reference: AGENTS.md:L75-L77

Useful? React with 👍 / 👎.

Comment thread python/harness.py
Comment on lines +1170 to +1171
if ranges and _in_ranges(*_diagnostic_row_span(diagnostic), ranges):
kept.append(diagnostic)

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 Compare type diagnostics against the base result

When a changed declaration causes basedpyright to report the resulting error on an unchanged consumer, this filter drops the newly introduced diagnostic. For example, changing a function's return annotation can make an untouched assignment incompatible, but because basedpyright locates the error at that assignment rather than the edited declaration, both check and ci pass; determine whether diagnostics are new relative to the base revision instead of using diagnostic-line overlap alone.

Useful? React with 👍 / 👎.

Comment thread python/harness.py
Comment on lines 2340 to +2341
arch_config_ok = _check_arch_config_guard(include_pre_push_stdin=True)
gates = [
gherkin_ok = _check_gherkin_guard(include_pre_push_stdin=True)

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 Read the pre-push ref stream only once

When the pushed-ref stream is the only usable change source—for example, an orphan branch or a checkout where none of the configured/fallback base refs resolves—the arch-config guard consumes sys.stdin here and the immediately following Gherkin guard reads EOF, sees no production changes, and passes. The same ordering exists in the Bun, Go, and Rust pre-push paths; cache the ref stream or collect changed paths once and share them between both guards.

AGENTS.md reference: python/AGENTS.md:L20-L20

Useful? React with 👍 / 👎.

Comment thread go/harness.go
// `.feature` file anywhere under root.
func hasAnyFeatureFiles() bool {
found := false
_ = filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {

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 Restrict feature discovery to the acceptance directory

In a brownfield Go repository containing an unrelated .feature file under vendor/, generated output, or another tooling directory, walking the entire repository marks the acceptance suite as adopted even when features/ is empty. The acceptance command then skips, but the Gherkin guard becomes active and blocks every production change; search only the features/ tree that the Godog acceptance gate actually executes.

AGENTS.md reference: go/AGENTS.md:L12-L12

Useful? React with 👍 / 👎.

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.

1 participant