Commit Graph

6 Commits

Author SHA1 Message Date
Dan Guido ca08fc8a91 Commit plugin lockfiles; unblock Dependabot (#213)
* Commit plugin lockfiles so Dependabot can do something useful

The uv ecosystem config added in #206 pointed at four directories that declare
PEP 621 ranges and carry no lockfile. With nothing to pin, Dependabot's only
available action is raising the lower bound of an already-open range — which
changes nothing about what installs and only drops support for older versions.
It opened five such PRs within a minute of #206 merging (#208-#212), all no-ops:
the existing ranges already resolved to exactly the versions being proposed as
new floors. The one directory that did have a lockfile, constant-time-analysis,
produced no PR at all, because there was genuinely nothing to update. That is
the whole diagnosis.

Lockfiles committed for the other four. .gitignore ignored uv.lock globally,
which is why they were missing; constant-time-analysis's was tracked only
because it predates the rule. Now scoped to the root file (ephemeral — there is
no root pyproject.toml) with plugin lockfiles explicitly allowed, matching the
pattern already used for .mcp.json.

Also fixes two bugs #206 introduced:

- The version-increment check failed all five Dependabot PRs, and Dependabot can
  neither bump a plugin version nor label its own PR, so every future dependency
  PR would have been permanently red. Exempted by actor.
- The 'no-version-bump' label was documented in AGENTS.md and wired into
  validate.yml but never created, so the escape hatch did not exist. Created.

* Re-run CI with the no-version-bump label applied

The version-increment check fired on this PR: adding uv.lock under plugins/<name>/
counts as touching those plugins. Correct behaviour — the lockfiles pin exactly
what the existing ranges already resolve to, so nothing changes for anyone
installing these plugins, which is what the label is for. First real use of the
escape hatch created in this same PR.

* Fix the three findings from this PR's review

A local uv setting leaked into all four new lockfiles. /etc/uv/uv.toml on ToB
machine images sets exclude-newer = "1 week", so every lock carried an
[options] block with exclude-newer-span = "P1W" and pinned versions resolved a
week stale — diverging from constant-time-analysis/uv.lock, which predates this
PR and has no such block. Regenerated with UV_NO_CONFIG=1. That cooldown is the
org's supply-chain posture and it belongs in dependabot.yml's
'cooldown: default-days: 7', where it already is; baking it into committed
lockfiles was my environment leaking, not a decision.

"EVERY directory here must carry a committed uv.lock" was enforced by a comment,
which is precisely the anti-pattern AGENTS.md tells people to avoid. Now a
validator check: it parses the uv ecosystem block out of dependabot.yml and
asserts a uv.lock beside each listed directory. Scoped to that block rather than
grepping for '- /plugins/...' so a future ecosystem's paths are not swept in,
and it errors if the block exists but no directories parse out — otherwise the
checker could inspect zero items and report clean, which is the exact failure it
exists to prevent. Three self-test fixtures, and verified by deleting a real
lockfile and confirming CI would go red.

The Dependabot exemption keyed on github.actor, which on a synchronize event is
whoever pushed. A human adding one commit to a Dependabot branch would re-arm
the version check and turn the PR red — making the follow-up bump mandatory
exactly where the comment says it is discretionary. Keyed on PR authorship now.
2026-07-29 20:09:36 -04:00
Scott Arciszewski 841bffed0d trailmark: add v0.4/v0.5 support and graph-assisted security workflows (#183)
* trailmark: update skills to use v0.4.0 features

* fix: resolve code review findings for PR #183

Redraws the version boundary to match the actual Trailmark release
history, verified against the v0.2.0/v0.2.1/v0.2.2/v0.3.1/v0.4.0 tags
of trailofbits/trailmark:

P1 (misclassified APIs, fixed):
- ancestors_of(), reachable_from(), entrypoint_paths_to(),
  nodes_with_annotation(), clear_annotations() and the diff/entrypoints
  CLI exist since v0.2.0 — moved from the v0.4+ list to the v0.2-safe
  baseline; removed needless hasattr() gates and degraded fallbacks
- supported_languages()/detect_languages() (trailmark.parse) are 0.3+
  modules, not v0.2-safe — annotated as such
- CLI --version/version were added in 0.2.2, not 0.4 — documented as
  0.2.2+ and version-probe failure semantics clarified
- graph-evolution/SKILL.md reverted to main: native diff has existed
  since v0.2.0 with identical args, so the 0.2.x-fallback rewrite was
  built on a false premise (also resolves the quality-checklist
  contradiction flagged in review)

P3 (fixed): lexical version comparison hazard noted; stale
diagramming-code checklist label; README baseline list now defers to
the SKILL.md Version Gate instead of keeping a second divergent copy

Dismissed: 'diff CLI signatures contradict' (both forms valid — before/
after positionals accept paths or git refs, --repo/--json exist since
0.2.0); 'subgraph_edges has no edge_kinds param' (v0.4.0 signature has
edge_kinds keyword); 'diagram.py fallback broken on 0.2.x'
(trailmark.diagram module exists in 0.2.x; only the CLI subcommand is
new); 'phantom diff_against()' (real, v0.2-safe, now in baseline)

Verified: check_claude_loadability.py, check_codex_loadability.py,
pre-commit hooks pass; all SKILL.md files under 500 lines

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* trailmark: add assurance workflow skills (#187)

* trailmark: add assurance workflow skills

* fix: drop hasattr gates on v0.2-baseline query APIs

entrypoint_paths_to() and reachable_from() are in the v0.2-safe
baseline, so the hasattr fallbacks were dead code — and the
entrypoint_paths_to fallback indexed attack_surface() entries with
entry["name"] instead of node_id, which would raise KeyError.
Addresses PR #187 review feedback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

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

* fix(trailmark): make detect_languages import v0.2-safe in operational skills

The trailmark-summary and trailmark-structural skills claimed v0.2-safe
workflows but unconditionally imported trailmark.parse, a 0.3+ module.
detect_languages() has existed in trailmark.query.api since v0.2.0 (kept
as a deprecated alias in 0.3+), so gate the import with a fallback
instead of relabeling the skills as 0.3+. Version Gate docs updated to
document the v0.2-safe import path; supported_languages() remains 0.3+
with no 0.2.x equivalent.

Verified against trailmark v0.2.0 source (fallback branch) and the
current 0.4 line (canonical branch).

Addresses review feedback on PR #183.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* trailmark: document and enable v0.5.0 features

Trailmark 0.5.0 adds a PostgreSQL-oriented sql parser (node kinds
schema/table/view/procedure), the stable .trailmark/links.toml
configuration for cross-language/FFI/RPC/external links, repository
links/proxies/type_uses edges on single-language parses, Solidity
entrypoints from parser metadata (visibility/mutability/overridden-by
attributes), node attributes in attack_surface() entries, TypeScript
constructed-receiver resolution, and C# file-scoped namespaces.

Updates the Version Gate with a v0.5+ section and a structural probe
('SCHEMA' in NodeKind.__members__ — 0.5.0 adds no new QueryEngine
methods, so hasattr() cannot detect it), adds a Repository Links
section and cross-boundary query recipe, extends the parser list and
graph model docs, notes the reachability-vs-taint limitation, and
threads the 0.5 output additions through trailmark-structural and
audit-augmentation. Plugin version 0.9.0 -> 0.10.0.

All version claims verified against trailofbits/trailmark v0.2.0 and
v0.5.0 builds, including a live links.toml materialization test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* trailmark: add slicing-code-context skill (#203)

Adds a skill for delegating focused code tasks to constrained or locally
hosted models using bounded, graph-informed Trailmark source packets:

- scripts/build_slice_packet.py: deterministic PEP 723 packet builder
  (Trailmark 0.5.x) with five selection modes, whole-unit budget admission,
  explicit omission accounting, path-traversal rejection, an embedded
  untrusted-source notice, and structured JSON errors (26 tests, including
  a real Trailmark integration test)
- agents/code-slice-worker.md: repository-tool-free Haiku worker returning
  a source-cited JSON contract
- SKILL.md + references/slice-packet.md: coordinator workflow, packet and
  worker response contracts, and validation rules

Reviewed with a multi-agent Claude pass and two Codex passes; fixes from
those reviews are included (doc/selection-order reconciliation, relationship
deduplication, line-range anchors no longer expand to full nodes in
path/entrypoint modes, background-safe worker toolset, structured io_error
handling, replacement-packet expansion semantics).

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

---------

Co-authored-by: Dan Guido <dan@trailofbits.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 16:51:40 -04:00
Lixin2026 d5fe2e6a78 feat(codex): add UI metadata for skills (#175)
* feat(codex): add skill UI metadata

* Use official Trail of Bits logo

* fix: resolve code review findings for PR #175

Codex silently drops the icons as authored: its loader
(codex-rs/core-skills resolve_asset_path) requires icon paths
containing '..' to resolve under <plugin_root>/assets/, and the
repo-root .codex/assets location fails that containment check.
Verified empirically via codex app-server plugin/read: every
iconSmall/iconLarge came back null; only brand_color applied.

P1 fixed:
- Vendor trail-of-bits-mark.svg into plugins/<name>/assets/ for
  all 38 plugins with skills and point every openai.yaml at
  ../../assets/trail-of-bits-mark.svg (the supported plugin-level
  shared asset pattern). Icons now resolve for marketplace
  installs too, since nothing escapes the plugin root.
- Drop the .codex/ additions: .codex/skills/gh-cli/agents/
  openai.yaml resolved nowhere (.codex/skills is not a Codex
  discovery root) and PR #173 removes the whole .codex/ tree

P2 fixed:
- Patch-bump all 38 touched plugins in plugin.json and
  marketplace.json so installed clients pick up the metadata

Verified:
- Static check replicating Codex's resolution algorithm: all 73
  yaml files resolve under their plugin assets/ and exist
- Live codex app-server probe: 71/72 loadable skills report
  resolved iconSmall/iconLarge and brand_color #D83A34
  (claude-in-chrome-troubleshooting fails to load on main due to
  a pre-existing 64-char qualified-name limit, fixed by #173's
  rename; zeroize-audit's manifest mcpServers object is likewise
  a pre-existing Codex incompatibility fixed by #173)
- validate_codex_skills.py, validate_plugin_metadata.py, prek all
  pass

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(codex): use skill-local icon assets

---------

Co-authored-by: Dan Guido <dan@trailofbits.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 12:28:41 -04:00
Scott Arciszewski 48bd2626a1 Refresh trailmark skills for public Trailmark 0.2.x (#153)
* Refresh trailmark skills for public Trailmark 0.2.x

Aligns all skills with the now-public trailmark package
(pypi.org/project/trailmark, github.com/trailofbits/trailmark):

- Replace hardcoded language tables with runtime detection via
  trailmark.parse.detect_languages() and --language auto, so the
  skill never goes stale as Trailmark adds languages (21 supported
  as of 0.2.x: Python, JS/TS, PHP, Ruby, C/C++, C#, Java, Go, Rust,
  Solidity, Cairo, Circom, Haskell, Erlang, Miden Assembly, Swift,
  Objective-C, Kotlin, Dart)
- Remove phantom --passes CLI flag from trailmark-structural;
  pre-analysis is a QueryEngine.preanalysis() method, not a flag
- Use native trailmark diff --json in graph-evolution alongside the
  subgraph-diff helper script
- Add `finding` and `audit_note` annotation kinds to the documented
  list (set by augment_sarif / augment_weaudit)
- Document trailmark entrypoints and trailmark augment subcommands
  that exist in the public package
- Bump plugin to 0.8.1

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Address Trailmark skill review nits

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Dan Guido <dan@trailofbits.com>
2026-04-28 21:04:14 -04:00
Jonathan Hefner debfb29c8e Fix allowed-tools to use spec-compliant space-delimited strings (#139)
* Fix `allowed-tools` to use spec-compliant space-delimited strings

Per the agentskills.io specification, `allowed-tools` must be a single
string of space-delimited patterns, not a YAML list. Converted all 23
SKILL.md files from the `- Item` list format to the correct
`"Item1 Item2"` string format. Also updated the frontmatter examples in
CLAUDE.md and the workflow-skill-design skill template to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix remaining allowed-tools format in firebase-apk-scanner and workflow-skill-design docs

- Convert firebase-apk-scanner from comma-separated to space-delimited
- Update anti-patterns.md and tool-assignment-guide.md examples from YAML lists to space-delimited strings
- Remove unnecessary quotes from SKILL.md template placeholder

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Cover commands, new SKILL.md files, and fix template placeholder

Extends the previous spec-compliance fixes:

* Convert command frontmatter (commands/*.md) — per Claude Code
  docs, command files use the same frontmatter as skills, so the
  same space-delimited rule applies.
* Convert three SKILL.md files added since the original PR:
  mutation-testing, trailmark-structural, trailmark-summary.
* Fix the placeholder in the workflow-skill-design template.
  The previous "[minimum tools needed, space-delimited]" was YAML
  flow-sequence syntax, which parses as a list — the opposite of
  what the placeholder claims. Replaced with a concrete-looking
  space-delimited example plus a comment.

Zeroize-audit agent files still use `allowed-tools:` in YAML list
form. They are intentionally excluded: per the project's own docs
(workflow-skill-design references), agents declare tools with
`tools:` (not `allowed-tools:`). Fixing those requires changing
the field name as well as the format and is out of scope for this
PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* zeroize-audit agents: switch allowed-tools to tools

Subagents declare their tool allowlist via `tools:` (comma-separated),
not `allowed-tools:` — see Claude Code's subagent docs and this
repo's own designing-workflow-skills/SKILL.md:47:

> Skills use `allowed-tools:` in frontmatter. Agents use `tools:`
> in frontmatter.

Before this change, the zeroize-audit agents declared their tool list
under `allowed-tools:`, which Claude Code does not read for subagents.
The field was effectively a no-op; the spawned agents had no tool
restriction enforced.

Renames the field on all 11 agents to `tools:` and reformats the YAML
list as comma-separated to match the documented format and existing
agents elsewhere in the repo (e.g. function-analyzer.md,
spec-compliance-checker.md). Tool sets are unchanged.

Behavior change: tools now actually constrain what each spawned agent
can call. The lists are the ones the original author intended.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* skill-improver: convert command allowed-tools to space-delimited

The two command files in plugins/skill-improver/commands/ still used
the JSON flow-array format (`allowed-tools: ["..."]`), which the rest
of this PR converted everywhere else. Convert them to the spec-compliant
space-delimited string form for consistency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Dan Guido <dan@trailofbits.com>
2026-04-28 19:50:30 -04:00
Scott Arciszewski 6b79b5e879 feat(trailmark): skills that reason about code as graphs (#133)
* feat(trailmark): skills that reason about code as graphs

* Add Codex skill symlinks for trailmark plugin

The trailmark plugin's 10 skills were missing .codex/skills/ mappings,
which caused the validate_codex_skills CI check to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address PR #133 review feedback

- Add Rationalizations (Do Not Skip) sections to 5 security skills:
  trailmark, audit-augmentation, crypto-protocol-diagram,
  mermaid-to-proverif, graph-evolution
- Fix requires-python: diagram.py >= 3.12 (was 3.13), protocol.py
  >= 3.12 (was 3.11) to match trailmark's actual requirement
- Rename diagram/ to diagramming-code/ to match SKILL.md frontmatter
  name and all cross-skill references; update Codex symlink

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix diagram skill to use uv run instead of plain python

The diagram.py script carries PEP 723 inline metadata declaring
trailmark as a dependency. Plain python ignores this metadata,
causing ImportError for users who haven't pre-installed trailmark.
uv run processes the metadata and handles dependency resolution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address second round of PR #133 review feedback

- Fix README directory tree: diagram/ -> diagramming-code/
- Fix diagram-types.md: python -> uv run for all script invocations
- Fix graph-evolution Phase 3: replace undefined shell variables
  ($BEFORE_JSON etc) with template substitutions ({before_json} etc)
- Fix vector-forge mutation-frameworks.md: replace cross-skill file
  link with prose reference to genotoxic skill (avoids reference chain)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Local skill-improver review pass across all 10 trailmark skills

diagramming-code:
- Fix arrow syntax inconsistency: uncertain edges use ..-> not -.->
- Fix extra closing paren in diagram-types.md
- Fix diagram.py docstring to match uv run invocation

crypto-protocol-diagram:
- Remove reference chain: spec-parsing-patterns.md no longer links to
  mermaid-sequence-syntax.md, inlines the arrow syntax instead
- Fix ProVerif example note: "Tamarin/ProVerif" -> "ProVerif"

trailmark:
- Replace "path/to/project" with {targetDir} in query-patterns.md
- Add uv run prefix to CLI examples in query-patterns.md
- Add circom to supported language list
- Add pre-analysis annotation kinds to annotation docs

genotoxic:
- Remove reference chains: triage-methodology.md and
  mutation-frameworks.md no longer link to graph-analysis.md

vector-forge:
- Add trailmark to Prerequisites section
- Fix bare trailmark commands to use uv run with {targetDir}

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address third round of PR #133 review feedback

mermaid-to-proverif:
- Fix ProVerif type error: verify(...) = true is a type mismatch
  since verify returns bitstring. Use let _ = verify(...) in instead,
  which aborts on destructor failure (correct ProVerif pattern)

trailmark-summary, trailmark-structural:
- Add 8 missing language extensions to find command (.rb, .php, .cs,
  .java, .hs, .erl, .cairo, .circom)
- Remove unsupported .lean extension
- Split .c -> --language c and .cpp -> --language cpp (separate parsers)

All 7 security skills:
- Rename "Rationalizations (Do Not Skip)" to "Rationalizations to
  Reject" per CLAUDE.md convention

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address fourth round of PR #133 review feedback

mermaid-to-proverif:
- Fix ProVerif type errors in process template: pkey values cannot
  appear in bitstring positions. Add pkey2bs() and concat() to the
  function declarations and rewrite the template to use them,
  matching the sample-output.pv example

trailmark-summary:
- Split .js/.ts mapping: .js -> --language javascript,
  .ts -> --language typescript (separate parsers)

graph-evolution:
- Replace bare python with python3 in graph_diff.py invocations
  (python does not exist on modern Ubuntu/Debian/macOS)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address fifth round of PR #133 review feedback

graph-evolution:
- Change python3 to uv run for graph_diff.py invocations to match
  ecosystem convention

trailmark-structural, trailmark-summary:
- Add Rationalizations to Reject sections (both are security skills
  running blast radius, taint, and privilege boundary analysis)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix ProVerif type consistency and graph-evolution template vars

mermaid-to-proverif:
- Rename senc/sdec to aead_enc/aead_dec in Step 3 preamble to match
  the process template and sample-output.pv
- Fix hkdf signature: hkdf(key, bitstring): key (first arg is DH
  shared secret which has type key, not bitstring)

crypto-to-proverif-mapping.md:
- Fix hkdf declaration and summary table to match corrected signature
- Fix example to use concat/pkey2bs for type-correct HKDF input

graph-evolution:
- Replace $BEFORE_DIR/$AFTER_DIR shell vars in Phase 5 with
  {before_dir}/{after_dir} template substitutions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Comprehensive vivisect-style review of all trailmark skills

ProVerif correctness (mermaid-to-proverif):
- Fix broken ForwardSecrecyTest pattern in security-properties.md:
  process waited on c_fs but nothing sent on it, past_session_key
  was never bound to any session. Replaced with working pattern
  that leaks long-term keys and checks session key secrecy.
- Fix hkdf(bitstring,bitstring) -> hkdf(key,bitstring) in
  proverif-syntax.md to match SKILL.md and sample-output.pv
- Fix type-incorrect example in proverif-syntax.md: tuple of
  (key,pkey,pkey) passed where bitstring expected. Now uses
  concat2/pkey2bs for type-correct serialization.
- Align senc/sdec -> aead_enc/aead_dec in proverif-syntax.md and
  crypto-to-proverif-mapping.md to match SKILL.md and example
- Fix auth query parameter count in security-properties.md:
  beginI fires before session key is known, so has fewer params

Cross-skill consistency:
- Fix 3 stale "diagram skill" references -> "diagramming-code"
  in trailmark/SKILL.md and preanalysis-passes.md
- Add PEP 723 header to graph_diff.py for convention consistency

README and helper skills:
- Add trailmark-summary and trailmark-structural to README skills
  table and directory tree
- Add secondary file extensions (.jsx, .tsx, .h, .hpp, .cc, .cxx)
  to language detection in summary and structural skills
- Inline language mapping in trailmark-structural (was deferred
  to trailmark-summary, violating one-level-deep rule)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix ProVerif type consistency and graph-evolution template vars

- Fix endInitiator -> endI in mermaid-to-proverif Step 6 template
  (endInitiator was never declared as an event)
- Add missing msg2_label constant to Step 3 constants block
- Add .hh/.hxx C++ header extensions to language detection in
  trailmark-summary and trailmark-structural

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix mermaid-to-proverif template: missing beginI event and secrecy witness

Step 6 Initiator template:
- Add missing event beginI(pk(sk_I), pk_R) before first out —
  without it, authentication queries always report false attacks
- Replace local new secret_I with free private_I [private] to
  match sample-output.pv's secrecy witness pattern

security-properties.md:
- Fix beginI/beginR from 3 args to 2 args in mutual auth section
  and query checklist (begin events fire before session key is
  known, so they only take the two public keys)
- Update "Placing Events" table to match 2-param form

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address sixth round of PR #133 review feedback

proverif-syntax.md Two-Party Process example:
- Fix type errors: pkey values passed directly to bitstring params
  in sign() and verify(). Now uses concat2(pkey2bs(...)) pattern.
- Add missing pkey2bs declaration to function list
- Add missing info_session constant declaration
- Fix msg2_label -> msg2 in verification check example to match
  the file's own constant declarations

trailmark-structural:
- Fix contradiction: Rationalizations table said "Install trailmark
  first" but Execution section forbids install commands. Changed
  to "Report not installed and return" to match execution policy.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:31:30 -04:00