chore: supply chain update - 1#119
Conversation
PR Review: mohan/supply-chain-update-1
SummaryNice cleanup here! 🧹 This PR strips away the post-v2-cutover infrastructure from predict-polymarket, simplifying the codebase significantly. You're also tightening up repo docs and config. Net result: cleaner, easier to maintain. Let's walk through the changes. The Big Changes: Predict-Polymarket SimplificationWhat's being removed?Worth noting: You're also removing two schema fields from - builder: Bytes # v2 builder-program attribution
- metadata: Bytes # 32-byte metadata from OrderFilledQuestion: Any API users querying these fields? If so, this is a breaking change we should communicate. Handler Changes
Thoughts: Good cleanup. The remaining
Looks good — These constants were only used in the removed collateral adapter logic. What Still Works ✅
Solid. Core functionality intact. Docs & Config UpdatesRoot
|
| Stat | Count |
|---|---|
| Files modified | 15 |
| Files added | 2 |
| Files deleted | 9 |
| Net | −8,295 lines (nice!) |
Questions Before Merge ❓
Breaking Changes:
- Schema removal — Any external queries depending on
Bet.builderorBet.metadata? If yes, we need:- Deprecation notice for API users
- Versioning strategy (schema version bump?)
- Timeline for removal
V2 Migration Status:
2. Is the v2 cutover truly complete? Confirm:
- All agent Safes migrated from direct
ConditionalTokens+ adapter calls - No ongoing fallback logic needed
- Historical data (pre-cutover bets) is preserved
Testing:
3. Test coverage — You removed ctf-exchange-v2.test.ts. Do remaining tests cover:
- v1 order creation & updates?
- Payout redemptions (both NegRisk & regular)?
- Edge cases (question ID reuse, missing agents)?
- ABI removal — Run a quick
grepon manifest files to confirm no subgraph still referencesCTFExchangeV2.jsonorCtfCollateralAdapter.json?
Deployment:
5. Deployed instances — Any Polymarket subgraph versions currently serving queries? If so:
- Confirm they've already migrated past the v2 cutover
- No stale references in The Graph Studio
Looks Good! ✨
The refactoring is clean and well-documented. Code simplification is solid — you've trimmed down the complexity while preserving core functionality. Docs are more accurate now too.
Approval: Ready to merge once you address the breaking change question above (if needed) and confirm v2 migration is truly complete.
ReviewSolid hardening PR — threat model and per-change justification are well above average. Each change is independently revertible. Recommend addressing (1) and (2) before merge; the rest are advisory. Issues / suggestions1. Node version mismatch between
2. Defense-in-depth: pass
env:
SUBGRAPH_NAME: ${{ inputs.name }}
SUBGRAPH_MANIFEST: ${{ inputs.manifest }}
STUDIO_KEY: ${{ secrets.SUBGRAPH_STUDIO_KEY }}
run: |
yarn graph auth "$STUDIO_KEY"
yarn graph deploy "$SUBGRAPH_NAME" "$SUBGRAPH_MANIFEST" -l "$SUBGRAPH_VERSION"Then a future input added without a regex doesn't regress the safety property. 3. CODEOWNERS routes everything to a single individual
4.
5.
6. CONTRIBUTING.md now sends CoC reports, security reports, and general questions all to The Risks
What's strong
|
… node alignment
Addresses three items from Tanya's PR review on deploy-subgraph.yaml:
1. Node version mismatch (test.yaml=20 vs deploy-subgraph.yaml=24) was a
pre-existing condition on main. Aligned deploy to "20" so CI exercises
the same Node version that production uses. PR3 normalizes both to
22.18.0 via .nvmrc.
2. Defense-in-depth: every run: block that previously interpolated
\${{ inputs.X }} or \${{ secrets.SUBGRAPH_STUDIO_KEY }} into the
rendered shell script source now binds the value via env: and
references it as "\$VAR". Covers plan summary, all four regex
validators, both folder/manifest existence checks, auth, codegen,
build, deploy, and post-deploy summary. The regex gates remain the
primary protection, but a future input added without a regex no
longer regresses the safety property.
3. Folder regex tightened: second segment must now start with [a-z0-9]
(rejects predict/-foo, predict/_foo). All 12 subgraph paths in the
CI matrix still match.
Local verification:
- python3 yaml.safe_load parses the workflow cleanly.
- 32/32 regex cases (legitimate inputs + shell-injection attempts)
behave as expected against version, folder, name, and manifest
patterns.
- All 12 paths in test.yaml's matrix accepted by the new folder regex.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks @Tanya-atatakai — really useful review. Pushed Fixed
Acknowledged but not changed in this PR
Bad-input regression test Ran a local regex simulator against the 4 patterns: 32/32 cases pass. Rejection cases include First post-merge deploy = the Node-20 dry run. The graph-cli engines field requires |
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
| uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 |
There was a problem hiding this comment.
is it safe to use like that? is it not latest stable version?
There was a problem hiding this comment.
Good catch — was latest at PR open but is now 4 months stale. Bumped both actions to current latest stable in 9ae6b02:
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2(released 2026-01-09)actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0(released 2026-04-20)
SHAs cross-verified via two GitHub API endpoints (refs/tags + commits).
For full disclosure on the v6 hesitation: my PR description said "Stayed on v5 (not v6) because setup-node v6 limited automatic caching to npm; deploy uses cache: yarn." I re-read actions/setup-node#1374 and that was wrong — v6 only changed the default for pnpm/yarn (auto-caching now off unless explicitly enabled). Our workflow sets cache: "yarn" explicitly under with:, so the explicit-caching path is unchanged in v6. Apologies for the mis-read.
| uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 | ||
| with: | ||
| node-version: "24" | ||
| node-version: "20" |
There was a problem hiding this comment.
why not 24? in infra afair we use 24 so better do that here as well
There was a problem hiding this comment.
Got it — bumped both workflows to node-version: "24" in 9ae6b02.
Verified locally on Node v24.4.1 across the three subgraph patterns CI covers:
| Subgraph | Pattern | Tests |
|---|---|---|
legacy-mech-fees |
single-network | 15/15 |
subgraphs/predict/predict-omen |
nested | 19/19 |
subgraphs/staking |
template + symlink | 18/18 |
| total | 52/52 |
Each ran yarn install --frozen-lockfile && yarn graph codegen && yarn graph build && yarn graph test — the exact sequence CI exercises. graph-cli, matchstick-as, and the AssemblyScript toolchain are all happy on Node 24.
…both workflows Addresses two new line-level review comments on PR #119 from @Tanya-atatakai: 1. test.yaml:61 / deploy-subgraph.yaml:46,141 — pinned to v5.0.1 SHA which was latest stable at PR open but is now 4 months stale. Bumped to v6.0.2 (released 2026-01-09). actions/setup-node@v5.0.0 was likewise stale (8 months); bumped to v6.4.0 (released 2026-04-20). My original PR rationale for staying on v5 ("setup-node v6 limited automatic caching to npm") was wrong on re-read of actions/setup-node#1374: v6 only changed the default for pnpm/yarn (auto OFF unless explicitly enabled). Our workflow already sets `cache: yarn` explicitly in `with:`, so the explicit caching path is unaffected by the v6 default change. SHAs cross-verified via two GitHub API endpoints (refs/tags + commits): - actions/checkout@de0fac2 # v6.0.2 - actions/setup-node@48b55a0 # v6.4.0 2. deploy-subgraph.yaml:146 — Node 20 was an interim alignment to match test.yaml after the previous review. Tanya clarified that infra runs on Node 24 and asked for both workflows to align on 24, not 20. Bumped both to "24". Local Node 24 smoke test (Node v24.4.1) across the three subgraph patterns covered by CI: - legacy-mech-fees (single-network): 15/15 tests passed - subgraphs/predict/predict-omen (nested): 19/19 tests passed - subgraphs/staking (template + symlink): 18/18 tests passed total: 52/52 tests passed Each ran the full sequence `yarn install --frozen-lockfile`, `yarn graph codegen`, `yarn graph build` (where applicable), and `yarn graph test` — the same steps CI exercises. graph-cli, matchstick-as, and the AssemblyScript toolchain are all happy on Node 24. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n workflow The merge-cascade commit `b810944` bumped `.nvmrc` from 22.18.0 to 24 to align with main's Node 24 preference (Tanya's PR #119 review). The root package.json's engines.node field was missed in that merge — left at "22.x" while .nvmrc said 24. `yarn install` enforces engines.node strictly. On CI: error autonolas-subgraph-studio@: The engine "node" is incompatible with this module. Expected version "22.x". Got "24.14.1" error Found incompatible module. This crashed `yarn install --frozen-lockfile` as the first step in both the `Dependency audit (root tree)` and `Install-hook audit` jobs in supply-chain.yml — surfaced as 2 CI failures on the b810944 push. Locally re-verified on Node 24.4.1: - yarn install --frozen-lockfile: clean - yarn audit:prod: OK (23 allowlisted, no unlisted) - yarn audit:install-hooks: OK (0 allowlisted) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Refactor code structure for improved readability and maintainability * chore: clean up empty code change sections in the changes log * chore(deps): bump graph-cli/graph-ts/matchstick-as, converge versions Converge all 13 package.json files onto a single exact-pinned toolchain target — latest stable on npm: @graphprotocol/graph-cli ^0.97.0 / ^0.98.1 -> 0.98.1 @graphprotocol/graph-ts ^0.38.0 / ^0.38.2 -> 0.38.2 matchstick-as 0.5.0 / ^0.6.0 -> 0.6.0 All carets stripped to exact pins for deterministic resolutions. Three subgraphs (staking, predict-omen, predict-polymarket) were already on the 0.98.1 line; the other 9 subgraphs + root are bumped up to converge. Verification (full local CI sequence on Node 22 + yarn 1.22): yarn install --frozen-lockfile : all 13 paths "Already up-to-date" yarn graph codegen + test : all 12 subgraphs pass liquidity 23 tests passed tokenomics-eth 3 tests passed governance 12 tests passed legacy-mech-fees 15 tests passed predict-omen 19 tests passed predict-polymarket 96 tests passed babydegen-optimism 10 tests passed liquidity-l2 15 tests passed staking 18 tests passed tokenomics-l2 8 tests passed service-registry 13 tests passed new-mech-fees 15 tests passed ---------------------------------------- TOTAL 247 Matchstick tests, all green yarn audit delta is modest (latest stable is only 0.98.1; bigger jumps not yet stable on npm). Net change across paths: -13 High advisories on heaviest paths, +3 on three paths (matchstick-as 0.6 transitive), unchanged on the rest. Real wins of this PR are version consistency and exact-pin determinism, not advisory clearance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(security): supply-chain CI gates + governance docs Phase 3: prevent regression — every future PR auto-checked. Closes T5 future-leak detection. Lands remaining hygiene without bundling with PR1 (CI hardening) or PR2 (dep bump). Workflows added: - .github/workflows/supply-chain.yml — audit + install-hooks + lockfile-lint matrix over 13 paths, with all-checks-passed aggregator. Advisory-only at first; promote to required-status in branch protection when team is ready. - .github/workflows/gitleaks.yml — secret scan on every push + PR. Gitleaks 8.30.1 with SHA-256 verified binary download (551f6fc83ea457...). Verified against townhall-kpis pin and upstream checksums.txt. Scripts added: - scripts/audit.mjs — wraps `yarn audit --json` with allowlist suppression. Critical: invoked as `yarn audit:prod` not `yarn audit` (yarn 1.x's built-in shadows same-named scripts). - scripts/audit-install-hooks.mjs — diffs node_modules install-hooks against .supply-chain/install-hooks.allowlist; drift in either direction (new hook OR removed hook) fails the job. Allowlists baselined: - .supply-chain/audit-allowlist.json — 23 high/critical advisories baselined as transitive of @graphprotocol/graph-cli (latest stable 0.98.1 doesn't refresh them). Each entry has reason + added + review (90-day cadence). - .supply-chain/install-hooks.allowlist — empty: graph-cli's transitives are pure JS, no install hooks at root level. Configuration: - .nvmrc → 22.18.0 (resolves prior Node 20/24 drift between test.yaml and deploy-subgraph.yaml workflows). - root package.json: engines.node "22.x", packageManager "yarn@1.22.22", and audit:* script aliases. - Both workflows updated to node-version-file: .nvmrc and Corepack activation with version assertion. Documentation: - SUPPLY-CHAIN-SECURITY.md — threat model (T1-T5), secrets inventory, Dependabot alerts setup (one-time UI toggle — no .github/dependabot.yml since user wants silent alerts only, no PR spam from version-update bot), audit/install-hooks/ lockfile-lint/gitleaks rationale, response playbook, repo-specific watches (graph-cli upstream, SUBGRAPH_STUDIO_KEY rotation). - CLAUDE.md — supply-chain section pointing at the docs + the audit:prod naming-collision warning + the org-wide blast radius note. - .github/CODEOWNERS — expanded to cover .supply-chain/, scripts/, SUPPLY-CHAIN-SECURITY.md, .nvmrc. Pre-merge verification (locally on Node 22 + yarn 1.22): yarn audit:prod : OK (23 allowlisted, no unlisted) yarn audit:install-hooks : OK (0 allowlisted) lockfile-lint x 13 paths : ✔ No issues detected Failure-mode simulations (all gates fail-closed correctly): - Empty allowlist → 23 unlisted advisories blocked ✓ - Stale install-hook entry → drift detected, exit 1 ✓ - codeload.github.com source → invalid host detected, exit 1 ✓ Branch protection settings change is OUT of scope for this PR; the new gates will run advisory until manually promoted to required-status (separate Settings UI change post-merge). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(security): add .gitleaks.toml to suppress false positives on public token addresses A history scan with gitleaks 8.18 / default ruleset reports 54 hits across 374 commits. All 54 are false positives — every redacted secret resolves to a public on-chain Optimism ERC20 contract address (USDC, USDT, DAI, WETH, etc.) hardcoded into babydegen mapping logic for decimals/symbol branching, plus one example token address in subgraphs/liquidity/README.md inside a Dune SQL snippet. This config extends the upstream default ruleset and adds a single allowlist scoped by BOTH path and regex shape (0x + exactly 40 hex chars), so secrets with any other shape — or in any other path — still flag. Verification (gitleaks 8.18.0, full history --log-opts="--all"): - Without config: 54 hits. - With config: 0 hits. - Positive test (synthetic AWS / Slack / sk_live_* fixtures in a temp dir outside the allowlisted paths): all 4 leaks still detected. The allowlist does not silence real secrets. The CI gitleaks workflow (.github/workflows/gitleaks.yml) already runs `gitleaks detect --source=.` and gitleaks auto-loads .gitleaks.toml from the source directory per the documented config precedence — no workflow edit required. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(ci): align engines.node with .nvmrc (24.x) to unblock supply-chain workflow The merge-cascade commit `b810944` bumped `.nvmrc` from 22.18.0 to 24 to align with main's Node 24 preference (Tanya's PR #119 review). The root package.json's engines.node field was missed in that merge — left at "22.x" while .nvmrc said 24. `yarn install` enforces engines.node strictly. On CI: error autonolas-subgraph-studio@: The engine "node" is incompatible with this module. Expected version "22.x". Got "24.14.1" error Found incompatible module. This crashed `yarn install --frozen-lockfile` as the first step in both the `Dependency audit (root tree)` and `Install-hook audit` jobs in supply-chain.yml — surfaced as 2 CI failures on the b810944 push. Locally re-verified on Node 24.4.1: - yarn install --frozen-lockfile: clean - yarn audit:prod: OK (23 allowlisted, no unlisted) - yarn audit:install-hooks: OK (0 allowlisted) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Refactor code structure for improved readability and maintainability * chore: clean up empty code change sections in the changes log * chore(deps): bump graph-cli/graph-ts/matchstick-as, converge versions Converge all 13 package.json files onto a single exact-pinned toolchain target — latest stable on npm: @graphprotocol/graph-cli ^0.97.0 / ^0.98.1 -> 0.98.1 @graphprotocol/graph-ts ^0.38.0 / ^0.38.2 -> 0.38.2 matchstick-as 0.5.0 / ^0.6.0 -> 0.6.0 All carets stripped to exact pins for deterministic resolutions. Three subgraphs (staking, predict-omen, predict-polymarket) were already on the 0.98.1 line; the other 9 subgraphs + root are bumped up to converge. Verification (full local CI sequence on Node 22 + yarn 1.22): yarn install --frozen-lockfile : all 13 paths "Already up-to-date" yarn graph codegen + test : all 12 subgraphs pass liquidity 23 tests passed tokenomics-eth 3 tests passed governance 12 tests passed legacy-mech-fees 15 tests passed predict-omen 19 tests passed predict-polymarket 96 tests passed babydegen-optimism 10 tests passed liquidity-l2 15 tests passed staking 18 tests passed tokenomics-l2 8 tests passed service-registry 13 tests passed new-mech-fees 15 tests passed ---------------------------------------- TOTAL 247 Matchstick tests, all green yarn audit delta is modest (latest stable is only 0.98.1; bigger jumps not yet stable on npm). Net change across paths: -13 High advisories on heaviest paths, +3 on three paths (matchstick-as 0.6 transitive), unchanged on the rest. Real wins of this PR are version consistency and exact-pin determinism, not advisory clearance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(security): supply-chain CI gates + governance docs Phase 3: prevent regression — every future PR auto-checked. Closes T5 future-leak detection. Lands remaining hygiene without bundling with PR1 (CI hardening) or PR2 (dep bump). Workflows added: - .github/workflows/supply-chain.yml — audit + install-hooks + lockfile-lint matrix over 13 paths, with all-checks-passed aggregator. Advisory-only at first; promote to required-status in branch protection when team is ready. - .github/workflows/gitleaks.yml — secret scan on every push + PR. Gitleaks 8.30.1 with SHA-256 verified binary download (551f6fc83ea457...). Verified against townhall-kpis pin and upstream checksums.txt. Scripts added: - scripts/audit.mjs — wraps `yarn audit --json` with allowlist suppression. Critical: invoked as `yarn audit:prod` not `yarn audit` (yarn 1.x's built-in shadows same-named scripts). - scripts/audit-install-hooks.mjs — diffs node_modules install-hooks against .supply-chain/install-hooks.allowlist; drift in either direction (new hook OR removed hook) fails the job. Allowlists baselined: - .supply-chain/audit-allowlist.json — 23 high/critical advisories baselined as transitive of @graphprotocol/graph-cli (latest stable 0.98.1 doesn't refresh them). Each entry has reason + added + review (90-day cadence). - .supply-chain/install-hooks.allowlist — empty: graph-cli's transitives are pure JS, no install hooks at root level. Configuration: - .nvmrc → 22.18.0 (resolves prior Node 20/24 drift between test.yaml and deploy-subgraph.yaml workflows). - root package.json: engines.node "22.x", packageManager "yarn@1.22.22", and audit:* script aliases. - Both workflows updated to node-version-file: .nvmrc and Corepack activation with version assertion. Documentation: - SUPPLY-CHAIN-SECURITY.md — threat model (T1-T5), secrets inventory, Dependabot alerts setup (one-time UI toggle — no .github/dependabot.yml since user wants silent alerts only, no PR spam from version-update bot), audit/install-hooks/ lockfile-lint/gitleaks rationale, response playbook, repo-specific watches (graph-cli upstream, SUBGRAPH_STUDIO_KEY rotation). - CLAUDE.md — supply-chain section pointing at the docs + the audit:prod naming-collision warning + the org-wide blast radius note. - .github/CODEOWNERS — expanded to cover .supply-chain/, scripts/, SUPPLY-CHAIN-SECURITY.md, .nvmrc. Pre-merge verification (locally on Node 22 + yarn 1.22): yarn audit:prod : OK (23 allowlisted, no unlisted) yarn audit:install-hooks : OK (0 allowlisted) lockfile-lint x 13 paths : ✔ No issues detected Failure-mode simulations (all gates fail-closed correctly): - Empty allowlist → 23 unlisted advisories blocked ✓ - Stale install-hook entry → drift detected, exit 1 ✓ - codeload.github.com source → invalid host detected, exit 1 ✓ Branch protection settings change is OUT of scope for this PR; the new gates will run advisory until manually promoted to required-status (separate Settings UI change post-merge). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(security): add .gitleaks.toml to suppress false positives on public token addresses A history scan with gitleaks 8.18 / default ruleset reports 54 hits across 374 commits. All 54 are false positives — every redacted secret resolves to a public on-chain Optimism ERC20 contract address (USDC, USDT, DAI, WETH, etc.) hardcoded into babydegen mapping logic for decimals/symbol branching, plus one example token address in subgraphs/liquidity/README.md inside a Dune SQL snippet. This config extends the upstream default ruleset and adds a single allowlist scoped by BOTH path and regex shape (0x + exactly 40 hex chars), so secrets with any other shape — or in any other path — still flag. Verification (gitleaks 8.18.0, full history --log-opts="--all"): - Without config: 54 hits. - With config: 0 hits. - Positive test (synthetic AWS / Slack / sk_live_* fixtures in a temp dir outside the allowlisted paths): all 4 leaks still detected. The allowlist does not silence real secrets. The CI gitleaks workflow (.github/workflows/gitleaks.yml) already runs `gitleaks detect --source=.` and gitleaks auto-loads .gitleaks.toml from the source directory per the documented config precedence — no workflow edit required. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(security): clear 3 audit advisories via yarn resolutions Apply selective version resolutions for transitive deps where the bump is semver-compatible AND only one major exists in the tree. Skips multi-major cases (picomatch 2.x+4.x, minimatch 3.x+5.x+9.x+ 10.x, glob 7.x+11.x), axios (needs graph-cli upstream), and lodash (advisory affects all of 4.x, no fix without major migration). Resolutions added (root package.json): immutable: 5.1.4 -> ^5.1.5 (advisory 1117068) cross-spawn: 7.0.3 + 7.0.6 -> ^7.0.6 (advisory 1104664) semver: 7.3.5 + 7.7.x -> ^7.5.2 (advisory 1112921) Effect on root yarn.lock: dedups cross-spawn (-2 entries), bumps immutable (1 patch) and semver 7.3.5 (-> 7.7.4 via existing range). Net -50 lines in yarn.lock. Allowlist trimmed from 23 -> 20 entries. Audit script's drift detector flagged the now-cleared advisories as warnings before trim, then exited clean after. Verification: - Root: yarn install --frozen-lockfile clean; yarn audit:prod OK (20 allowlisted, no unlisted high/critical). - All 13 paths: yarn install --frozen-lockfile "Already up-to-date" (subgraph lockfiles untouched — root resolutions don't propagate). - Smoke test: predict-omen (19/19 tests pass), babydegen-optimism (10/10 tests pass) — same counts as PR2's verification. Out of scope (left in allowlist with 90-day review): - 5x axios advisories (need graph-cli upstream migration to axios 1.x) - 3x minimatch (multi-major in tree — risky to force one) - 3x undici, 1x picomatch, 1x lodash, 1x glob - Total: 20 remaining entries, all reviewed 2026-08-05 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(security): propagate yarn resolutions to all 12 subgraph package.jsons Addresses concerns #1 and #3 from @atepem's review on PR #122. #1: Subgraph yarn.locks shipped vulnerable versions The supply-chain audit gate covers root only (".github/workflows/ supply-chain.yml: 'Dependency audit (root tree)'"). All 12 subgraph yarn.locks still contained the same 3 vulnerable versions that the root resolutions cleared: immutable@5.1.4 (advisory 1117068) cross-spawn@7.0.3 (advisory 1104664) semver@7.3.5 (advisory 1112921) Mirrored the root resolutions block into all 12 subgraph package.jsons with a short pointer back to root for the rationale, then ran 'yarn install' in each subgraph to refresh its yarn.lock. After-state across all 12 subgraphs: immutable 5.1.4 -> 5.1.5 cross-spawn 7.0.3 -> 7.0.6 semver 7.3.5 -> 7.7.4 (forced 7.5.2 floor pulls latest minor) #3: Allowlist entries now cite the multi-major constraint picomatch / minimatch / glob entries previously cited only the graph-cli ceiling. Appended the multi-major reasoning so a future reviewer trying to clear those entries via 'yarn resolutions' sees why the same fix that worked for immutable/cross-spawn/semver does not apply (forcing one major across consumers expecting another breaks installs). Drive-by fix: npm advisory database rotated 1113274 -> 1117857 for the same axios CVE (GHSA-43fc-jf86-j433). Root audit:prod was failing with "stale entry" on 1113274 + "unlisted" on 1117857. Replaced the id in place; reason / dates / GHSA preserved. Verification: - All 12 subgraphs: 'yarn install --frozen-lockfile' passes (12/12). - End-to-end smoke on 3 patterns: legacy-mech-fees (single-network) codegen + build + 15/15 tests predict-omen (nested) codegen + build + 19/19 tests predict-polymarket (nested, dep-heavy) codegen + build + 96/96 tests Total: 130/130 tests green on the new resolutions. - Root 'yarn audit:prod' clean (20 allowlisted, 0 unlisted, exit 0). - Root yarn.lock unchanged; only subgraph trees and the allowlist moved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(ci): align engines.node with .nvmrc (24.x) to unblock supply-chain workflow The merge-cascade commit `b810944` bumped `.nvmrc` from 22.18.0 to 24 to align with main's Node 24 preference (Tanya's PR #119 review). The root package.json's engines.node field was missed in that merge — left at "22.x" while .nvmrc said 24. `yarn install` enforces engines.node strictly. On CI: error autonolas-subgraph-studio@: The engine "node" is incompatible with this module. Expected version "22.x". Got "24.14.1" error Found incompatible module. This crashed `yarn install --frozen-lockfile` as the first step in both the `Dependency audit (root tree)` and `Install-hook audit` jobs in supply-chain.yml — surfaced as 2 CI failures on the b810944 push. Locally re-verified on Node 24.4.1: - yarn install --frozen-lockfile: clean - yarn audit:prod: OK (23 allowlisted, no unlisted) - yarn audit:install-hooks: OK (0 allowlisted) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Tier 1 of the supply-chain hardening rollout (see
.plans/supply-chain-update.md, kept local — see review feedback notes below). Closes the most urgent attack-surface gaps without touching subgraph code or dependency versions. Zero functional change to indexed data.Threats closed by this PR:
tj-actions/changed-files, March 2025) → all actions are now SHA-pinned.workflow_dispatchshell injection viafolder/name/manifest→ regex gates added (and now reinforced by env-var defense-in-depth — see review feedback below).contents: writeblast radius if any other compromise lands → both workflows locked tocontents: read.yarn install --frozen-lockfile || yarn install→ fallback removed; underlying drift fixed.Pre-PR recon: gitleaks history scan (T5)
Ran
gitleaks detect --no-banner --redact --log-opts="--all"over the full git history (374 commits, all branches/tags) as the pre-PR-recon step for T5 — historical secret leak in repo or CI logs.Result: 0 actual leaks. Repo history is clean.
The default ruleset returned 54 raw findings; every one was confirmed a false positive by
git show <sha>:<path>inspection — each redacted "secret" resolves to a public on-chain Optimism token contract address (USDC, USDT, DAI, WETH, FRAX, LUSD, DOLA, BOLD, sDAI, USDC.e) hardcoded into babydegen mappers for decimals/symbol branching, plus one Dune SQL example insubgraphs/liquidity/README.md. No credentials, tokens, or keys present in history.The CI gitleaks workflow lands in PR #121 with a path+regex-scoped
.gitleaks.tomlallowlist (40-hex shape, scoped to the babydegen mapper paths and the liquidity README) so future scans surface real findings cleanly. Verified the allowlist does not silence genuine secrets — synthetic AWS / Slack /sk_live_*fixtures in a temp dir still tripped the scanner.Review feedback addressed (commit
1675b82)Replying to @Tanya-atatakai's review:
deploy-subgraph.yamltonode-version: "20". The mismatch pre-existed onmain— both workflows now exercise the Node version CI validates. PR3 will normalize to 22.18.0 via.nvmrc.workflow_dispatchinputs viaenv:run:block that previously interpolated${{ inputs.X }}or${{ secrets.SUBGRAPH_STUDIO_KEY }}now binds the value viaenv:and references it as"$VAR". Covers plan summary, all four regex validators, both folder/manifest existence checks, and all four deploy steps (auth/codegen/build/deploy/summary). Future inputs added without a regex no longer regress the safety property.* @Tanya-atatakaifor now; backup handle to be added when a team handle exists. Doesn't enforce until branch protection's "Require review from Code Owners" is enabled, so vacation-blocking is theoretical until that flip.predict/-foo^[a-z0-9][a-z0-9_-]*(/[a-z0-9][a-z0-9_-]*)?$— second segment must also start with[a-z0-9]. All 12 current subgraph paths still match..plans/gitignoredinfo@valory.xyzcollapsing CoC + security + general triageLocal verification of the changes (commit
1675b82):python3 yaml.safe_loadparses the updated workflow cleanly.folder=../../etc,name=1; rm,manifest=../subgraph.yaml, etc.) behave as expected.test.yaml's matrix accepted by the tightened folder regex.Follow-up review feedback addressed (commit
9ae6b02)Replying to two new line-level comments from @Tanya-atatakai:
actions/checkout@de0fac2… # v6.0.2(released 2026-01-09) andactions/setup-node@48b55a0… # v6.4.0(released 2026-04-20). Old v5.0.1 / v5.0.0 pins were latest at PR open but had drifted 4 / 8 months. SHAs cross-checked via two GitHub API endpoints (refs/tags+commits).node-version: "24"(was"20"after the previous round). Local Node 24.4.1 smoke test across the three CI patterns:legacy-mech-fees(single-network) 15/15,predict-omen(nested) 19/19,staking(template + symlink) 18/18 = 52/52 tests green. Each ran the full sequenceyarn install --frozen-lockfile && yarn graph codegen && yarn graph build && yarn graph test. graph-cli, matchstick-as, and the AssemblyScript toolchain all happy on Node 24.Correction on a previous PR-description claim: I had said "Stayed on v5 (not v6) because setup-node v6 limited automatic caching to npm; deploy uses cache: yarn." On re-read of actions/setup-node#1374, that was wrong — v6 only changed the default for pnpm/yarn (auto-caching off unless explicitly enabled). Our workflow already sets
cache: "yarn"explicitly underwith:, so the explicit-caching path is unaffected.Changes
Workflow hardening
deploy-subgraph.yamlandtest.yaml. Pinned to current latest stable:actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0refs/tags+commits).permissions: { contents: read }on both workflows. Pre-checked: no current job needs write (nogit push, nogh release, etc.).workflow_dispatchinputs indeploy-subgraph.yaml— regex gates forfolder,name,manifestmatching The Graph slug + path patterns. Joins the existingversionvalidation. Mitigation against compromised-maintainer shell injection.run:block consumes inputs / secrets viaenv:rather than inline${{ }}interpolation (per Tanya's review).node-version: "24"(matches the infra side).|| yarn installfallback intest.yaml. The fallback was silently regenerating lockfiles every CI run, masking real drift (see lockfile fixes below).Lockfile hygiene
package-lock.jsonat root andsubgraphs/staking/. Yarn is canonical (CI uses yarn, README saysyarn install).yarn.lockand the deletedpackage-lock.jsonagreed.package-lock.jsonwas byte-identical to root's and resolvedgraph-cli@0.97.xwhile staking'spackage.jsondeclares^0.98.1— demonstrably stale, not canonical.yarn.lockfor subgraphs that lacked one:subgraphs/tokenomics-eth/andsubgraphs/babydegen/babydegen-optimism/had no lockfile committed; installs were non-deterministic per CI run. New yarn-classic v1 lockfiles, both passyarn install --frozen-lockfile.subgraphs/predict/predict-omen/yarn.lockwas in yarn-berry format (__metadata: version: 6,@npm:syntax) since the polymarket subgraph was initialized — rejected by yarn-classic 1.22 in CI. Regenerated as classic v1 (3108 lines). Also deleted.yarnrc.yml(only containednodeLinker: node-modules— Berry-only directive, dead under yarn classic).Documentation & governance
SECURITY.mddisclosure policy with in-scope / out-of-scope sections adapted for the data-pipeline nature of the repo. Vulnerabilities in The Graph's hosted service itself are explicitly out-of-scope (report there directly)..github/CODEOWNERSadvisory stub routing review of security-sensitive files. Currently set to@Tanya-atatakai; switch to a team handle when one exists. Doesn't enforce until "Require review from Code Owners" is set in branch protection..gitignore— addedpackage-lock.json,pnpm-lock.yaml,bun.lockb(block stray lockfiles from other package managers) and/audit(Tier 0 baseline output dir).CONTRIBUTING.md— corrected the disclosure email fromsecurity@valory.xyz(doesn't exist) toinfo@valory.xyz. Same fix applied toSECURITY.md.Operating notes
SUBGRAPH_STUDIO_KEYcmdline residual exposure (intentional, this PR)deploy-subgraph.yamlstill passes the key as a positional argument toyarn graph auth(now viaenv: STUDIO_KEY→"$STUDIO_KEY"after the review fix, but it still ends up on argv after shell expansion). graph-cli0.97.x/0.98.xaccepts the deploy key only positionally — no--access-tokenflag, no env var, no stdin support (verified withnpx graph auth --help).GitHub Actions auto-redacts secret literals in logs (
***), so the practical residual exposure is limited to/proc/<pid>/cmdlineon the runner during the brief auth step. Hosted runners isolate that surface.Mitigation: rotate
SUBGRAPH_STUDIO_KEYon a quarterly cadence. The CLI bump in the next supply-chain PR will enable env-var auth and eliminate this entirely.What's deferred to follow-up PRs
graph-cli 0.97 → latest) — clears the 37 standing High-severity advisories. High runtime risk; gated by mandatory staging-deploy validation.Verification (pre-merge)
Locally ran the full CI test sequence (
yarn install --frozen-lockfile && yarn graph codegen && yarn graph build && yarn graph test) on every subgraph affected by lockfile changes:32/32 Matchstick tests green. All builds compile to WASM cleanly.
Verified separately:
gh api repos/actions/checkout/commits/v6.0.2andgh api repos/actions/setup-node/commits/v6.4.0return the SHAs we pinned (cross-checked againstrefs/tags).setup-nodev6 caching behavior — re-read actions/setup-node#1374: v6 disabled the auto-default for pnpm/yarn but preserves explicitcache: "yarn"exactly as in v5. Our workflow uses the explicit form, so the behavior is unchanged across v5 → v6.subgraph.gnosis.yaml,subgraphs/liquidity,predict/predict-omen, etc.) all match the new regexes.../../etc,predict/-foo,predict/_foo,1; rm,../subgraph.yaml) are rejected.legacy-mech-fees15/15,predict-omen19/19,staking18/18 (52/52 total) running the fullyarn install --frozen-lockfile && graph codegen && graph build && graph testsequence.The remaining residual risk is environmental: local Node version (24.4.1) matches CI; yarn versions differ slightly (CI 1.22.22, local 1.22.19). Both are within graph-cli's supported range.
Rollback
Each change is independently revertible:
git revertthe workflow edits; old@v4tag-pinned versions still work.git revertthe lockfile commit; predict-omen's previous Berry lockfile + the missing tokenomics-eth/babydegen lockfiles are recoverable from history.Test plan
test.yaml's matrix pass on this branch.yarn install --frozen-lockfilesucceeds for every subgraph.yarn graph codegen && yarn graph build && yarn graph testgreen for the 3 lockfile-affected subgraphs.security@valory.xyzreferences remain (was non-existent address).folder=../../etc,predict/-foo,predict/_foo,name=1; rm,manifest=../subgraph.yaml, etc. (32/32 cases pass). Liveworkflow_dispatchwith bad inputs is still possible on a sandbox branch if a belt-and-suspenders test is wanted.SUBGRAPH_STUDIO_KEYonce to baseline the rotation cadence.