Skip to content

ci: make public-hygiene-lint green - #5

Open
MattJackson wants to merge 4 commits into
mainfrom
ci/public-hygiene-green
Open

ci: make public-hygiene-lint green#5
MattJackson wants to merge 4 commits into
mainfrom
ci/public-hygiene-green

Conversation

@MattJackson

Copy link
Copy Markdown
Contributor

public-hygiene-lint was RED on main in this repo. Every hit is fixed by rewriting the text to
state the BEHAVIOUR rather than our internal process. No allow markers were added anywhere in
this change: a blanket allow would turn the gate into decoration.

Hits found on main, and the decision for each

  • .github/scripts/next-version.sh + .github/workflows/release-selftest.yml [internal-issue-id]
    cited an internal guard id. REWRITTEN: the id is dropped, the behaviour statement stays.
  • store-sqlite/src/tests.rs section banner [internal-issue-id, mutation-testing] named an
    internal QA tool and campaign round. REWRITTEN to name what the tests below actually guard
    (predicate boundaries in store-sqlite/src/lib.rs).
  • store-sqlite-plugin/tests/e2e.rs [personal-identifier] attributed the acceptance bar to a named
    individual. REWRITTEN: the doc comment already spells out exactly what the test proves, so the
    attribution carried no information a reader can use.

Red before green

Same invocation CI uses. Output is ASCII-folded for this description; the runs are verbatim
otherwise.

Before (on main)

$ python3 busbarAI/scripts/public-hygiene-lint.py --root .
== public-hygiene: what a customer reads, in . ==
  scanned 19 file(s) via git ls-files; 11 rules applied

  [internal-issue-id] internal issue / task / audit-round identifier - 3 hit(s)
      why: cites a tracker or audit artifact the reader cannot open; `task #141` and `R27 #8` shipped inside operator-facing API documentation
      .github/scripts/next-version.sh:5: # release automation can't silently rot (guard #135.8). Prints "v<MAJOR>.<MINOR>.<PATCH>" to stdout.
      .github/workflows/release-selftest.yml:1: # CI self-test for the release-on-upstream version-compute logic (guard #135.8).
      store-sqlite/src/tests.rs:754: // -- Mutation-testing regressions (cargo-mutants round 1, store-sqlite/src/lib.rs) --------------

  [mutation-testing] mutation-testing workflow leaked into shipped prose - 1 hit(s)
      why: names an internal QA tool and the campaign it was run in; the shipped comment should state the invariant the test protects, not the harness that found the gap
      store-sqlite/src/tests.rs:754: // -- Mutation-testing regressions (cargo-mutants round 1, store-sqlite/src/lib.rs) --------------

  [personal-identifier] a named individual addressed in source - 1 hit(s)
      why: a shipped file naming a person and what they asked for reads as a private conversation the customer was accidentally shown
      store-sqlite-plugin/tests/e2e.rs:399: /// THE REAL "PROD READY" PROOF (Matthew's bar): the sqlite plugin installed the way a real operator

== result ==
  19 public file(s) scanned against 11 rules - 5 hit(s), 0 allowed
  public-hygiene-lint FAILED
  These lines describe how the software was BUILT, not what it does, in files a
  customer can read. Rewrite the text to state the behaviour or the invariant; if a
  line is genuinely legitimate, mark it:
    # public-hygiene-lint: allow - <why this text belongs in a public file>

After (this branch)

$ python3 busbarAI/scripts/public-hygiene-lint.py --root .
== public-hygiene: what a customer reads, in . ==
  scanned 19 file(s) via git ls-files; 11 rules applied

== result ==
  19 public file(s) scanned against 11 rules - 0 hit(s), 0 allowed
  public-hygiene-lint passed

Matthew Jackson and others added 4 commits August 8, 2026 16:00
The public-hygiene gate flags text in customer-readable files that
describes how the software was BUILT rather than what it DOES. Every hit
in this repo is rewritten to state the behaviour or the invariant; no
allow markers are added, so the gate keeps its teeth.
Two independent reasons the real-binary e2e tests could not boot busbar, both of
them core changes the fixtures never caught up with.

1. Secret references are RESOLVED now, at `--validate` and at boot, and busbar
   exits non-zero when one cannot resolve. The file-drop fixture named
   `providers.mock.api_key: { env: MOCK_KEY }` and nobody exported MOCK_KEY:

     [error] providers.mock.api_key: secret env:MOCK_KEY cannot resolve:
             environment variable 'MOCK_KEY' is unset

   which surfaced in CI only as `busbar --validate must succeed with the
   file-dropped sqlite plugin` and a panic 200 lines from the YAML at fault.

   Fixed by deriving the variable names FROM the config files busbar is about to
   read, rather than listing them at the call site: the next person to add a
   secret reference to one of these fixtures must not also have to remember to
   export it, because forgetting produces a failure that never names the
   variable. `tests/common/mod.rs` holds the scan, `tests/config_secrets.rs`
   covers it directly.

2. The admin-API fixture set no `auth.signing_key`, and busbar no longer
   auto-generates one, so the mint it asserts on came back 409:

     {"error":{"code":"conflict","message":"signed-token minting is unavailable:
      no signing key is configured (set auth.signing_key - busbar no longer
      auto-generates one; run `busbar --generate-signing-key`)"}}

   The assertion printed only `left: 409, right: 201`, so the reason was
   invisible; it now carries the response body, which is how the above was read.

Red-before-green, against a `busbar` built from the core branch CI tests against:
before, `install_sqlite_plugin_via_admin_api_and_verify_persistence` and
`load_and_exercise_sqlite_plugin_via_file_drop` both FAILED; after, `test result:
ok. 3 passed; 0 failed`.
…achine

`plugin_path()` looked only at the "uplifted" `<profile>/<name>` copy of the
cdylib. A bare `cargo test` does not uplift it — only `cargo build` does — so on
a developer machine the lookup returned None and all three tests returned early
with a cheerful green:

  running 3 tests
  test load_and_exercise_sqlite_plugin_via_file_drop ... ok
  test result: ok. 3 passed; ... finished in 0.00s

Nothing ran. That 0.00s is the tell, and it is easy to miss. CI is protected by
the `is_none() && CI` panic below, so this never shipped a false green there, but
it does mean the only over-the-ABI coverage of this plugin was routinely not
running locally — which is where it is most useful.

Now checks both the uplifted path and the raw `deps/` compiler output, preferring
whichever is newer. store-mysql's `admin_api_e2e.rs` already had exactly this
fix; its own `e2e.rs` did not, which is the drift this closes.
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