Skip to content

fix(ci): exclude k9 contracts from the Nickel gate - #985

Merged
hyperpolymath merged 2 commits into
mainfrom
fix/nickel-gate-excludes-k9-contracts
Sep 22, 2026
Merged

hyperpolymath merged 2 commits into
mainfrom
fix/nickel-gate-excludes-k9-contracts

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Closes #982. Cures the Nickel half of #976.

The defect

A suffix is not a format. *.k9.ncl files are k9 contracts, not Nickel
source — they open with a K9! sentinel on line 1, so nickel typecheck dies at
1:3 on the !. The gate globbed *.ncl and swallowed all of them.

Measured in the one pilot repo that actually ran the pipeline (cicd-squabbler):

bucket count can it ever pass?
*.k9.ncl — a different format 16 no
.ncl importing build-time JSON (correctly uncommitted) 2 no, standalone
genuine, standalone-checkable Nickel 9 yes
tracked .ncl total 27 18 could never pass

That repo went red entirely on boilerplate, never on its own source.

detect counted the same inflated glob at line 132, so has_nickel went true on
repos holding no Nickel at all — installing a toolchain in order to fail.

The fix

  • One shared pathspec. detect and the job both use
    '*.ncl' ':!*.k9.ncl'. A guard that counts a different set than its consumer
    checks is how this defect arose
    , so the cure is that they cannot diverge.
  • k9 contracts are disclosed, not hidden — counted as N_K9, printed in the
    detection table, and explicitly excluded from the Total (the same shape as
    the existing "detected but unsupported" disclosure).
  • Typecheck is skipped only where an import target is untracked in git, and
    every skip is disclosed by name with its reason via ::notice and in the
    step summary. A skip is never a pass. Comments are stripped before scanning —
    _base.ncl documents its own usage in a # comment containing a literal
    import "../_base.ncl", and matching that would have skipped a file that
    typechecks perfectly well.
  • Format is still checked over every genuine .ncl, with no exemption. This
    narrows the file set; it does not weaken the check.
  • Narrowing cannot manufacture a pass. The job prints its denominators and
    refuses when zero files survive, or when every file was skipped.

Still read-only: --check only, no --fix, no nickel format in CI.

Verification — the mutants, not just the greens

Run with the workflow's own pinned nickel 1.18.0 (sha256-verified), and the
embedded step body extracted from this YAML and diffed byte-identical to the
script under test, so these results are about the artefact, not a paraphrase.

control expected got
unmodified tree exit 1, 11 format errors, 2 named skips ✅
formatted tree exit 0 — 11 checked / 9 typechecked / 2 skipped / 16 k9 excluded ✅
injected type error exit 1 ✅
one file un-formatted exit 1 ✅
every file skipped exit 1, refuses — does not report a pass ✅
k9-only tree has_nickel=false; job refuses if reached ✅

Format-safety control for the follow-up commits: nickel pprint-ast is
byte-identical for 11/11 files before and after nickel format, so the
reformatting is provably semantics-preserving.

Consequence, stated plainly

Repos that were vacuously green because their only .ncl were k9 contracts
will now correctly report no Nickel. That is #976's intended cure, not a
regression.

This alone does not turn cicd-squabbler green: all 11 of its genuine .ncl
genuinely fail format --check. That is a real defect in that repo and is fixed
in its own PR, together with the matching fix in rsr-template-repo so future
seeded repos do not inherit it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

`*.k9.ncl` files are k9 contracts, not Nickel source: they open with a
`K9!` sentinel on line 1, so `nickel typecheck` dies at 1:3 on the `!`.
The gate globbed `*.ncl` and swallowed them, so it failed over files the
repo has no way to fix. Measured in cicd-squabbler: 16 of 27 `.ncl` are
k9 contracts, and 2 more import JSON generated at build time and
correctly uncommitted — 18 of 27 could never pass.

`detect` counted the same inflated glob, so `has_nickel` went true on
repos holding no Nickel at all, installing a toolchain to fail. detect
and the job now share ONE pathspec: a guard that counts a different set
than its consumer checks is how this defect arose.

