Skip to content

fix(openclaw): parse nested SKILL.md frontmatter + hoist metadata.openclaw.web3#19

Merged
Markeljan merged 1 commit into
mainfrom
claude/bold-leavitt-ae282a
May 14, 2026
Merged

fix(openclaw): parse nested SKILL.md frontmatter + hoist metadata.openclaw.web3#19
Markeljan merged 1 commit into
mainfrom
claude/bold-leavitt-ae282a

Conversation

@Markeljan
Copy link
Copy Markdown
Collaborator

Summary

The hand-rolled YAML parser in packages/openclaw/src/manifest.ts only handled one level of nesting, so any SKILL.md whose frontmatter declared metadata.openclaw.web3.policy.allowedContracts (the shape recommended in docs/odos-skill-recommendations.md and adopted upstream by odos-xyz/odos-skills) was silently flattened — the parsed manifest ended up with a malformed metadata block and no web3 field. Consequences:

  • W04M-003 (no metadata.openclaw) and W04M-004 (no allowedContracts) fired as false positives, even when both fields were correctly declared.
  • Every downstream rule that reads manifest.web3.* (AST-W01, AST-W06, AST-W10, AST-W12, etc.) was silently skipped because manifest.web3 was undefined — masking real findings.

What changed

  • Replace custom parseYaml with the standard yaml package. Correct handling of arbitrary nesting, block scalars, anchors, and quoted keys — replacing the ~60 LoC single-level scanner that was the root cause.
  • Hoist metadata.openclaw.web3 → top-level manifest.web3 during normalization, only when no top-level web3 is declared (top-level wins on conflict). Lets skills follow either canonical layout; every rule keeps reading the same single path.
  • Normalize policy.allowedContracts / allowedSelectors from chain-keyed maps ({ 1: ["0x..."], 8453: ["0x..."] }) into deduped flat string[]. Fixes a scanner regression in web3-permit-capture that surfaced once the hoist was wired up (it crashed with allowlistArray.map is not a function on the chain-keyed shape).
  • Adds 5 new parser/normalizer tests: deeply-nested SKILL.md frontmatter, hoisting from metadata.openclaw.web3, top-level wins, metadata preservation for AST04, chain-keyed-map flattening.

Verification

Re-audited odos-xyz/odos-skills@93b3db6 with --profile web3:

Finding Before fix After fix
W04M-001 (missing license) already cleared already cleared
W04M-002 (no permissions) fires fires (legitimate — Odos has no permissions array)
W04M-003 (no metadata.openclaw block) fires (false positive) cleared ✓
W04M-004 (no allowedContracts) fires (false positive) cleared ✓
W12-001 (no audit sink) not detected (parser masked it) fires (legitimate)
W12-002 (no kill-switch contract) not detected (parser masked it) fires (legitimate)
W12-003 (no incident runbook) not detected (parser masked it) fires (legitimate)
SCANNER-ERR web3-permit-capture crash (regression after hoist) clean

Score moved from a falsely-flattering 65 (C) to an accurate 47 (D) for the latest Odos commit. The two false-positives Odos was being penalized for now clear; the previously-masked AST-W12 findings (rec #8 in the Odos recommendations doc — not yet shipped upstream) now correctly fire. Re-running the audit against the pre-recommendation commit f88b7c89 is byte-identical to the v0.3.0 baseline (53, same 5 findings), confirming no regression on manifests that don't use the nested shape.

Test plan

  • bun run build — 9/9 packages
  • bun run test — 17/17 tasks, 95 openclaw tests pass (5 new), 0 failures
  • bun run check — typecheck clean
  • bun run lint — only pre-existing complexity warnings (unrelated, on other files)
  • Re-audit odos-xyz/odos-skills@93b3db6 end-to-end
  • Re-audit f88b7c89 (pre-recommendation baseline) — no regression
  • Reviewer to spot-check audit output on a non-web3 skill (e.g. e2e/fixtures/good-skill)

🤖 Generated with Claude Code

…nclaw.web3

The hand-rolled YAML parser in `packages/openclaw/src/manifest.ts` only
handled a single level of nesting, so any SKILL.md whose frontmatter
declared `metadata.openclaw.web3.policy.allowedContracts` (the shape the
Web3 Annex recommendations doc tells skills to use, and the shape adopted
upstream in odos-xyz/odos-skills) was silently flattened — leaving the
parsed manifest with a malformed `metadata` block and no `web3` field at
all. The W04M-003 / W04M-004 rules then fired as false positives, and
the downstream AST-W rules that read `manifest.web3.*` were skipped
entirely (silently masking real findings, e.g. AST-W12 audit sink /
kill-switch / runbook gaps).

This change:

- Replaces the custom `parseYaml` with the standard `yaml` package so
  deeply-nested frontmatter parses correctly (no more single-level
  limitation, plus correct handling of block scalars and quoted keys).
- Hoists `metadata.openclaw.web3` to top-level `manifest.web3` during
  normalization when no top-level `web3` block is declared. Both shapes
  are now supported; top-level wins when both are present.
- Normalizes `policy.allowedContracts` (and `allowedSelectors`) from
  chain-keyed maps (`{ 1: ["0x..."], 8453: ["0x..."] }`) into deduped
  flat string arrays, so every downstream rule can read them as
  `string[]` without crashing on `.map`/`.includes`. This fixes a
  scanner regression in `web3-permit-capture` that surfaced once the
  hoist was in place.
- Adds parser and normalizer tests covering: deeply-nested frontmatter
  parsing, hoisting from `metadata.openclaw.web3`, top-level wins over
  nested, metadata preservation for AST04, and the chain-keyed-map
  flatten case.

Verified against odos-xyz/odos-skills@93b3db6: W04M-003 and W04M-004
findings clear (Odos correctly credited for the fixes shipped in their
PRs #2-#4), and the previously-masked AST-W12 findings now correctly
fire so they can be addressed upstream.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Markeljan Markeljan merged commit edc1bfb into main May 14, 2026
1 check passed
@Markeljan Markeljan deleted the claude/bold-leavitt-ae282a branch May 21, 2026 14:43
Markeljan added a commit that referenced this pull request May 21, 2026
Honest grades: fixes the MetricsAnalyzer wiring bug that made every
audit fall through to hardcoded defaults, calibrates four web3 severities
(W12-001/002/003, W04M-002) to LOW so governance-hygiene gaps stop
masquerading as exploitable findings, and makes maintenance + documentation
scoring skill-type-aware so markdown-only skill packs aren't penalized for
missing source-code signals.

Also rolls up the openclaw frontmatter parser fix (nested SKILL.md parsing
+ metadata.openclaw.web3 hoisting) shipped in #19.

Co-Authored-By: Claude Opus 4.7 (1M context) <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.

1 participant