Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e17a2c1
fix(harness): exercise real verifier gates in conformance runner
EfeDurmaz16 Jul 13, 2026
c293251
test(harness): require declared conformance modes to execute
EfeDurmaz16 Jul 13, 2026
f01a9f0
feat(harness): declare per-runner modesByIntent and add adversarial v…
EfeDurmaz16 Jul 13, 2026
03cf978
ci(harness): add non-vacuous run-count gate
EfeDurmaz16 Jul 13, 2026
5dff045
ci: fail closed on routed SDK gate ambiguity
EfeDurmaz16 Jul 13, 2026
470cd2e
ci: enforce Rust coverage fail closed
EfeDurmaz16 Jul 13, 2026
6f86863
ci(harness): block fail-open default stores with semgrep
EfeDurmaz16 Jul 13, 2026
2558422
ci: track PR216 delivery ledger and harden repo hygiene
EfeDurmaz16 Jul 13, 2026
436eb49
ci: wire adversarial gates into workflows
EfeDurmaz16 Jul 13, 2026
7ee3668
chore(ci): reconcile PR216 ledger against rebased base
EfeDurmaz16 Jul 13, 2026
cc93323
fix(harness): reconcile boot-policy probes to delivered contracts
EfeDurmaz16 Jul 13, 2026
1b2cc07
ci: drop duplicated python.yml hunk owned by #228
EfeDurmaz16 Jul 13, 2026
efc620a
fix(harness): restore php/ruby/lua native off-localnet store guards t…
EfeDurmaz16 Jul 13, 2026
7b416f9
test(harness): gate covered boot-policy probes on in-tree guard presence
EfeDurmaz16 Jul 13, 2026
66964c3
test(harness): scope missing-ATA blocking gate to harness.yml
EfeDurmaz16 Jul 13, 2026
6cbdcbc
fix(ci): align python.yml payment-channels checkout to solana-foundation
EfeDurmaz16 Jul 13, 2026
d4d0e42
docs(ledger): reflect #214/#229/#230/#231/#232 merged to main in the …
EfeDurmaz16 Jul 14, 2026
de71232
ci(harness): add the rehearsal rebuild script for the #216 cascade
EfeDurmaz16 Jul 14, 2026
4318b8a
Merge remote-tracking branch 'origin/fix/mpp-replay-store-hardening' …
EfeDurmaz16 Jul 14, 2026
25ab4d1
Merge remote-tracking branch 'origin/fix/mpp-subscription-hardening' …
EfeDurmaz16 Jul 14, 2026
ba2d499
Merge remote-tracking branch 'origin/fix/python-security-hardening' i…
EfeDurmaz16 Jul 14, 2026
0e3abd7
Merge remote-tracking branch 'origin/fix/mpp-session-state-hardening'…
EfeDurmaz16 Jul 14, 2026
a910384
Merge remote-tracking branch 'origin/fix/x402-replay-hardening' into …
EfeDurmaz16 Jul 14, 2026
8cec61d
fix(semgrep): exclude typeof guards from the nonconstant-time secret …
EfeDurmaz16 Jul 14, 2026
9d2e059
Merge remote-tracking branch 'origin/fix/x402-replay-hardening' into …
EfeDurmaz16 Jul 14, 2026
dc6443a
Merge remote-tracking branch 'origin/fix/mpp-subscription-hardening' …
EfeDurmaz16 Jul 14, 2026
e4e91a5
Merge remote-tracking branch 'origin/fix/rust-security-hardening' int…
EfeDurmaz16 Jul 14, 2026
be4bc47
Merge remote-tracking branch 'origin/fix/ruby-replay-store-capability…
EfeDurmaz16 Jul 14, 2026
047aa78
docs(ledger): revalidate the #216 equivalence ledger against the comp…
EfeDurmaz16 Jul 14, 2026
612271a
test(harness): track sibling contract renames in the boot-policy and …
EfeDurmaz16 Jul 14, 2026
c77c582
test(harness): satisfy the hardened session confirmation contracts in…
EfeDurmaz16 Jul 14, 2026
2296eab
build(rehearsal): order cascade for conflict-free merges + prove pure…
EfeDurmaz16 Jul 14, 2026
542b229
fix(harness): give the on-chain settlement suite an atomic production…
EfeDurmaz16 Jul 14, 2026
6464c08
test(rust-cov): exempt the two on-chain-heavy MPP files behind the sa…
EfeDurmaz16 Jul 14, 2026
b9fe46b
style(mpp): normalize the merged blockhash cache (fmt + drop duplicat…
EfeDurmaz16 Jul 14, 2026
a53a899
Merge remote-tracking branch 'origin/fix/ruby-replay-store-capability…
EfeDurmaz16 Jul 15, 2026
862b83d
test(harness): seal the gate self-activation chain and track the new …
EfeDurmaz16 Jul 15, 2026
5c8ca50
Merge remote-tracking branch 'origin/fix/ruby-replay-store-capability…
EfeDurmaz16 Jul 15, 2026
a28ed5e
Merge remote-tracking branch 'origin/fix/ruby-replay-store-capability…
EfeDurmaz16 Jul 15, 2026
4c838c1
Merge remote-tracking branch 'origin/fix/ruby-replay-store-capability…
EfeDurmaz16 Jul 15, 2026
d45635d
Merge remote-tracking branch 'origin/fix/ruby-replay-store-capability…
EfeDurmaz16 Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/actions/setup-harness/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ runs:
args=()
IFS=',' read -ra parts <<< "$bins"
for b in "${parts[@]}"; do args+=(--bin "$b"); done
echo "cargo build -p $pkg ${args[*]}"
cargo build -p "$pkg" "${args[@]}"
echo "cargo build --locked -p $pkg ${args[*]}"
cargo build --locked -p "$pkg" "${args[@]}"
done

- name: Install harness
Expand Down
13 changes: 13 additions & 0 deletions .github/delivery/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Delivery ledgers

Delivery ledgers inventory source work without treating file presence as proof of
semantic delivery. `pr216-ledger.json` is pinned to the authoritative
`49dc797..45ad8c9` commit and path sets. Validate it with:

```sh
node scripts/validate-pr216-ledger.mjs
node scripts/validate-pr216-ledger_test.mjs
```

Only use `integrated` with independently checkable evidence. Keep unresolved
work as `open_pr` or `missing` with an owner and concrete follow-up.
8,085 changes: 8,085 additions & 0 deletions .github/delivery/pr216-ledger.json

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions .github/workflows/harness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ jobs:
- name: Checkout payment channels program
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
repository: Moonsong-Labs/solana-payment-channels
ref: d1dee6b34d45d4e4a1ed3174ef421ca2e801aaea
repository: solana-foundation/payment-channels
ref: 0c07d5751c8972abf6a219570a3f39a72f46f879
path: _payment-channels
fetch-depth: 1
# Pinned Agave release, fetched as a tarball and checksum-verified.
Expand Down Expand Up @@ -235,10 +235,14 @@ jobs:
fi
pnpm exec vitest run test/e2e.test.ts --testTimeout 180000 --reporter=default --reporter=json --outputFile=vitest-report.json
node scripts/assert-run-count.mjs --report vitest-report.json --exact 1
- name: Focused Python session missing-ATA rejection
- name: Focused Python session missing-ATA settlement invariant (deliver-or-reject)
working-directory: harness
# This regression is blocking: a successful response must never hide a
# settlement that delivered no funds because the recipient ATA was absent.
# Blocking (no continue-on-error): a settle reported successful
# (200 + settledSignature) MUST deliver the payout to the recipient ATA,
# creating it idempotently when absent. A clean rejection (>= 400, no
# receipt surfaced, no delivery) is equally acceptable. The only failure
# is the false-paid condition — a confirmed receipt with no on-chain
# delivery — which #216 fixed and this leg keeps release-blocking.
env:
MPP_HARNESS_INTENTS: session
MPP_HARNESS_SCENARIOS: session-basic
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/lua.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ jobs:
test-lua:
name: Lua tests
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5

Expand Down
40 changes: 7 additions & 33 deletions .github/workflows/pr-routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
swift: ${{ steps.select.outputs.swift }}
kotlin: ${{ steps.select.outputs.kotlin }}
harness: ${{ steps.select.outputs.harness }}
docs_only: ${{ steps.select.outputs.docs_only }}
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
Expand All @@ -40,7 +41,9 @@ jobs:
node-version: 22
package-manager-cache: false
- name: Test path classifier
run: node scripts/select-pr-workflows_test.mjs
run: |
node scripts/select-pr-workflows_test.mjs
node scripts/verify-routed-sdk-gate_test.mjs
- id: select
name: Select SDK workflows
run: |
Expand All @@ -49,7 +52,7 @@ jobs:
echo "::error::PR verification router requires a synthetic merge commit with a base parent"
exit 1
fi
git diff --name-only HEAD^1 HEAD | \
git diff --no-renames --name-only HEAD^1 HEAD | \
node scripts/select-pr-workflows.mjs --github-output "$GITHUB_OUTPUT"

go:
Expand Down Expand Up @@ -122,37 +125,8 @@ jobs:
needs: [classify, core, go, go_consumer, python, ruby, lua, php, swift, kotlin, harness]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Require every selected workflow to pass
env:
NEEDS: ${{ toJSON(needs) }}
run: |
node <<'NODE'
const needs = JSON.parse(process.env.NEEDS);
if (needs.classify.result !== "success") {
throw new Error(`classifier did not pass: ${needs.classify.result}`);
}

const selected = needs.classify.outputs;
const required = {
typescript: ["core"],
rust: ["core"],
go: ["go", "go_consumer"],
python: ["python"],
ruby: ["ruby"],
lua: ["lua"],
php: ["php"],
swift: ["swift"],
kotlin: ["kotlin"],
harness: ["core", "harness"],
};

for (const [surface, jobs] of Object.entries(required)) {
if (selected[surface] !== "true") continue;
for (const job of jobs) {
if (needs[job].result !== "success") {
throw new Error(`${surface} selected ${job}, which finished ${needs[job].result}`);
}
}
}
console.log("all selected SDK workflows passed");
NODE
run: node scripts/verify-routed-sdk-gate.mjs
2 changes: 1 addition & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
- name: Checkout payment channels program
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
repository: Moonsong-Labs/solana-payment-channels
repository: solana-foundation/payment-channels
ref: 0c07d5751c8972abf6a219570a3f39a72f46f879
path: _payment-channels
fetch-depth: 1
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/release-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,14 @@ jobs:
uses: ./.github/workflows/kotlin.yml
secrets: inherit

semgrep:
name: Semgrep
uses: ./.github/workflows/semgrep.yml

gate:
name: All release gates green
runs-on: ubuntu-latest
needs: [ci, harness, go, go-consumer, python, ruby, lua, php, swift, kotlin]
needs: [ci, harness, go, go-consumer, python, ruby, lua, php, swift, kotlin, semgrep]
steps:
- name: Confirm
run: echo "core CI, harness, on-chain legs, and every SDK matrix passed"
20 changes: 5 additions & 15 deletions .github/workflows/semgrep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ name: Semgrep (radar L7)
# - self-test: every *.bad.* fixture MUST fire, every *.good.* MUST stay clean
# - scan: run the ruleset over the real source tree (typescript/, go/, python/)
#
# The scan step is advisory (does not fail the build) so a newly surfaced,
# to-be-triaged finding doesn't block unrelated PRs. The self-test step IS
# blocking: it guarantees the rules keep catching their known-bad and stay quiet
# on their known-good. Flip `continue-on-error` off once the tree is clean.
# Every source scan is blocking. A security-rule finding is either a real
# regression or a rule-quality defect that must be resolved before merge.

on:
push:
Expand All @@ -29,16 +27,8 @@ jobs:
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install semgrep
run: pip install semgrep==1.168.0

- name: Self-test rules against fixtures (blocking)
run: bash harness/semgrep/run.sh --test
run: docker run --rm -v "$PWD:/src" -w /src semgrep/semgrep@sha256:59fbed6127ea7c5dde3ba6a85142733bb20ea9aaa36120c953904f1539aaf66e bash harness/semgrep/run.sh --test

- name: Scan real source (advisory)
continue-on-error: true
run: bash harness/semgrep/run.sh typescript go python
- name: Scan real source (blocking)
run: docker run --rm -e SEMGREP_ERROR_ON_FINDINGS=1 -v "$PWD:/src" -w /src semgrep/semgrep@sha256:59fbed6127ea7c5dde3ba6a85142733bb20ea9aaa36120c953904f1539aaf66e bash harness/semgrep/run.sh typescript go python
24 changes: 24 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Contributing

## Pull request scope

Keep changes reviewable and independently green. Use one pull request per language when a coherent SDK feature or refactor is language-owned. Use one pull request per protocol flaw when the same invariant must change in multiple SDKs, for example `fix(upto): bind settlement amounts in Ruby and TypeScript`.

Stacked pull requests must name their base and merge order. Do not mix unrelated language cleanup, protocol security changes, generated artifacts, and CI infrastructure solely to reduce the number of pull requests.

## Verification

Run the focused SDK tests, lint, typecheck, format, coverage, and owned harness legs before requesting review. Changes to shared vectors, schemas, routing, or harness infrastructure must run the full matrix; unknown paths deliberately fall back to full verification.

Security guards need an adversarial reject case that executes the real verifier, plus a valid accept case proving the guard is not over-broad. A declared verifier mode without both outcomes is treated as untested.

## Large pull requests and Greptile

Greptile may skip diffs above its 100-file review ceiling. Prefer splitting those changes by language or protocol. When a large mechanical migration cannot be split safely:

1. Separate and document the mechanical and semantic portions of the diff.
2. Keep the exact head green and resolve human review findings first.
3. Post `@greptile-apps please review` once on the meaningful final head.
4. Record the reviewed head commit in the pull request description; request another review only after a semantic change.

This bypass is review friction, not a substitute for focused tests, the full integration matrix, or maintainer approval.
3 changes: 2 additions & 1 deletion harness/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"express": "^4.21.0",
"tsx": "^4.19.2",
"typescript": "^5.9.3",
"vitest": "^4.1.0"
"vitest": "^4.1.0",
"yaml": "^2.8.3"
}
}
3 changes: 3 additions & 0 deletions harness/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion harness/runners/go.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
"language": "go",
"command": ["go", "run", "./cmd/conformance"],
"cwd": "go",
"intents": ["charge", "x402-exact", "session"]
"intents": ["charge", "x402-exact", "session"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"session": ["canonical-bytes"],
"x402-exact": ["verify-x402-transaction"]
}
}
6 changes: 5 additions & 1 deletion harness/runners/kotlin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@
"language": "kotlin",
"command": ["sh", "-c", "exec build/install/mpp-kotlin-conformance/bin/mpp-kotlin-conformance"],
"cwd": "harness/kotlin-conformance",
"intents": ["session"]
"intents": ["charge", "session"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"session": ["canonical-bytes"]
}
}
7 changes: 6 additions & 1 deletion harness/runners/lua.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"language": "lua",
"command": ["luajit", "cmd/conformance/main.lua"],
"cwd": "lua"
"cwd": "lua",
"intents": ["charge", "x402-exact"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"x402-exact": ["verify-x402-transaction"]
}
}
7 changes: 6 additions & 1 deletion harness/runners/php.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"language": "php",
"command": ["php", "conformance/runner.php"],
"cwd": "php"
"cwd": "php",
"intents": ["charge", "x402-exact"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"x402-exact": ["verify-x402-transaction"]
}
}
7 changes: 6 additions & 1 deletion harness/runners/python.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
"language": "python",
"command": ["uv", "run", "python", "conformance_runner.py"],
"cwd": "python",
"intents": ["charge", "x402-exact", "session"]
"intents": ["charge", "x402-exact", "session"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"x402-exact": ["verify-x402-transaction"],
"session": ["canonical-bytes"]
}
}
7 changes: 6 additions & 1 deletion harness/runners/ruby.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"language": "ruby",
"command": ["bundle", "exec", "ruby", "exe/conformance"],
"cwd": "ruby"
"cwd": "ruby",
"intents": ["charge", "x402-exact"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"x402-exact": ["verify-x402-transaction"]
}
}
9 changes: 8 additions & 1 deletion harness/runners/rust.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,12 @@
"language": "rust",
"command": ["bash", "-lc", "if [ -x target/debug/examples/conformance_runner ]; then exec target/debug/examples/conformance_runner; fi; exec cargo run -q -p solana-pay-kit --example conformance_runner --features x402,client"],
"cwd": "rust",
"intents": ["x402-exact"]
"intents": ["charge", "x402-exact"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"x402-exact": ["build-transaction", "verify-transaction", "verify-x402-transaction"]
},
"strictModesByIntent": {
"x402-exact": ["verify-transaction", "verify-x402-transaction"]
}
}
7 changes: 6 additions & 1 deletion harness/runners/swift.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
"language": "swift",
"command": ["swift", "run", "-c", "release", "mpp-conformance"],
"cwd": "swift",
"intents": ["charge", "x402-exact", "session"]
"intents": ["charge", "x402-exact", "session"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"x402-exact": ["verify-x402-transaction"],
"session": ["canonical-bytes"]
}
}
7 changes: 6 additions & 1 deletion harness/runners/typescript.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"language": "typescript",
"command": ["pnpm", "exec", "node", "--import", "tsx", "src/conformance/ts-runner.ts"],
"cwd": "harness"
"cwd": "harness",
"intents": ["charge", "x402-exact"],
"modesByIntent": {
"charge": ["canonical-bytes"],
"x402-exact": ["verify-x402-transaction"]
}
}
Loading
Loading