Typecheck is skipped only where an `import` target is untracked in git,
each skip disclosed by name with its reason. Comments are stripped before
scanning, because `_base.ncl` documents its own usage in a `#` comment
containing a literal import. Format is still checked over every genuine
Nickel file, with no exemption.

Narrowing cannot manufacture a pass: the job prints its denominators and
refuses when zero files survive, or when every file was skipped.

Verified with the workflow's own pinned nickel 1.18.0, the embedded step
body extracted byte-identical to the tested script:
  - unmodified tree    -> exit 1, 11 format errors, 2 named skips
  - formatted tree     -> exit 0, 11 checked / 9 typechecked / 2 skipped
  - injected type error-> exit 1
  - un-formatted file  -> exit 1
  - all files skipped  -> exit 1 (refuses, does not pass)
  - k9-only tree       -> has_nickel false; job refuses if reached

Refs: #982, #976

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR
@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 8f86fb94-4f70-405d-9661-b75292737bc4

📥 Commits

Reviewing files that changed from the base of the PR and between de68103 and 4d5db63.

📒 Files selected for processing (1)
  • .github/workflows/ci-pipeline.yml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (22)
  • GitHub Check: Trust pipeline summary
  • GitHub Check: scan / gitleaks
  • GitHub Check: governance / Workflow security linter
  • GitHub Check: governance / Well-Known (RFC 9116 + RSR)
  • GitHub Check: governance / Guix packaging policy (Nix retired)
  • GitHub Check: governance / Actions lockfile verify
  • GitHub Check: governance / Exemption ratchet
  • GitHub Check: governance / Code quality + docs
  • GitHub Check: governance / Licence consistency
  • GitHub Check: governance / Trusted-base reduction policy
  • GitHub Check: governance / Debt ratchet
  • GitHub Check: governance / Security policy checks
  • GitHub Check: governance / Check Workflow Staleness
  • GitHub Check: scan / Hypatia Neurosymbolic Analysis
  • GitHub Check: scorecard / Run Scorecard PR
  • GitHub Check: analyze-actions / analyze
  • GitHub Check: analyze-js / analyze
  • GitHub Check: K9-SVC contractile validation
  • GitHub Check: Registry + topology in sync
  • GitHub Check: Verify CLAIMS.a2ml + conformance
  • GitHub Check: Check Documentation Format
  • GitHub Check: Repo self-tests
🔇 Additional comments (1)
.github/workflows/ci-pipeline.yml (1)

132-139: LGTM!

Also applies to: 234-244, 901-901


📝 Summary

Summary by CodeRabbit

  • Bug Fixes

    • Improved automated validation to distinguish Nickel sources from k9 contracts.
    • Nickel checks now accurately report the files being validated and identify files skipped due to unavailable imports.
    • Prevented successful validation runs when no Nickel files were actually typechecked.
  • Chores

    • Updated CI reporting to clearly reflect the separate handling of Nickel sources and k9 contracts.

Walkthrough

The CI workflow now separates k9 contracts from Nickel sources. It checks format for genuine Nickel files, skips typechecking only when imports are untracked, reports each skip, and fails when no file is typechecked.

Changes

Nickel CI validation

Layer / File(s) Summary
File detection and reporting
.github/workflows/ci-pipeline.yml
Detection counts *.ncl files without *.k9.ncl and counts k9 contracts separately. Report text documents the exclusion and updated skip condition.
Nickel job validation
.github/workflows/ci-pipeline.yml
The job checks every genuine Nickel file, skips typechecking for files with untracked imports, reports skip reasons and counts, and fails when zero files are typechecked.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions as GitHub Actions Nickel job
  participant GitRepository as Git repository
  participant NickelCLI as Nickel CLI
  participant StepSummary as Step summary
  GitHubActions->>GitRepository: List *.ncl excluding *.k9.ncl
  GitHubActions->>NickelCLI: Check format for each genuine Nickel file
  GitHubActions->>GitRepository: Resolve imported targets
  GitHubActions->>NickelCLI: Typecheck files with tracked imports
  GitHubActions->>StepSummary: Report validation counts and skip reasons
