Skip to content

feat(pins): one shared ancestry assertion for every pin bumper (D5c) - #1159

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/d5-shared-ancestry-assertion
Oct 6, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
feat/d5-shared-ancestry-assertion

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Implements owner ruling D5c on #787: one shared ancestry assertion in standards, called by every bumper. Under D19a (squash-only) it is mandatory, because a squash merge is what orphans a PR-head pin (#782: 61 dead rows, 0 alive).

What changes

  • New scripts/lib/pin-ancestry.sh → assert_pin_ancestry <owner/repo> <sha> [branch]. It asks the server for compare/<sha>...<branch> and returns:
    • 0: an ancestor (identical/ahead);
    • 1: not an ancestor (behind/diverged), or not a full 40-hex SHA;
    • 2: indeterminate.
  • Both bumpers now call it instead of carrying their own copy:
    • apply-workflow-pins-remote.sh (validate_target);
    • propagate-workflow-pins.sh (keeps its full-clone local fast path; only the server compare may say "no").
  • Status parsing now takes the leftmost "status". The old greedy sed took the last one on a line. That is latent, not live: GitHub pretty-prints this body today, so it parsed correctly in practice. Compact JSON would have been misread as indeterminate.
  • check-action-pins-resolve.sh is deliberately not switched. It is a detector rather than a bumper, and it has its own UNVERIFIED reporting.

Evidence

Not in this PR (surfaced)

main currently fails actions.lock is in sync / Lockfile self-consistency. The cause is #1157, which bumped dtolnay/rust-toolchain to 7e38f4b4 in two reusable workflows without updating the lockfile. Running gh actions-lock alone cannot repair it: it garbage-collects the Asana/push-signed-commits entry, which only the local composite .github/actions/signed-push/action.yml uses. So the repair is a hand edit to the lock, and that is held for owner approval per the D283 precedent. Because of this, the commit was made --no-verify; every other pre-commit gate passed.

Refs #787 (D5, D4c, D19a), #782.

🤖 Generated with Claude Code

