MCP HubMCP Hub
스킬 목록으로 돌아가기

redact-for-public-disclosure

pjt222
업데이트됨 2 days ago
5 조회
17
2
17
GitHub에서 보기
커뮤니케이션general

정보

이 스킬은 역공학 결과물을 공개 목적으로 편집하며, 방법론과 일반화 가능한 패턴은 보존한 채 민감한 세부 정보를 제거합니다. 비공개/공개 저장소 분리, 거부 목록 패턴, 그리고 `git log` 유출을 방지하기 위한 고립 커밋 발행을 활용한 안전한 워크플로우를 구현합니다. CLI 도구 분석 결과, 업스트림 제안 사항을 안전하게 공개하거나 `check-redaction.sh` CI 검증을 통해 연구를 보관할 때 사용하세요.

빠른 설치

Claude Code

추천
기본
npx skills add pjt222/agent-almanac -a claude-code
플러그인 명령대체
/plugin add https://github.com/pjt222/agent-almanac
Git 클론대체
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/redact-for-public-disclosure

Claude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서

Redact for Public Disclosure

Split 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.

Use When

  • Publish methodology findings re: closed-source CLI harness you integrate w/
  • Prep upstream proposal/bug report → project not yours
  • Archive private research repo → public ref
  • Promote investigation notes (Phase 1-4) → public guide
  • Establish publish pipeline before findings stack → leak risk no backup
  • Clean up after near-miss draft almost shipped sensitive id

In

  • Required: Private research repo w/ mixed-sensitivity (source of truth)
  • Required: Target public mirror (separate repo, or public/ worktree)
  • Optional: Existing draft slated for publication
  • Optional: Version-lag policy (default "current + 1 prior stay private")
  • Optional: List of vendor ids, flag prefixes, namespaces known sensitive

Do

Step 1: Categorize Each Fact

Before write/promote, sort each fact → 1 of 4 categories. Determines if/when ships.

CategoryDefinitionShareable?
methodologyThe how of investigation, independent of any specific findingAlways
generic patternClass-level observations (e.g., "harnesses commonly use a single-prefix flag namespace")Yes
version-specific findingConcrete observation tied to a specific release (e.g., "in vN.M, the gate defaults off")Only after the version-lag cool-off
live internalMinified names, byte offsets, dark flag names, current-version gate logic, PRNG/salt constants, internal codenamesNever

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.

Step 2: Set Version-Lag Cool-Off

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.

Step 3: Build Deny-List Scanner

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.

Step 4: Maintain Deny-List Before Drafting

When Phase 1-4 finding could leak via draft → extend scanner before draft. Drafts cheap; teaching scanner durable.

Workflow:

  1. New finding lands in private repo (e.g., new flag prefix)
  2. Ask: "If leaked, what scanner catch?"
  3. Add pattern entry to tools/check-redaction.sh (label + regex)
  4. Run scanner vs entire public mirror → confirm new pattern not tripped by legit content
  5. Only then draft public content touching area

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.

Step 5: Private/Public File-Set Split

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.

Step 6: Publish via Orphan Commit

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.

Step 7: Wire CI Gate

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:

  • Scanner pulled from private at CI time → deny-list never lives in public (patterns themselves sensitive — publishing tells reader exactly what to look for)
  • Job exits w/ scanner exit code; non-zero blocks workflow

→ 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.

Step 8: False Positives Honestly

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:

  1. Match actually safe? Re-categorize via Step 1. If turns out live internal in disguise → redact, no suppress.
  2. Pattern too broad? Tighten regex so safe content no match. Doc tightening w/ comment in check-redaction.sh linking case.
  3. Only if 1 + 2 fail — pattern structurally too entangled w/ legit to narrow → single-line suppress w/ # 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.

Step 9: Periodic Sweeps

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:

  • Re-read version-lag policy; confirm empirical "current" unchanged or update
  • Audit last month private-repo commits for new uncategorized findings (Step 1)
  • Run tools/check-redaction.sh vs public mirror (should still exit 0)
  • Review scanner patterns added since last sweep — too broad? Tighten if so
  • Any version aged past cool-off → ID findings now eligible for promotion
  • Confirm 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.

