Skip to content

feat: catch CI's commonest failures before the push - #1147

Merged
REPPL merged 22 commits into
mainfrom
fix/catch-ci-failures-before-push
Oct 29, 2026
Merged

REPPL merged 22 commits into
mainfrom
fix/catch-ci-failures-before-push

Conversation

@REPPL

@REPPL REPPL commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Catches the failures that most often cost a hosted CI run, before the push:

  • a pull-request body and title are held to the attribution and issue-resolution gates before gh posts them: a missing Assisted-by line, a tool footer, an undeclared issue mention;
  • an undeclared issue mention in a commit message is refused at the commit, not at the preflight;
  • make preflight runs CI's gitleaks and govulncheck scans, at the versions CI pins;
  • abcd land composes the pull-request body from the branch's commits when it finds no pull request to queue.

It also drafts the local-first landing intent and files the CI escapes that intent measured.

No test can reach the machine's own GitHub login any more. With the announce-before-push change on main, a landing announces the items its trailers name and asks gh whose account it is when git's identity does not say. The body-composition test reached the developer's own login that way, so it passed preflight and failed in the merge queue, where CI has none. gittest.HideGHLogin points gh at an empty configuration directory and clears its token variables for the whole test process. The landing, claim, implement/loop and surface/cli test packages, which are every package whose tests reach the announce path, call it from TestMain, so a test there that reaches gh fails locally as it does on CI.

Not covered here, for follow-up: these test packages depend on the GitHub entry point (internal/core/github) and have no such guard yet: afterupdate, ahoy, autonomy, capture, embargo, github, ideate, implement, lifeboat, reading, record, release, repolint, report, reservesweep, scribe, site, sweep, update, surface/session and surface/session/web. None of their tests is known to reach a login.

Commits:

  • docs: draft the local-first landing intent for private repositories
  • docs: record the confirmed routing of the local-first landing draft
  • docs: file the CI escapes and record the ruling to build them first
  • feat: hold a pull request's body and issue ids to the hosted checks before gh posts them
  • feat: refuse a bare issue mention at the commit, not at the preflight
  • feat: run CI's gitleaks and govulncheck scans in make preflight
  • feat: compose the pull-request body when land finds none to queue
  • fix: act on the review of the pre-push checks
  • test: run the new tests' git through gittest and name the gate's fence copy
  • test: give the scan tests' git a directory of its own on PATH
  • test: keep the machine's GitHub login out of reach of the tests
  • docs: keep AGENTS.md under the smallest reader's cap after main grew it

Refs: iss-2609012313465609
Refs: iss-2610161639025702
Refs: iss-2610110939559446
Refs: iss-172
Refs: iss-2610261151381604, iss-2610261151481013, iss-2610261152125261
Refs: iss-2609061525437969, iss-220, iss-2610241424265464
Resolves: iss-2609061525437969
Resolves: iss-2610261152125261
Resolves: iss-2610241424265464
Refs: iss-2610261852072295
Resolves: iss-2610261151381604
Resolves: iss-2610261151481013
Resolves: iss-220
Refs: iss-2610241424265464
Refs: iss-2610261151481013
Refs: iss-2610262219309883
Refs: iss-2610262219399974
Assisted-by: abcd:dev
Assisted-by: Claude:claude-opus-5-5