Loading

Suggested reviewers: joshuajewell

Merge Risk: ⚪ Minimal · up to 4d5db

The Nickel gate’s documented filtering and skip behavior is implemented without an outstanding actionable issue.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: excluding k9 contracts from the Nickel CI gate.
Description check ✅ Passed The description directly explains the CI defect, the k9 exclusion, the typecheck skip rules, and the verification results.
Linked Issues check ✅ Passed The change satisfies the coding requirements in [#982]. detect and the Nickel job use *.ncl with :!*.k9.ncl, and the workflow reports excluded k9 files separately. nickel format --check still …
Out of Scope Changes check ✅ Passed The reviewed change is limited to .github/workflows/ci-pipeline.yml. The detection changes, k9 disclosure, typecheck skip reporting, denominator checks, and refusal conditions directly implement [#9…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks the Nickel trail
K9 files leave the typecheck rail
Format guards each source in sight
Missing imports earn a note in white
No checked files means the gate says no

Comment @coderabbitai help to get the list of available commands.

hyperpolymath added a commit to hyperpolymath/cicd-squabbler that referenced this pull request Sep 22, 2026
Formatting only — all 11 genuine Nickel files in this repo fail
`nickel format --check`.

This is the **repo's own** half of the Nickel red. The other half was a
defect in
the shared gate, fixed in hyperpolymath/standards#985: it globbed
`*.ncl` and so
also checked the 16 `*.k9.ncl` **k9 contracts**, which are a different
format
(`K9!` sentinel on line 1) and can never pass. With that gate fix alone
this repo
would still be red, on these 11 files, legitimately.

## Verification

Run with the pipeline's **own pinned nickel 1.18.0** (sha256-verified
from the
workflow), not a local build — formatter output differs between
releases.

| control | result |
|---|---|
| `nickel pprint-ast` byte-identical before vs after | **11 / 11** |
| SPDX + copyright headers unchanged | 11 / 11 |
| total comment lines | 353 before, 353 after |
| files touched outside `*.ncl` | 0 |
| `nickel format --check` after | passes on all 11 |

The AST comparison is the point: this is provably a cosmetic reformat,
not a
semantic change.

## Not an auto-fix

No `--fix` runs in CI. The pipeline still uses `--check` only; this is a
deliberate commit in a reviewable PR.

## Remaining

Once standards#985 merges, this repo's caller needs re-pinning to that
squash
SHA. Until then the pipeline check here still runs the old gate and will
stay
red on the k9 contracts — that is expected and is not caused by this PR.

The 2 files importing build-time JSON (`claude-md-data.json`,
`clauses.json`)
remain un-typecheckable standalone by design; standards#985 skips them
and
discloses each skip by name rather than pretending to check them.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath merged commit f95130b into main Sep 22, 2026
46 checks passed
@hyperpolymath
hyperpolymath deleted the fix/nickel-gate-excludes-k9-contracts branch September 22, 2026 13:54
hyperpolymath added a commit to hyperpolymath/rsr-template-repo that referenced this pull request Sep 22, 2026
Formatting only — all 11 genuine Nickel files in the template fail
`nickel format --check`.

**This is where the defect originates.** Every repo seeded from this
template
inherits these files, so each one goes red on the ci-pipeline Nickel
gate over
boilerplate it did not write. `cicd-squabbler` is the measured case
(hyperpolymath/cicd-squabbler#106) — it went 100% red on template files,
never on
its own source. Fixing the template stops the defect propagating to new
seeds.

The other half of that red was a defect in the shared gate itself, fixed
in
hyperpolymath/standards#985: it globbed `*.ncl`, so it also checked the
18
`*.k9.ncl` **k9 contracts** here — a different format (`K9!` sentinel on
line 1)
that can never pass `nickel typecheck`. Those 18 files are untouched by
this PR.

## Verification

Run with the pipeline's **own pinned nickel 1.18.0** (sha256-verified
from the
workflow), not a local build — formatter output differs between
releases.

| control | result |
|---|---|
| `nickel pprint-ast` byte-identical before vs after | **11 / 11** |
| SPDX + copyright headers unchanged | 11 / 11 |
| total comment lines | 356 before, 356 after |
| files touched outside genuine `*.ncl` | 0 |
| `nickel format --check` after | passes on all 11 |

The AST comparison is the point: this is provably a cosmetic reformat,
not a
semantic change.

## Not an auto-fix

No `--fix` runs in CI. The pipeline still uses `--check` only; this is a
deliberate commit in a reviewable PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
hyperpolymath added a commit to hyperpolymath/tropical-types that referenced this pull request Sep 22, 2026
…3f65 (#56)

## What

Re-pins this repository's `standards-pipeline.yml` caller from
`2eb9bb19` to
**`f95130bb`** — the squash merge of [hyperpolymath/standards#985][985].

## Why

`2eb9bb19` predates #985, which fixed the `ci-pipeline` detect gate.
Every caller
still on the old pin runs the **pre-fix** gate. The workflow is
`pull_request`-triggered
only, so the failure is latent: it does not manifest until the next PR
is opened here.

## What moves

Two lines, together:

| Line | From | To |
|---|---|---|
| provenance comment | `@ 2eb9bb19 — ci-pipeline.yml blob d2583657.` |
`@ f95130bb — ci-pipeline.yml blob 8bcdeaf2.` |
| `uses:` ref | `...ci-pipeline.yml@2eb9bb19...` |
`...ci-pipeline.yml@f95130bb...` |

A SHA bump that leaves the blob comment behind is a **phantom pin** — it
names a tree
it can no longer be checked against — so both change or neither does.

## Why `f95130bb` and not current `main`

`main` has since moved to `d1bd7f42` (#988, a changelog fix). `f95130bb`
was chosen
deliberately:

- `ci-pipeline.yml` is **byte-identical at both** — blob `8bcdeaf2`
either way.
- `f95130bb` is the **reviewed** revision: the commit #985 was merged
as.
- Its only failing checks are `SonarCloud Code Analysis` and the mirror
trio
(`mirror-gitea`, `mirror-disroot`, `mirror-codeberg`) — all four are
listed in
standards' own `config/rulesets/gates.json` under
`never_required_workflows`.
  Nothing ci-pipeline-related is red there.

`ci-pipeline.yml` pins its own sub-reusables fully-qualified at
`571cc734` rather than
`./`, so this pin selects only which `ci-pipeline.yml` is read — not its
dependencies.

## Verification

- Pre-flight refused to edit unless the exact pre-fix SHA **and** the
expected
  provenance-comment shape were both present.
- Post-flight asserted exactly `2/2` changed lines, no residue of
`2eb9bb19` or
  `d2583657`, and the new SHA present.
- Commit is SSH-signed (`%G?` = `G`).

[985]: hyperpolymath/standards#985

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
hyperpolymath added a commit to hyperpolymath/modshells that referenced this pull request Sep 22, 2026
…3f65 (#122)

## What

Re-pins this repository's `standards-pipeline.yml` caller from
`2eb9bb19` to
**`f95130bb`** — the squash merge of [hyperpolymath/standards#985][985].

## Why

`2eb9bb19` predates #985, which fixed the `ci-pipeline` detect gate.
Every caller
still on the old pin runs the **pre-fix** gate. The workflow is
`pull_request`-triggered
only, so the failure is latent: it does not manifest until the next PR
is opened here.

## What moves

Two lines, together:

| Line | From | To |
|---|---|---|
| provenance comment | `@ 2eb9bb19 — ci-pipeline.yml blob d2583657.` |
`@ f95130bb — ci-pipeline.yml blob 8bcdeaf2.` |
| `uses:` ref | `...ci-pipeline.yml@2eb9bb19...` |
`...ci-pipeline.yml@f95130bb...` |

A SHA bump that leaves the blob comment behind is a **phantom pin** — it
names a tree
it can no longer be checked against — so both change or neither does.

## Why `f95130bb` and not current `main`

`main` has since moved to `d1bd7f42` (#988, a changelog fix). `f95130bb`
was chosen
deliberately:

- `ci-pipeline.yml` is **byte-identical at both** — blob `8bcdeaf2`
either way.
- `f95130bb` is the **reviewed** revision: the commit #985 was merged
as.
- Its only failing checks are `SonarCloud Code Analysis` and the mirror
trio
(`mirror-gitea`, `mirror-disroot`, `mirror-codeberg`) — all four are
listed in
standards' own `config/rulesets/gates.json` under
`never_required_workflows`.
  Nothing ci-pipeline-related is red there.

`ci-pipeline.yml` pins its own sub-reusables fully-qualified at
`571cc734` rather than
`./`, so this pin selects only which `ci-pipeline.yml` is read — not its
dependencies.

## Verification

- Pre-flight refused to edit unless the exact pre-fix SHA **and** the
expected
  provenance-comment shape were both present.
- Post-flight asserted exactly `2/2` changed lines, no residue of
`2eb9bb19` or
  `d2583657`, and the new SHA present.
- Commit is SSH-signed (`%G?` = `G`).

[985]: hyperpolymath/standards#985

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
hyperpolymath added a commit to hyperpolymath/ddraig-ssg that referenced this pull request Sep 22, 2026
…3f65 (#22)

## What

Re-pins this repository's `standards-pipeline.yml` caller from
`2eb9bb19` to
**`f95130bb`** — the squash merge of [hyperpolymath/standards#985][985].

## Why

`2eb9bb19` predates #985, which fixed the `ci-pipeline` detect gate.
Every caller
still on the old pin runs the **pre-fix** gate. The workflow is
`pull_request`-triggered
only, so the failure is latent: it does not manifest until the next PR
is opened here.

## What moves

Two lines, together:

| Line | From | To |
|---|---|---|
| provenance comment | `@ 2eb9bb19 — ci-pipeline.yml blob d2583657.` |
`@ f95130bb — ci-pipeline.yml blob 8bcdeaf2.` |
| `uses:` ref | `...ci-pipeline.yml@2eb9bb19...` |
`...ci-pipeline.yml@f95130bb...` |

A SHA bump that leaves the blob comment behind is a **phantom pin** — it
names a tree
it can no longer be checked against — so both change or neither does.

## Why `f95130bb` and not current `main`

`main` has since moved to `d1bd7f42` (#988, a changelog fix). `f95130bb`
was chosen
deliberately:

- `ci-pipeline.yml` is **byte-identical at both** — blob `8bcdeaf2`
either way.
- `f95130bb` is the **reviewed** revision: the commit #985 was merged
as.
- Its only failing checks are `SonarCloud Code Analysis` and the mirror
trio
(`mirror-gitea`, `mirror-disroot`, `mirror-codeberg`) — all four are
listed in
standards' own `config/rulesets/gates.json` under
`never_required_workflows`.
  Nothing ci-pipeline-related is red there.

`ci-pipeline.yml` pins its own sub-reusables fully-qualified at
`571cc734` rather than
`./`, so this pin selects only which `ci-pipeline.yml` is read — not its
dependencies.

## Verification

- Pre-flight refused to edit unless the exact pre-fix SHA **and** the
expected
  provenance-comment shape were both present.
- Post-flight asserted exactly `2/2` changed lines, no residue of
`2eb9bb19` or
  `d2583657`, and the new SHA present.
- Commit is SSH-signed (`%G?` = `G`).

[985]: hyperpolymath/standards#985

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
hyperpolymath added a commit to hyperpolymath/cicd-squabbler that referenced this pull request Sep 22, 2026
…3f65 (#107)

## What

Re-pins this repository's `standards-pipeline.yml` caller from
`2eb9bb19` to
**`f95130bb`** — the squash merge of [hyperpolymath/standards#985][985].

## Why

`2eb9bb19` predates #985, which fixed the `ci-pipeline` detect gate.
Every caller
still on the old pin runs the **pre-fix** gate. The workflow is
`pull_request`-triggered
only, so the failure is latent: it does not manifest until the next PR
is opened here.

## What moves

Two lines, together:

| Line | From | To |
|---|---|---|
| provenance comment | `@ 2eb9bb19 — ci-pipeline.yml blob d2583657.` |
`@ f95130bb — ci-pipeline.yml blob 8bcdeaf2.` |
| `uses:` ref | `...ci-pipeline.yml@2eb9bb19...` |
`...ci-pipeline.yml@f95130bb...` |

A SHA bump that leaves the blob comment behind is a **phantom pin** — it
names a tree
it can no longer be checked against — so both change or neither does.

## Why `f95130bb` and not current `main`

`main` has since moved to `d1bd7f42` (#988, a changelog fix). `f95130bb`
was chosen
deliberately:

- `ci-pipeline.yml` is **byte-identical at both** — blob `8bcdeaf2`
either way.
- `f95130bb` is the **reviewed** revision: the commit #985 was merged
as.
- Its only failing checks are `SonarCloud Code Analysis` and the mirror
trio
(`mirror-gitea`, `mirror-disroot`, `mirror-codeberg`) — all four are
listed in
standards' own `config/rulesets/gates.json` under
`never_required_workflows`.
  Nothing ci-pipeline-related is red there.

`ci-pipeline.yml` pins its own sub-reusables fully-qualified at
`571cc734` rather than
`./`, so this pin selects only which `ci-pipeline.yml` is read — not its
dependencies.

## Verification

- Pre-flight refused to edit unless the exact pre-fix SHA **and** the
expected
  provenance-comment shape were both present.
- Post-flight asserted exactly `2/2` changed lines, no residue of
`2eb9bb19` or
  `d2583657`, and the new SHA present.
- Commit is SSH-signed (`%G?` = `G`).

[985]: hyperpolymath/standards#985

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
hyperpolymath added a commit to hyperpolymath/AcceleratorGate.jl that referenced this pull request Sep 22, 2026
## What

Re-pins this repository's `standards-pipeline.yml` caller from
`2eb9bb19` to
**`f95130bb`** — the squash merge of [hyperpolymath/standards#985][985].

## Why

`2eb9bb19` predates #985, which fixed the `ci-pipeline` detect gate.
Every caller
still on the old pin runs the **pre-fix** gate. The workflow is
`pull_request`-triggered
only, so the failure is latent: it does not manifest until the next PR
is opened here.

## What moves

Two lines, together:

| Line | From | To |
|---|---|---|
| provenance comment | `@ 2eb9bb19 — ci-pipeline.yml blob d2583657.` |
`@ f95130bb — ci-pipeline.yml blob 8bcdeaf2.` |
| `uses:` ref | `...ci-pipeline.yml@2eb9bb19...` |
`...ci-pipeline.yml@f95130bb...` |

A SHA bump that leaves the blob comment behind is a **phantom pin** — it
names a tree
it can no longer be checked against — so both change or neither does.

## Why `f95130bb` and not current `main`

`main` has since moved to `d1bd7f42` (#988, a changelog fix). `f95130bb`
was chosen
deliberately:

- `ci-pipeline.yml` is **byte-identical at both** — blob `8bcdeaf2`
either way.
- `f95130bb` is the **reviewed** revision: the commit #985 was merged
as.
- Its only failing checks are `SonarCloud Code Analysis` and the mirror
trio
(`mirror-gitea`, `mirror-disroot`, `mirror-codeberg`) — all four are
listed in
standards' own `config/rulesets/gates.json` under
`never_required_workflows`.
  Nothing ci-pipeline-related is red there.

`ci-pipeline.yml` pins its own sub-reusables fully-qualified at
`571cc734` rather than
`./`, so this pin selects only which `ci-pipeline.yml` is read — not its
dependencies.

## Verification

- Pre-flight refused to edit unless the exact pre-fix SHA **and** the
expected
  provenance-comment shape were both present.
- Post-flight asserted exactly `2/2` changed lines, no residue of
`2eb9bb19` or
  `d2583657`, and the new SHA present.
- Commit is SSH-signed (`%G?` = `G`).

[985]: hyperpolymath/standards#985

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ji1bq3TypfycfUPAR7hSxR

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.

ci-pipeline.yml Nickel job globs *.k9.ncl and generated-input .ncl: 20 of 29 template files can never pass

1 participant