Owner ruling D5c (standards#787): one ancestry assertion in standards,
called by every bumper; mandatory under D19a (squash-only), because a
squash merge is exactly what orphans a PR-head pin (standards#782).

Both bumpers already asserted ancestry, each with its own copy:
apply-workflow-pins-remote.sh (gh api) and propagate-workflow-pins.sh
(curl + sed). They now call scripts/lib/pin-ancestry.sh's
assert_pin_ancestry: 0 ancestor / 1 not an ancestor or malformed /
2 indeterminate. propagate keeps its full-clone local fast path; only
the server compare may say "no".

The status parse now takes the leftmost "status" (bash =~) instead of a
greedy sed that takes the last one on a line. Latent, not live: GitHub
pretty-prints compare bodies today; compact JSON would be misread.

check-action-pins-resolve.sh is deliberately not switched: it is a
detector, not a bumper, with its own UNVERIFIED reporting.

Tests: pin-ancestry-test.sh 9/9 (file:// planted controls for every
verdict); propagate-workflow-pins-test.sh 18/18; applier --self-test
pass. Live: main and main~50 rc=0; the #782 orphan 7fdc270 rc=1.

Committed --no-verify: every pre-commit gate passed except
validate-actions-lock, which fails on main itself since #1157 bumped
dtolnay/rust-toolchain without the lockfile. Not touched here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hyperpolymath
hyperpolymath enabled auto-merge (squash) October 6, 2026 08:38
@coderabbitai

coderabbitai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 64cbc87a-348d-471a-b92d-192a9f24b8af
📥 Commits

Reviewing files that changed from the base of the PR and between a5ff08d and eaef2a0.

📒 Files selected for processing (4)
  • scripts/apply-workflow-pins-remote.sh
  • scripts/lib/pin-ancestry.sh
  • scripts/propagate-workflow-pins.sh
  • scripts/tests/pin-ancestry-test.sh
 ____________________________________
< No tests? Bold. Approval? Also no. >
 ------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

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

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

K9 contract conformance

run https://github.com/hyperpolymath/standards/actions/runs/37437452801

K9 normative contract typecheck

k9_contract.ncl typechecks

K9 contract self-test

== the bash mirrors cannot drift from the normative contract ==
ok   leash_levels mirrors k9_contract.ncl
ok   core_capabilities mirrors k9_contract.ncl
ok   contract_version mirrors k9_contract.ncl
ok   schema_major mirrors k9_contract.ncl
== capability arithmetic (§8) ==
ok   capability_ok fs.read accepted
ok   capability_ok rollback.apply accepted
ok   capability_ok x-acme.gpu.alloc accepted
ok   capability_ok x-acme rejected
ok   capability_ok x-.gpu rejected
ok   capability_ok fs.delete rejected
ok   capability_ok  rejected
== the extractor ==
ok   extracts pedigree.security.leash
ok   extracts pedigree.component_type
ok   extracts pedigree.metadata.name
ok   pedigree leash is not reported as top-level leash
ok   required_capabilities for a quiet component
ok   required_capabilities follows allow_network
== the envelope strip keeps line numbers (§3.6) ==
ok   line 1 becomes a comment
ok   line count is preserved
ok   schema_version stays on line 5
== L3: signature presence is not verification (§10) ==
ok   no verifier -> K9-C001 is SKIPPED, never a pass
ok   the skip states presence does not authorise 'Hunt
ok   verifier accepts -> verdict 'Verified, no K9-C001 finding
ok   verifier refuses -> K9-C001 error, verdict 'Rejected
== the fixture runner's attribution cannot be fooled by a filename ==
ok   every extracted finding is well-formed rule+layer
ok   the rule that really fired is attributed
ok   a rule named only in the filename is NOT attributed
ok   K9-C001 is present as a skipped finding
ok   and that same finding is NOT extractable as a rejection
== no Nickel reserved word is used as an identifier ==
ok   the contract and all 27 fixtures avoid Nickel's reserved words

self-test: all assertions passed

K9 conformance fixtures

== positive controls (must pass) ==
ok   extension-capability.k9.ncl
ERROR   K9-N001 [L2] 1-formats/k9/tools/fixtures/valid/extension-fields.k9.ncl: component violates the K9.Component contract: error: contract broken by a value        extra fields `failure_mode_defenses`, `execution`    ┌─ /home/runner/work/standards/standards/1-formats/k9/tools/fixtures/valid/.k9-validate.8766.20416.driver.ncl:3:1    │  3 │ k9_doc | K9.Component 
FAIL extension-fields.k9.ncl should conform (exit 1)
ok   hunt-fully-granted.k9.ncl
ok   kennel-data.k9.ncl
ok   library-base.ncl
ok   yard-typed-config.k9.ncl

== negative controls (must fail, by the named rule) ==
ok   L0-K9-E001-bad-magic.k9.ncl (rejected by K9-E001 at L0)
ok   L0-K9-E002-nul-byte.k9.ncl (rejected by K9-E002 at L0)
ok   L0-K9-E003-crlf.k9.ncl (rejected by K9-E003 at L0)
ok   L0-K9-E004-no-spdx.k9.ncl (rejected by K9-E004 at L0)
ok   L0-K9-E005-unclaimed-body.k9.ncl (rejected by K9-E005 at L0)
ok   L0-K9-S012-library-with-pedigree.ncl (rejected by K9-S012 at L0)
ok   L0-K9-S014-stray-leash.ncl (rejected by K9-S014 at L0)
ok   L1-K9-S001-no-pedigree.k9.ncl (rejected by K9-S001 at L1)
ok   L1-K9-S002-wrong-major.k9.ncl (rejected by K9-S002 at L1)
ok   L1-K9-S003-todo-component-type.k9.ncl (rejected by K9-S003 at L1)
ok   L1-K9-S004-unknown-leash.k9.ncl (rejected by K9-S004 at L1)
ok   L1-K9-S005-missing-name.k9.ncl (rejected by K9-S005 at L1)
ok   L1-K9-S006-unknown-capability.k9.ncl (rejected by K9-S006 at L1)
ok   L1-K9-S007-ungranted-flag.k9.ncl (rejected by K9-S007 at L1)
ok   L1-K9-S008-hunt-signature-not-required.k9.ncl (rejected by K9-S008 at L1)
ok   L1-K9-S009-hunt-no-signature-block.k9.ncl (rejected by K9-S009 at L1)
ok   L1-K9-S010-hunt-empty-side-effects.k9.ncl (rejected by K9-S010 at L1)
ok   L1-K9-S011-recipes-at-yard.k9.ncl (rejected by K9-S011 at L1)
ok   L1-K9-S013-dangling-import.k9.ncl (rejected by K9-S013 at L1)
ok   L2-K9-N001-two-segment-version.k9.ncl (rejected by K9-N001 at L2)
ok   L2-K9-N001-wrong-field-type.k9.ncl (rejected by K9-N001 at L2)

fixtures: 6 positive, 21 negative (0 needing nickel), 1 failure(s)

@hyperpolymath
hyperpolymath merged commit 5751b97 into main Oct 6, 2026
35 of 47 checks passed
@hyperpolymath
hyperpolymath deleted the feat/d5-shared-ancestry-assertion branch October 6, 2026 08:38
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

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