技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
redact-for-public-disclosure【数据与研究】Redact reverse-eng findings → public disclosure. Preserve methodology, generalizable patterns, teaching value. Private/public repo split, deny-list patterns, orphan-commit publish (no `git log` leaks), category-based calibration (methodology/pattern/version/internal), `check-redaction.sh` CI gate. Use → publish CLI harness findings, upstream proposal…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
git log leaks), category-based
calibration (methodology/pattern/version/internal), check-redaction.sh CI
gate. Use → publish CLI harness findings, upstream proposals, archive
private research.
license: MIT
allowed-tools: Read Write Edit Bash Grep
metadata:
author: Philipp Thoss
version: "1.0"
domain: investigation
complexity: intermediate
language: multi
tags: redaction, disclosure, deny-list, orphan-commit, ci-gate, research-publishingSplit reverse-eng research repo → private source-of-truth + public-disclosure subset via redaction checker, deny-lists, orphan-commit publish. Methodology travels; specific findings stay private.
public/ worktree)Before write/promote, sort each fact → 1 of 4 categories. Determines if/when ships.
| Category | Definition | Shareable? |
|---|---|---|
| methodology | The how of investigation, independent of any specific finding | Always |
| generic pattern | Class-level observations (e.g., "harnesses commonly use a single-prefix flag namespace") | Yes |
| version-specific finding | Concrete observation tied to a specific release (e.g., "in vN.M, the gate defaults off") | Only after the version-lag cool-off |
| live internal | Minified names, byte offsets, dark flag names, current-version gate logic, PRNG/salt constants, internal codenames | Never |
Annotate each draft section, capture log, note → category before review for publication. Section mixing categories splits → methodology lifts clean, rest private.
→ Each fact has category. Public drafts contain only methodology + generic-pattern (+ version-specific older than cool-off).
If err: fact resists categorization → treat as live internal default. Re-categorize only after explicit review vs version-lag policy.
Decide upfront how many versions sit between "current" + "shareable". Two typical: current + 1 prior private, older patterns may discuss. Write to private repo (REDACTION_POLICY.md) → no re-derive later.
# Redaction Policy
Version-lag cool-off: **2 releases**.
- Current release (vN): all version-specific findings PRIVATE.
- Previous release (vN-1): all version-specific findings PRIVATE.
- Releases vN-2 and earlier: version-specific findings may move to public draft after Step 5 review.
Source of truth for "current": output of `monitor-binary-version-baselines`.
Owner: <name>. Reviewed quarterly.
"Current" must be empirical (read from installed binary), not admin. Tie policy to baseline scanner, not calendar.
→ Committed REDACTION_POLICY.md in private repo w/ explicit cool-off + owner.
If err: stakeholders disagree → default most conservative. Cool-offs shorten later; recall leak cannot.
Maintain patterns in single executable script = source of truth for redaction policy. Lives in private repo (tools/check-redaction.sh), runs vs public mirror.
#!/usr/bin/env bash
set -u
PUBLIC_REPO="${1:-./public}"
LEAKS=0
PATTERNS=(
"minified identifier shape|<regex matching short bundle-style identifiers>"
"vendor-prefixed flag|<regex matching the vendor's flag prefix>"
"PRNG/salt constant|<regex matching the specific constants>"
)
for entry in "${PATTERNS[@]}"; do
desc="${entry%%|*}"
pattern="${entry##*|}"
if rg -q "$pattern" "$PUBLIC_REPO"; then
echo "LEAK: $desc"; LEAKS=$((LEAKS+1))
fi
done
exit $LEAKS
Each entry: human label + regex. One per sensitive id shape (not literal — shapes survive version churn). Exit code = leak count; clean exits 0.
→ tools/check-redaction.sh ./public-mirror runs <1s on small repo, exits 0 when no match.
If err: no rg → fall back grep -rqE. Patterns too broad (every run leaks) → narrow source not suppress.
When Phase 1-4 finding could leak via draft → extend scanner before draft. Drafts cheap; teaching scanner durable.
Workflow:
tools/check-redaction.sh (label + regex)Inverts usual order: scanner first, draft second. Scanner = executable spec of "too sensitive to publish", draft can't outpace.
→ Pattern entries in tools/check-redaction.sh predate any public-mirror content matching. git log tools/check-redaction.sh shows scanner updates landing before related drafts.
If err: scanner lags drafts → audit public mirror vs new pattern immediately. Redact, then commit scanner update w/ note.
Define explicit allow-list of files syncing to public mirror. New files default private; promotion needs redaction-check clearance.
# tools/public-allowlist.txt
README.md
LICENSE
guides/methodology-overview.md
guides/category-classification.md
docs/contributing.md
tools/sync-to-public.sh reads allow-list, copies only those files, exits non-zero if missing file (catches typos).
#!/usr/bin/env bash
set -eu
PRIVATE_ROOT="${1:?private repo path required}"
PUBLIC_ROOT="${2:?public mirror path required}"
ALLOWLIST="$PRIVATE_ROOT/tools/public-allowlist.txt"
while IFS= read -r path; do
[ -z "$path" ] && continue
case "$path" in \#*) continue ;; esac
src="$PRIVATE_ROOT/$path"
dst="$PUBLIC_ROOT/$path"
if [ ! -e "$src" ]; then
echo "MISSING: $path"; exit 2
fi
mkdir -p "$(dirname "$dst")"
cp -a "$src" "$dst"
done < "$ALLOWLIST"
Promotion needs 3 in order: file added to allow-list, passes redaction check, reviewer confirms category labels (Step 1).
→ Public mirror = exactly files in tools/public-allowlist.txt. No file in mirror missing from allow-list.
If err: file in mirror missing allow-list → leak event. Investigate arrival, remove or formally promote after review.
Public mirror = single git commit --orphan-rooted commit recreated each publish. Prevents git log exposing pre-redaction drafts.
# In the public mirror (separate repo or worktree)
cd /path/to/public-mirror
git checkout --orphan publish-tmp
git rm -rf . # Clear the index
# Sync from private using the allow-list
bash /path/to/private/tools/sync-to-public.sh /path/to/private .
git add -A
git commit -m "Publish: <date>"
git branch -D main 2>/dev/null || true
git branch -m main
git push --force origin main
Public repo git log shows exactly 1 commit. Prior drafts + redaction iter stay in private. No git log -p, git reflog, branch listing on public can recover pre-redaction → never committed there.
→ git log --oneline on public mirror shows single commit per publish. No refs to private repo history (no parent SHAs, merge commits, tags from private) appear.
If err: git push --force rejected (branch protection) → open single-commit PR from clean orphan branch instead. Never solve rejection by pushing private history.
Run tools/check-redaction.sh on every commit to public-sync branch. Failed check blocks publish, not warns.
# .github/workflows/redaction-check.yml (in the public mirror repo)
name: redaction-check
on:
push:
branches: [main, publish-*]
pull_request:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install ripgrep
run: sudo apt-get update && sudo apt-get install -y ripgrep
- name: Fetch redaction scanner
env:
GH_TOKEN: ${{ secrets.PRIVATE_REPO_TOKEN }}
run: |
gh api repos/<org>/<private-repo>/contents/tools/check-redaction.sh \
--jq .content | base64 -d > check-redaction.sh
chmod +x check-redaction.sh
- name: Run scanner
run: ./check-redaction.sh .
2 design choices:
→ Pushes introducing deny-listed pattern fail CI; publish doesn't land. Maintainers see failing label (e.g., LEAK: vendor-prefixed flag) w/o regex itself.
If err: private-repo token can't grant to public CI → embed only minimum-leak portion in public (broad shape patterns not identifying vendor) + run full scanner pre-push from private.
When scanner trips on legit content → narrow pattern not add ignore-line. Broad deny-lists w/ local suppressions rot fast — 6 mo later no one remembers why line suppressed, next leak slides past.
Decision tree:
check-redaction.sh linking case.# REASON: comment stating why safe. Date comment.# Bad — mystery suppression
echo "API endpoint pattern" >> ignore.txt
# Good — narrowed pattern with rationale
# Pattern v2: tightened from `\bgate\(` to `\bgate\(['\"][a-z]+_phase` after
# legitimate `gate(true)` calls in our own SDK examples started matching. 2026-04-15.
PATTERNS+=("vendor flag predicate|\\bgate\\(['\"][a-z]+_phase")
→ Each scanner pattern has 0 or 1 inline comment explaining tightening. Suppressions, if any, carry date + rationale.
If err: suppressions accumulate (>1/quarter) → deny-list mis-shaped. Schedule policy review + rebuild patterns from categorized inventory.
Not all redaction incident-driven. Run periodic sweep (monthly typical) → re-categorize recent additions + re-run scanner. Drift catches itself before incident-grade.
Sweep checklist:
tools/check-redaction.sh vs public mirror (should still exit 0)tools/public-allowlist.txt matches actual public-mirror file set→ Short sweep log per month in private repo (sweeps/2026-04.md) w/ checklist outcomes + actions.
If err: sweep repeatedly skipped → automate calendar reminder. Sweep keeps finding same drift → workflow upstream is problem. Investigate why categorization skipped at draft time.
tools/public-allowlist.txttools/check-redaction.sh ./public-mirror exits 0git log --oneline on public mirror = single orphan commit per publishREDACTION_POLICY.md exists in private repo w/ explicit version-lag cool-offacme_widget_v3, widget_handler_42) — clearly invented, never traceable.git rebase/filter-branch to scrub leak in place on public. Force-push rewritten history still leaves traces in clones + forks. Orphan-commit = structural fix; ad-hoc rewriting not.LEAK: vendor-prefixed flag) appear in public CI logs.monitor-binary-version-baselines — Phase 1, baselines feed version-lag policyprobe-feature-flag-state — Phases 2-3, classification enters pipeline at Step 1conduct-empirical-wire-capture — Phase 4, capture artifacts need redaction before public refsecurity-audit-codebase — both pipelines benefit from deny-list scanningmanage-git-branches — orphan-commit pattern needs branch hygiene