REPPL added 9 commits October 27, 2026 02:56
File itd-2610261025516272: an abcd-managed private repository lands each
change after one check sized to what it touches, run on the person's own
machine, with hosted CI minutes spent only where the person chose. The
draft rests on a dated state-of-the-art note (GitHub's billing and plan
tiers, local CI with a commit status, the not-rocket-science rule, Pants
and Nx selection, Go's test cache) and on abcd's own measured baseline.

Join iss-2609012313465609, iss-2610110939559446 and iss-172 to the draft
from both ends, regenerate the brief's draft-intent index, and grade the
proposed routing in the decomposition-calibration note as unconfirmed.

Refs: iss-2609012313465609
Refs: iss-2610161639025702
Refs: iss-2610110939559446
Refs: iss-172
Assisted-by: Claude:claude-opus-5-5
The product thinker accepted the proposed split and typed links of
itd-2610261025516272. Supersede itd-115 by it through intent reclassify,
add its builds-on edge to itd-2610161647248332 (which now names it back),
mark it as refining itd-106, record the ruling as the draft's decision 1,
regrade the decomposition-calibration entry as confirmed, and regenerate
the brief's draft-intent index.

Refs: iss-172
Assisted-by: Claude:claude-opus-5-5
Of 32 failed hosted CI runs between 2026-10-18 and 2026-10-26, 13 were
deterministic checks that could have run before the push, and 10 more
were one govulncheck finding that stood on the default branch itself.

File three issues: the preflight runs neither gitleaks nor govulncheck
(iss-2610261151381604), nothing says before the push that the default
branch itself fails a check (iss-2610261151481013), and RS004 on the
pull-request form runs only in CI (iss-2610261152125261). Write the
adopted remedies of iss-2609061525437969 (narrowed to pull-request
bodies) and iss-220 (its compose half), record the ruling as
dcn-2610261152329451, and add the escape-recording criterion and its
decision to itd-2610261025516272.

Refs: iss-2610261151381604, iss-2610261151481013, iss-2610261152125261
Refs: iss-2609061525437969, iss-220, iss-2610241424265464
Assisted-by: Claude:claude-opus-5-5
…efore gh posts them

The shell guard's forge-text check now judges a gh pr create, new or edit
for the two faults the hosted checks found most often after a push. A body
or body file with no Assisted-by line in an accepted form is blocked
(forge-text-disclosure), judged by assistedby.JudgeBody, the Go copy of
the attribution gate's body arm. A test runs the gate itself over a shared
corpus to keep the two in step. Where outbound.declare_mentions is set
beside outbound.forge, a title and body naming an issue id with no
Resolves: or Refs: line are blocked too (forge-text-mention). That is
RS004, through core/issuemention, the one Go copy of its vocabulary, which
capture's mentions listing now reads too. abcd's own repository opts in,
and the bundled COMMITTING rule names pull-request bodies beside commits.

Resolves: iss-2609061525437969
Resolves: iss-2610261152125261
Assisted-by: Claude:claude-opus-5-5
The committed commit-msg hook runs RS004's message half, a new message
form of scripts/check-issue-resolution.sh. It reads the message without
its comment lines, since git's own status comments name the branch and
git strips them after the hook. A shallow clone judges it too, as the form
reads no history. The hook runs it before writing any file and hands it
the message on standard input (message -), so no write the shell guard
cannot place comes before the shell that runs the gate. The guard's
script reading still warns on the hook, through a tokenizer defect that
cuts its is_scissors test at each &&; the script corpus ceiling is one
until that is fixed.

Resolves: iss-2610241424265464
Refs: iss-2610261852072295
Assisted-by: Claude:claude-opus-5-5
secrets-check and vulncheck are preflight prerequisites, so a finding
stops the run before its test stages wait at the load gate. Each runs at
the version ci.yml pins, read from ci.yml, and each is skipped loudly where
it cannot run here. On a finding the vulncheck step names each fix
govulncheck reports. When the branch changes neither go.mod nor go.sum, it
also says the finding most likely stands on the default branch.

Resolves: iss-2610261151381604
Resolves: iss-2610261151481013
Assisted-by: Claude:claude-opus-5-5
With no pull request open, abcd land composes the body from the branch's
commits: each subject, then their Refs:, Resolves:, Delivers: and
Assisted-by: lines once each. It judges the body with the shell guard's
checks of a posted body and writes it to the checkout's local tier. The
gh pr create command it prints names it with --title and --body-file. land
makes no local tier, so a checkout without one gets the bare command, and
land still opens no pull request.

Resolves: iss-220
Assisted-by: Claude:claude-opus-5-5
The commit-msg hook judged RS004 on a merge commit, whose message git
writes and names the merged branch (`Merge branch 'capture/iss-N'`),
though the range check skips merges; and under a global dispatcher it
held every other repository on the machine to abcd's own rule. It now
judges RS004 only for a commit in a working tree of the repository the
hook belongs to (a shared git common directory) and leaves a merge to
the range check.

The preflight's govulncheck stopped every branch on a finding that most
likely stands on the default branch, though govulncheck is not a
required check; a finding on a branch that moves no dependency now
warns. gitleaks exits 1 on its own errors as on a leak, so a leak now
has an exit code of its own and an error is not called a secret.

land's composed body declares abcd's own Assisted-by label before the
models' lines (ruling R4) and no longer carries None for text a tool
assembled; a disclosure fault other than a missing line is named for
what it is, and a check-ignore that cannot answer is not reported as a
tier git does not ignore. The ahoy help and page say the forge-text
check holds a pull request's body to its disclosure, and CONTRIBUTING
names the hook's RS004 half.

Two shell-guard misreadings met on the way are captured: a syntax
check read as a run, and a context-dependent block of the hook's build
line.

Refs: iss-2610241424265464
Refs: iss-2610261151481013
Refs: iss-2610262219309883
Refs: iss-2610262219399974
Assisted-by: Claude:claude-opus-5-5
…e copy

The preflight's canonical-primitive checks refused three things this branch
added. Two new test files spawned git without the shared gittest helper, so
they now take their environment from gittest.Env. The pull-request body
check's fence reader is the Go copy of the attribution gate's
strip_fenced_blocks, and must strip what that shell gate strips rather than
what mdrecord.Read reads, so it is allowlisted in both scans with that reason.

Assisted-by: Claude:claude-opus-5-5
@REPPL
REPPL enabled auto-merge October 27, 2026 06:58
@REPPL
REPPL added this pull request to the merge queue Oct 27, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 27, 2026
REPPL added 4 commits October 27, 2026 19:12
Both conflicts were additions on each side: the out-of-scope index gains
this branch's draft beside main's two new ones, in id order, and the
decomposition-calibration note keeps both 2026-10-26 routing entries.

Assisted-by: Claude:claude-opus-5-5
Main's make precheck runs preflight's gates, so it gains the two scans
this branch adds to preflight.

Assisted-by: Claude:claude-opus-5-5
Main replaced the generated list of draft intents in the out-of-scope
chapter with the commands that enumerate them, so its version stands.

Assisted-by: Claude:claude-opus-5-5
@REPPL
REPPL enabled auto-merge October 29, 2026 01:37
REPPL added 4 commits October 29, 2026 04:36
With main merged in, AGENTS.md was 32856 bytes, past the 32768 a host may
read, and CI's merge-ref run failed TestAgentsMDFitsTheSmallestReadersCap.
The scans' skip and warn rules are already the header of
scripts/preflight-scans.sh, so the definition of done now points there,
and AGENTS.md is 32522 bytes.

Assisted-by: Claude:claude-opus-5-5
The no-gitleaks case put git's install directory on PATH. Where a package
manager installs both, that directory also holds gitleaks, so the case ran
a real scan and its assertion that nothing was checked failed. git now runs
through a wrapper in a temporary directory, and PATH names only that and the
system directories.

Refs: iss-2610261151381604
Assisted-by: Claude:claude-opus-5-5
@REPPL
REPPL added this pull request to the merge queue Oct 29, 2026
@REPPL
REPPL removed this pull request from the merge queue due to a manual request Oct 29, 2026
REPPL added 2 commits October 29, 2026 17:43
A landing announces the items its trailers name before it pushes, and asks gh
whose account it is when git's identity does not say. The body-composition
test reached the developer's own gh login that way, so it passed preflight
and failed in the merge queue, where CI has no login.

gittest.HideGHLogin points gh at an empty configuration directory and clears
its token variables for the whole test process. The landing, claim,
implement/loop and surface/cli packages call it from TestMain, so a test there
that reaches gh fails locally as it would on CI. The body-composition test now
names the sender through git's identity and stubs the embargo check, which it
does not test.

Refs: iss-220
Assisted-by: Claude:claude-opus-5-5
…-before-push

# Conflicts:
#	.abcd/development/brief/05-internals/03-configuration.md
@REPPL
REPPL enabled auto-merge October 29, 2026 19:45
REPPL added 2 commits October 29, 2026 20:18
Main's AGENTS.md reached 32,741 bytes, so this branch's 208 added bytes took
the merge past the 32,768 a host may read and failed the conventions-file
test in the merge queue. Rewrap the make preflight comment onto fewer lines
and leave the scans' skip and warn behaviour to scripts/preflight-scans.sh,
which already says it; the file is 32,709 bytes.

Refs: iss-2610261151381604, iss-2610261151481013
Assisted-by: Claude:claude-opus-5-5
@REPPL
REPPL added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 89965b4 Oct 29, 2026
15 of 16 checks passed
@REPPL
REPPL deleted the fix/catch-ci-failures-before-push branch October 29, 2026 23:25
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