Check

  • Every public mirror file on tools/public-allowlist.txt
  • tools/check-redaction.sh ./public-mirror exits 0
  • git log --oneline on public mirror = single orphan commit per publish
  • REDACTION_POLICY.md exists in private repo w/ explicit version-lag cool-off
  • Every Phase 1-4 finding has category label (methodology/pattern/version/internal)
  • Public CI runs scanner on every push; deliberate test pattern fails build
  • Deny-list scanner itself does NOT live in public repo
  • Most recent monthly sweep log dated <35 days

Traps

  • "Just one example to make concrete." Including one specific finding "to ground methodology" = most common leak path. Use synthetic placeholders (acme_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.
  • Suppressions vs tightening. Scanner w/ 20 suppressions = 0 meaningful coverage. Each suppression = future leak.
  • Public CI warns vs fails. Warnings ignored. Gate must block publish (non-zero exit, no merge button).
  • Allow-list drift. New private files don't auto belong on allow-list. Default-deny only safe.
  • Encryption ≠ redaction. Encoding, hashing, rot13-ing sensitive id + publishing = still publishes (original recoverable). Redact = "does not appear at all."
  • Publishing deny-list. Patterns themselves = finding catalog. Reader seeing regex knows exactly what to grep in binary. Keep scanner private; only labels (LEAK: vendor-prefixed flag) appear in public CI logs.
  • Private repo as draft pile. Source of truth not scratch space. Same versioning, review, backup as production.

  • monitor-binary-version-baselines — Phase 1, baselines feed version-lag policy
  • probe-feature-flag-state — Phases 2-3, classification enters pipeline at Step 1
  • conduct-empirical-wire-capture — Phase 4, capture artifacts need redaction before public ref
  • security-audit-codebase — both pipelines benefit from deny-list scanning
  • manage-git-branches — orphan-commit pattern needs branch hygiene

GitHub 저장소

pjt222/agent-almanac
경로: i18n/caveman-ultra/skills/redact-for-public-disclosure
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

himalaya-email-manager

커뮤니케이션

이 Claude Skill은 IMAP을 통해 Himalaya CLI 도구를 이용한 이메일 관리를 가능하게 합니다. 개발자들이 자연어 쿼리로 IMAP 계정의 이메일을 검색하고, 요약하고, 삭제할 수 있게 해줍니다. 일일 요약 수신이나 Claude에서 직접 배치 작업 수행과 같은 자동화된 이메일 워크플로우에 활용하세요.

스킬 보기

imsg

커뮤니케이션

imsg는 macOS용 CLI 도구로, Messages.app을 통해 iMessage/SMS와 프로그래밍 방식으로 상호작용할 수 있게 해줍니다. 이 도구를 사용하면 개발자가 채팅 목록을 확인하고, 메시지 기록을 조회하며, 대화를 실시간으로 모니터링하고, 메시지나 첨부 파일을 보낼 수 있습니다. 이 스킬을 활용하여 메시징 작업을 자동화하거나 개발 워크플로우에 iMessage/SMS 기능을 통합해 보세요.

스킬 보기

internationalization-i18n

커뮤니케이션

이 Claude Skill은 애플리케이션에 국제화(i18n)와 현지화를 구현하기 위한 포괄적인 지침을 제공합니다. i18next 및 gettext와 같은 라이브러리를 활용하여 메시지 추출, 번역 관리, 로케일별 형식 지정, RTL(오른쪽에서 왼쪽) 지원 등 주요 작업을 다룹니다. 다국어 애플리케이션을 구축하거나 국제 사용자를 위한 현지화 기능을 추가할 때 활용하세요.

스킬 보기

wacli

커뮤니케이션

wacli는 WhatsApp Web 프로토콜을 통해 WhatsApp 메시징, 검색 및 동기화를 가능하게 하는 명령줄 도구입니다. 주로 Clawdis 워크플로우 내에서 자동화 처리를 위해 사용되지만, 메시지 전송, 채팅 동기화 또는 기록 조회를 위해 직접 호출할 수도 있습니다. 주요 기능으로는 QR 기반 인증, 지속적인 백그라운드 동기화, 텍스트 및 파일 전송 기능이 포함됩니다.

스킬 보기