fork
Fork the scanned repository into the configured GitHub organisation, enable private vulnerability reporting on the fork, record the scan as a git note, and…
Skill by lukehinds
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/lukehinds-fork
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: security, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/fork
What's inside
- Skill name
fork- Description
- Fork the scanned repository into the configured GitHub organisation, enable private vulnerability reporting on the fork, record the scan as a git note, and file each finding as a draft security advisory on the fork with a relevant org team invited as collaborator. Run after a scan has produced findings; the fork is the staging area for disclosure work.
- License
- MIT
- Compatibility
- Needs the gh CLI authenticated with a token that can create forks in the fork_org and manage repository settings and security advisories there. Needs network access to api.github.com and the scrutineer API. github.com upstreams only for now.
- Metadata
- scrutineer.version: 1 · scrutineer.output_file: report.json · scrutineer.output_kind: freeform
- Instructions
- 239 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
Files (4)
- SKILL.md
- SKILL.md.bundle
- schema.json
- schema.json.bundle
SKILL.md (first lines)
# fork
Stage a scanned repository into the disclosure org. Forks the upstream into `fork_org`, turns on private vulnerability reporting on the fork, leaves a git note recording when scrutineer last scanned the upstream, and opens one draft advisory per finding on the fork so analysts and the relevant team can collaborate on the write-up before anything goes upstream.
## Workspace
- `./src` — the upstream clone at the commit that was scanned
- `./context.json` — has `repository.url`, `repository.full_name`, `scrutineer.api_base`, `scrutineer.token`, `scrutineer.repository_id`, `scrutineer.scan_id`, and `scrutineer.fork_org`
- `./report.json` — write what you did
Use the `gh` CLI for every GitHub call. Do not use curl against api.github.com.
## Preconditions
Read `./context.json`. Refuse to continue (write `{"error": "..."}` to `report.json` and exit 0) if:
- `scrutineer.fork_org` is missing or empty — the operator has not configured `fork_org` in scrutineer.yaml
- `repository.url` does not have host `github.com` — only GitHub upstreams are supported for now; non-GitHub hosts will get a create-in-org path later
- `gh auth status` fails — the runner has no GitHub credentials
Derive `{owner}/{repo}` from `repository.full_name` (fall back to parsing the path of `repository.url`, stripping a trailing `.git`).
## 1. Fork into the org
First check whether scrutineer already knows the fork: `GET {api_base}/repositories/{repository_id}` returns a `fork` field. If it is non-empty and `gh repo view {fork}` succeeds with `.parent` pointing at `{owner}/{repo}`, use it as `{fork_org}/{fork_name}`, record `"forked": "exists"`, and skip to step 2.
Otherwise the fork normally lives at `{fork_org}/{repo}`, but that slot may already be taken by an unrelated repository (e.g. forking `foo/redis` when `fork-central/redis` is already a fork of `bar/redis`). Resolve the fork name as follows.
For each candidate name, in order `{repo}` then `{owner}-{repo}`:
```
gh repo view {fork_org}/{candidate} --json name,parent
```
- not found — the slot is free; remember this candidate as `{fork_name}` and stop
- found and `.parent.owner.login == {owner}` and `.parent.name == {repo}` — this is already our fork; set `{fork_name}` to this candidate, record `"forked": "exists"`, and skip to step 2
- found but the parent is something else (or null) — the name is taken by an unrelated repo; move to the next candidate
If both candidates are taken by unrelated repositories, write `{"error": "no free fork name for {owner}/{repo} in {fork_org}"}` and exit 0.
If you found a free slot, create the fork there:
```
gh repo fork {owner}/{repo} --org {fork_org} --fork-name {fork_name} --clone=false --default-branch-only
```
`gh repo fork` is asynchronous on GitHub's side. Poll `gh repo view {fork_org}/{fork_name}` until it returns 0 (a few seconds is normal; give up after a minute and report `{"error": "fork did not become available"}`). Record `"forked": "created"`.
Whichever path you took, persist the resolved name back to scrutineer so the next run and the UI can find it without re-probing:
```
PATCH {api_base}/repositories/{repository_id}
Authorization: Bearer {token}
{"fork": "{fork_org}/{fork_name}"}
```
## 2. Enable private vulnerability reporting on the fork
Use the dedicated endpoint; the `security_and_analysis` block on `PATCH /repos/...` accepts the field but does not actually flip it.
```
gh api -X PUT repos/{fork_org}/{fork_name}/private-vulnerability-reporting
```
A 204 means it is on. Confirm with `gh api repos/{fork_org}/{fork_name}/private-vulnerability-reporting` which returns `{"enabled": true|false}`. A 422 usually means the org has it forced on or off at the org level; record that in `notes` and carry on.
## 3. Record the scan on the fork
Record when scrutineer last looked at this repository, regardless of whether there were findings, as a git note on the scanned commit and push it to the fork. The note lives under `refs/notes/scrutineer` so it does not collide with anything upstream uses.
```
HEAD=$(git -C ./src rev-parse HEAD)
NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
git -C ./src notes --ref=scrutineer add -f -m "scrutineer: scanned $NOW at $HEAD (scan {scan_id})" "$HEAD"
git -C ./src push -f "https://github.com/{fork_org}/{fork_name}.git" refs/notes/scrutineer
```
If the workspace clone is shallow `git push` may need `git -C ./src fetch --unshallow` first; only do that if the push is rejected for shallow reasons. If the push fails for any other reason (branch protection on notes refs, auth), record the error in `notes` and carry on — the note is a convenience, not a hard requirement.
## 4. File draft advisories for findings
Fetch the repository's findings: `GET {api_base}/repositories/{repository_id}/findings` with `Authorization: Bearer {token}`. File an advisory for every finding whose `status` is one of `new`, `enriched`, `triaged`, or `ready` — that is, anything that has not already been reported upstream or closed out. Skip `reported`, `acknowledged`, `fixed`, `published`, `rejected`, and `duplicate`; record those under `"skipped_advisories"` with the status as the reason. If nothing is left, record `"advisories": []` and skip to step 5.
For each remaining finding fetch the full record (`GET {api_base}/findings/{id}`) so you have `disclosure_draft`, `cvss_vector`, `cwe`, `affected`, and `title`.
Before filing, list the advisories already on the fork so re-runs do not duplicate:
```
gh api repos/{fork_org}/{fork_name}/security-advisories --paginate --jq '.[].description'
```
Every advisory this skill files carries a `[scrutineer-finding:{finding_id}]` marker on its last line (see below). Skip a finding whose marker already appears in any existing description; record it under `"skipped_advisories"` with reason `"already filed"`. Do not dedup on summary/title — distinct findings can share a title.
For each remaining finding, build the request body and create a draft repository security advisory on the fork. Use the admin create endpoint, not `/reports` — `/reports` is for external reporters and is rejected when the caller is a repo admin, which we are.
```
gh api -X POST repos/{fork_org}/{fork_name}/security-advisories --input ./advisory-{finding_id}.json
```
The body shape is the GHSA create schema:
```json
{
"summary": "<finding.title>",
"description": "<finding.disclosure_draft>",
"severity": "<critical|high|medium|low, lowercased from finding.severity>",
"cvss_vector_string": "<finding.cvss_vector, omit severity if this is set>",
"cwe_ids": ["CWE-79"],
"vulnerabilities": [
{"package": {"ecosystem": "<ghsa enum>", "name": "<pkg>"}, "vulnerable_version_range": "<finding.affected>"}
]
}
```
Build `vulnerabilities` from `GET {api_base}/repositories/{repository_id}/packages` using the same ecosystem mapping the disclose skill uses (rubygems, npm, pip, maven, nuget, composer, go, rust, erlang, actions, pub, other). If the repository has no packages, send `"vulnerabilities": [{"package": {"ecosystem": "other", "name": "{owner}/{repo}"}}]` — the endpoint requires at least one entry.
`vulnerable_version_range` must be a bare constraint string. `finding.affected` is analyst prose; normalise it before sending:
- drop anything in parentheses and any repeated package nameFrom lukehinds/scrutineer-attest-test, MIT.
More from lukehinds/scrutineer-attest-test
- 0.479score
sbom
lukehinds
Generate a CycloneDX Software Bill of Materials for the repository.
SkillCFreshness: CClaude Code +9 - 0.476score
zizmor
lukehinds
Audit the repository's GitHub Actions workflows for common security issues (credential mishandling, untrusted inputs, template injection, overly permissive…
SkillCFreshness: CClaude Code +9 - 0.476score
semgrep
lukehinds
Run semgrep static analysis with the security-audit and secrets rulesets, then map each hit into scrutineer's findings shape so it surfaces alongside…
SkillCFreshness: CClaude Code +9 - 0.476score
dependencies
lukehinds
Index every dependency declared in the repository's manifest and lockfile files (package.json, Gemfile, go.mod, requirements.txt, etc.) and record each one…
SkillCFreshness: CClaude Code +9 - 0.474score
maintainers
lukehinds
Identify the real maintainers of a repository and the best way to contact them about a security issue.
SkillCFreshness: CClaude Code +9 - 0.474score
cna-match
lukehinds
Determine which CVE Numbering Authority (if any) covers this repository, so disclosures can be routed to the CNA's security contact rather than only the…
SkillCFreshness: CClaude Code +9 - 0.474score
reachability
lukehinds
Check whether known sinks in this application's dependencies are reachable from its own trust boundaries.
SkillCFreshness: CClaude Code +9 - 0.474score
posture
lukehinds
Assess a repository's security posture and its readiness to receive a vulnerability report.
SkillCFreshness: CClaude Code +9 - 0.474score
repo-overview
lukehinds
Produce a structured plain-language overview of what a repository does, who maintains it, its activity level, and the shape of its codebase.
SkillCFreshness: CClaude Code +9 - 0.474score
security-deep-dive
lukehinds
Audit first-party source for security vulnerabilities using an inventory-first, six-step per-sink methodology.
SkillCFreshness: CClaude Code +9 - 0.474score
disclose
lukehinds
Draft the disclosure content for a finding in GitHub Security Advisory shape.
SkillCFreshness: CClaude Code +9 - 0.471score
patch
lukehinds
Propose a code patch for a finding.
SkillCFreshness: CClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Jun 11, 2026 (4 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from lukehinds
- 0.479score
sbom
lukehinds
Generate a CycloneDX Software Bill of Materials for the repository.
SkillCFreshness: CClaude Code +9 - 0.476score
zizmor
lukehinds
Audit the repository's GitHub Actions workflows for common security issues (credential mishandling, untrusted inputs, template injection, overly permissive…
SkillCFreshness: CClaude Code +9 - 0.476score
semgrep
lukehinds
Run semgrep static analysis with the security-audit and secrets rulesets, then map each hit into scrutineer's findings shape so it surfaces alongside…
SkillCFreshness: CClaude Code +9 - 0.476score
dependencies
lukehinds
Index every dependency declared in the repository's manifest and lockfile files (package.json, Gemfile, go.mod, requirements.txt, etc.) and record each one…
SkillCFreshness: CClaude Code +9 - 0.474score
disclose
lukehinds
Draft the disclosure content for a finding in GitHub Security Advisory shape.
SkillCFreshness: CClaude Code +9 - 0.474score
maintainers
lukehinds
Identify the real maintainers of a repository and the best way to contact them about a security issue.
SkillCFreshness: CClaude Code +9
Cite this page
fork skill. Agent Mart. https://agentmart.dev/skills/lukehinds-fork (last updated 2026-10-24)