# Company Brainify > Extrae un company brain saneado desde un brain personal: elimina ratings, compensación, evaluaciones y dinámicas políticas de páginas, takes y facts, y purga el historial de git sensible. Fuente: https://skillsagentes.com/skills/garrytan/gbrain/company-brainify Markdown: https://skillsagentes.com/skills/garrytan/gbrain/company-brainify.md Repositorio: https://github.com/garrytan/gbrain Autor: garrytan Licencia: MIT Actualizado: hace 8 días Coste de contexto: 121 tok instalada, 8.5k tok al activarse, 8.8k tok con todos los archivos del bundle Bundle: 2 archivos, 35 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add garrytan/gbrain --skill company-brainify --agent claude-code # Cursor npx -y skills add garrytan/gbrain --skill company-brainify --agent cursor # Codex npx -y skills add garrytan/gbrain --skill company-brainify --agent codex # Gemini CLI npx -y skills add garrytan/gbrain --skill company-brainify --agent gemini # Windsurf npx -y skills add garrytan/gbrain --skill company-brainify --agent windsurf # Cline npx -y skills add garrytan/gbrain --skill company-brainify --agent cline ``` ## Qué hace - Strips ratings, comp, performance, retention and political-dynamics content from pages, takes and facts across the full brain scan scope - Scans people/, meetings/, daily/, companies/, projects/, analysis/, plus takes and facts, not just people/ - Purges sensitive git history from the shared repo behind a data-loss-gate confirmation card - Verifies removal with grep triage plus gbrain query/takes search/recall retrieval passes - Runs as a report-only re-audit on an existing shared brain, flagging without editing ## Cuándo usarla - Standing up a shared company brain from a founder/exec's personal brain - Auditing an existing shared brain for sensitive content that shouldn't be there - Onboarding new team members to a brain repo that must be verified clean first - Periodic hygiene pass on a shared brain that re-accumulates sensitive data ## Cuándo no - A standalone 'delete/purge/clean up X' intent — that routes to data-loss-gate instead - Sharing a single page as encrypted HTML — that's the publish skill - Checking structural brain health (orphans, backlinks, stale pages) — that's maintain ## Qué la activa - "Ayúdame a crear un company brain a partir de mi brain personal" - "Necesito sanitizar el brain compartido antes de dar acceso al equipo" - "Audita el brain compartido para ver si quedan datos sensibles" - "Quiero compartir mi brain con el equipo, límpialo primero" ## Antes de instalar - Requiere gbrain instalado y, para el purgado de historial, git filter-repo instalado por separado. - Necesita en el PATH: git - Variables de entorno: BACKUP_PATH, BRAIN, CLEAN, PERSONAL, PURGE_DIRS, STAGING, WORK - reads environment config ## Archivos - SKILL.md — 33 KB - routing-eval.jsonl — 1 KB ## SKILL.md Reproducido tal cual desde garrytan/gbrain bajo MIT. Esta sección es el documento original y está en inglés. # company-brainify — Personal → Team-Brain Sanitization > **Convention:** see [conventions/brain-first.md](../conventions/brain-first.md) — > discovery runs through the brain's own retrieval, not filesystem guesswork. > The grep pipelines below TRIAGE; `gbrain query` finds what keyword patterns miss. > > **Convention:** see [conventions/test-before-bulk.md](../conventions/test-before-bulk.md) — > sanitize 3-5 files, read the output yourself, then ramp. A bad bulk > sanitization pass is worse than none: it looks done and isn't. > > **Convention:** see [conventions/regex-discipline.md](../conventions/regex-discipline.md) — > "is this sensitive?" is a judgment call, so the model decides per file. The > grep patterns are earned triage/verification tools, never the judge. > > **Convention:** see [_brain-filing-rules.md](../_brain-filing-rules.md) — > edits stay in the page's existing directory; the deletion log files > date-keyed under `daily/`. ## The Problem Personal brains accumulate everything — company knowledge, meeting notes, internal assessments, compensation details, management strategy, candid opinions about the people you work with. When you stand up a shared team brain from that personal brain (see `docs/architecture/brains-and-sources.md` for the team-mount topology), all of that has to go. The knowledge is valuable; the sensitive metadata is a liability. Clean working-tree files alone are NOT enough: git history still carries every pre-sanitization version, and gbrain takes/facts carry evaluative claims outside the page prose. This skill handles all three surfaces — pages, takes/facts, and history. ## When to Use - Standing up a shared company brain from a founder/exec's personal brain - Auditing an existing shared brain for sensitive content that shouldn't be there - Onboarding new team members to a brain repo that must be verified clean first - Periodic hygiene pass on a shared brain that re-accumulates sensitive data ## What Gets Removed ### Always strip (non-negotiable) | Category | Examples | |----------|----------| | **Internal scores/ratings** | `score:`, `rating:`, `skill:`, or any vertical-specific `*_score:` frontmatter field; any numeric rating of a person | | **Compensation** | Salary, equity, carry, option grants, comp changes, retention packages | | **Performance assessments** | Strengths/weaknesses sections about employees, "at risk" flags, underperformance mentions, "picking up slack" references | | **Departure/retention** | Who's considering leaving, who was convinced to stay, departure rumors, retention conversations | | **Management strategy** | How-to-manage-someone sections, "the hard conversation" notes, scope/title management plans | | **Internal political dynamics** | Who doesn't like whom, who's nervous about whom, adversarial relationships, power dynamics | | **Personal PII** | Phone numbers, personal email addresses, home addresses, family or medical details, personal legal matters, personal-life details | | **Takes/facts** | Any take or fact referencing the above categories — performance, comp, retention, weakness, management risk. Fact rows are DELETED from the page's Facts fence, never merely expired with `gbrain forget` | ### Always keep | Category | Examples | |----------|----------| | **Professional identity** | Name, role, title, work email, LinkedIn | | **What they're building** | Current projects, product work, technical contributions | | **Career arc** | Prior companies, education, professional background (public info) | | **Professional beliefs** | Their views on technology, strategy, product philosophy | | **Timeline of work** | Meeting attendance, project milestones, launches (factual, not evaluative) | | **Skills/expertise** | Technical capabilities, domain knowledge | ## Scan Scope — Wider Than people/ Sensitive content leaks far beyond people pages. The scan scope is: - `people/` — the primary surface (frontmatter fields, assessment sections) - `meetings/` — transcripts and minutes with candid assessments - `daily/` — daily notes referencing comp/performance/retention conversations - `companies/`, `projects/`, `analysis/` — cross-references to removed content - **Takes** — evaluative claims in page takes fences (`gbrain takes search`) - **Facts** — hot-memory facts (`gbrain recall --grep`) - **Back-links** — after edits, `gbrain check-backlinks check` confirms no page still points at removed sections A pass that only covers `people/` will certify a brain that still leaks. ## Procedure All paths below are relative to the brain repo root: ```bash BRAIN="$(gbrain config get sync.repo_path)" cd "$BRAIN" ``` ### Phase 1: Identify scope (retrieval-first) 1. Retrieval discovery — hybrid search catches judgment-shaped content that no keyword pattern will: ```bash gbrain query "compensation, equity, or salary discussions about team members" --limit 50 gbrain query "performance concerns, underperformance, or who is struggling" --limit 50 gbrain query "considering leaving, retention conversations, departure rumors" --limit 50 gbrain takes search "performance" --limit 50 gbrain recall --grep "salary" ``` Resolve every returned slug to its repo-relative file path and write the paths into `/tmp/brainify-scope.txt` (one per line). This file is the scope list; the structural pass below APPENDS to it — nothing later in the procedure may truncate it, or the retrieval-discovered pages silently drop out of scope. 2. Structural discovery — people files that belong to the company, plus keyword hits across the wider scan scope: ```bash grep -rli 'company: *"acme-example"' people/ --include="*.md" | sort >> /tmp/brainify-scope.txt grep -rli -E 'salary|equity|carry|retention|underperform|performance review|hard conversation' \ meetings/ daily/ companies/ projects/ analysis/ --include="*.md" 2>/dev/null >> /tmp/brainify-scope.txt sort -u -o /tmp/brainify-scope.txt /tmp/brainify-scope.txt ``` 3. Cross-reference against the company's public people page (website, LinkedIn) to catch files using different frontmatter conventions. 4. Count: `wc -l /tmp/brainify-scope.txt` ### Phase 2: Triage sensitivity Prioritize by hit density (portable `grep -E`; no `\b` — BSD and GNU disagree): ```bash while read -r f; do hits=$(grep -c -i -E 'carry|salary|equity|comp change|departure|considering leaving|retention|underperform|picking up slack|performance review|management risk|hard conversation|nervou|score: *[0-9]|firing|fired|pip|probation|weakness' "$f" 2>/dev/null || true) [ "${hits:-0}" -gt 0 ] && echo "$hits $f" done < /tmp/brainify-scope.txt | sort -rn > /tmp/brainify-triage.txt ``` High-hit files need full judgment passes. Zero-hit files may only need frontmatter field removal — but they still get read (regex triages, the model judges). ### Phase 3: Sanitize (STAGING COPY preferred; test first, then parallel) Phase 3 is destructive: it strips content across many files, removes takes, and deletes fact rows. Two rules govern it. **Choose the target FIRST — copy, don't mutate the personal brain.** - **Standing up a NEW team brain (default, preferred):** sanitize a STAGING COPY of the scanned directories, never the personal brain in place. The founder's personal brain is SUPPOSED to keep comp, performance, and candid notes — stripping them from the personal working tree destroys valuable private data. Copy the Phase-1 scope into a durable staging dir and edit THAT; Phase 5 Step 0 exports from the staging copy. Blast radius: none on the personal brain. ```bash # Durable staging dir (NOT /tmp — same reasoning as the mirror backup). STAGING="$HOME/.gbrain/backups/brainify-staging-$(date +%Y%m%d-%H%M%S)" mkdir -p "$STAGING" && chmod 700 "$STAGING" for d in people meetings daily companies projects analysis; do [ -d "$d" ] && rsync -a "$d/" "$STAGING/$d/" done cd "$STAGING" # all edits below happen here, not in sync.repo_path ``` - **Re-auditing an EXISTING shared brain:** the shared brain IS the target, so edits are in place on the SHARED repo (cd into the shared repo, never the personal `sync.repo_path`). Fact-row removal + re-sync applies to the shared source's DB. **Fire the [data-loss-gate](../data-loss-gate/SKILL.md) confirmation card BEFORE the bulk destructive edits begin.** Both targets are destructive (the copy path removes content from the tree destined for the team; the in-place path removes content from a live brain). Pre-filled for Phase 3: ``` ⚠️ DATA DELETION — Confirmation Required What: strip sensitive content, remove takes, and delete fact rows across [N files] in [STAGING COPY at | the SHARED brain in place] Count: [N files edited; T takes removed; F fact rows removed] Location: [staging path OR shared repo path] — NOT the personal sync.repo_path on the staging path Why: preparing a sanitized tree for team access Recoverable? - [x] Personal brain untouched (staging-copy path) — re-copy to redo - [ ] In-place shared-brain path: edits overwrite the live tree; git history is the recovery line until Phase 5 purges it Proceed? (yes/no) ``` Require a typed "yes"/"do it" per data-loss-gate; "ok"/"sure" are not consent. Per test-before-bulk: do 3-5 files first, read the results, then ramp. For large sets (50+ files), batch into groups of 10-12 and spawn parallel subagents. Per file: 1. Read the file completely 2. Remove all content matching the "Always strip" categories 3. Frontmatter: delete rating/comp field lines entirely 4. Sections: remove entire sections (assessment weaknesses, team dynamics, management strategy) 5. Takes and Facts fences: remove entire rows that reference sensitive categories — a take like "alice-example believes charlie-example is underperforming" reveals both the opinion and who holds it; remove the whole row, never just the attribution 6. Inline mentions: surgically edit sentences/paragraphs 7. Write the cleaned file back **Decision rule:** use `Edit` for surgical removal when only a few sections need it. Use `Write` to rewrite the entire file only when sensitive content is deeply interwoven throughout. **Facts: `forget` is NOT removal.** `gbrain forget ` expires a fact — the row stays on the page's Facts fence struck through, and the DB still serves it via `--include-expired`. An expired fact is retained, not gone. For sanitization, sensitive fact rows must be ACTUALLY REMOVED: find them (`gbrain recall --grep`), then delete the row from the page's Facts fence (step 5), exactly like a sensitive take. On an in-place shared brain, the page edit must then be re-synced (`gbrain sync` re-imports the edited page) AND the facts index reconciled — sync's convergence contract covers page import only; downstream fact extraction is explicitly decoupled (`src/commands/sync.ts`, "CONVERGENCE CONTRACT"), so the DB keeps serving the deleted row until the extract-facts reconcile runs. Trigger it (`gbrain sweep`, or wait for the serve-resident sweep), then confirm with `gbrain recall --grep` that the row is actually gone. An edited page over an un-reconciled facts index still leaks through retrieval. `forget` alone can never certify a brain clean. After edits: on the **staging-copy** path the fact rows are removed by editing the copied markdown directly (there is no live DB to re-sync yet — the team DB is built fresh when Phase 5 Step 0 turns the export into a source). On the **in-place shared-brain** path, run `gbrain sync` so the page content matches the markdown, then reconcile and verify the facts index as above. Either way, run `gbrain check-backlinks check` to catch pages still pointing at removed content. ### Phase 4: Verify Re-run the Phase 2 triage — the count of flagged files should drop to (near-)zero. Then targeted greps: ```bash # Rating fields remaining in frontmatter grep -rn -E '^[a-z_]*(score|rating|skill)[a-z_]*: *[0-9]' people/ --include="*.md" # Phone numbers grep -rn -E '\+1[0-9]{10}|\([0-9]{3}\) [0-9]{3}-[0-9]{4}' people/ --include="*.md" # Comp keywords (full scan scope, not just people/) grep -rin -E 'carry|comp change|equity|salary' people/ meetings/ daily/ companies/ projects/ analysis/ --include="*.md" 2>/dev/null # Management/performance grep -rin -E 'considering leaving|departure rumor|underperform|picking up slack|hard conversation' people/ meetings/ daily/ companies/ projects/ analysis/ --include="*.md" 2>/dev/null ``` False positives (e.g. "carry the torch") are fine — manually confirm each remaining hit rather than tightening the pattern (regex-discipline). **Verify the tree that ships.** On the staging-copy path, these greps run against the sanitized `$STAGING` tree (which Phase 5 Step 0 turns into the export) — the personal working tree is not what ships, so certifying it proves nothing. For an in-place shared-brain re-audit, the shared repo's tree is the shipped tree and this pass stands as-is. Then the strongest check — the retrieval the team will actually use. Against the sanitized brain/source (scope with `--source ` when the shared source is mounted alongside personal content): ```bash gbrain query "what is alice-example's compensation" --limit 10 gbrain query "who is underperforming or at risk of leaving" --limit 10 gbrain takes search "weakness" --limit 20 ``` Every one of these must come back empty or with only keep-category content. ### Phase 5: Commit and purge history — GATED Clean files aren't enough if the repo has history: old commits still contain the sensitive versions. **Step 0 — preferred alternative (non-destructive).** When standing up a NEW team repo, skip history rewriting entirely: the sanitized STAGING tree from Phase 3 becomes a fresh repo with fresh history. The personal repo keeps its full history AND its full working tree, untouched. **Export rule: nothing unscanned ships.** Because Phase 3 copied ONLY the scanned directories into `$STAGING`, the staging tree contains nothing the sanitization pass didn't read — the include-only rule holds by construction. Never copy extra directories in: everything outside the scan scope (`conversations/`, `originals/`, `sources/`, `inbox/`) stays out. A whole-repo copy is the classic leak — it ships raw transcripts, originals, and inbox captures no pass ever read. To ship a new directory, add it to the scan scope first (Phases 1-4) so it lands in `$STAGING` sanitized. ```bash # The sanitized staging tree IS the export. cd "$STAGING" # Re-run the Phase 4 verification greps + retrieval checks INSIDE $STAGING — # the staging tree is what ships, and it is the tree that must certify clean. # ... Phase 4 greps against $STAGING ... git init -b main git add -A && git commit -m "Initial import — sanitized team brain" git remote add origin git push -u origin main ``` Only when a shared repo ALREADY exists with sensitive history in it do you need the purge below. **Step 1 — target the SHARED repo, commit the clean tree, then mirror-clone.** The purge operates on the SHARED repo, NEVER on `sync.repo_path` (the personal brain) — Step 0's guarantee that the personal repo keeps full history depends on it. Clone the shared repo to a durable work dir, stay there for every step below, and assert the target is not the personal repo before touching anything. ```bash PERSONAL="$(gbrain config get sync.repo_path)" mkdir -p "$HOME/.gbrain/backups" && chmod 700 "$HOME/.gbrain/backups" WORK="$HOME/.gbrain/backups/brainify-purge-$(date +%Y%m%d-%H%M%S)" git clone "$WORK/shared" cd "$WORK/shared" [ "$(git rev-parse --show-toplevel)" != "$PERSONAL" ] \ || { echo "target IS sync.repo_path (personal brain) — ABORT"; exit 1; } # Apply the sanitized tree, then COMMIT it BEFORE the mirror clone. A mirror # captures COMMITTED state only; if the clean tree lives only in volatile # staging during the rewrite window, a crash loses the sanitization work. # Committing makes the clean state durable and recoverable. for d in people meetings daily companies projects analysis; do [ -d "$STAGING/$d" ] && rsync -a "$STAGING/$d/" "./$d/" # or sanitize in place here done git add -A && git commit -m "Sanitize: strip sensitive content before history purge" # Mirror-clone backup = the recoverability line on the card. Capture the path # in a variable NOW and reuse it verbatim at purge time — a run crossing # midnight must NOT recompute $(date) and false-abort on a mismatched name. BACKUP_PATH="$HOME/.gbrain/backups/shared-brain-history-backup-$(date +%Y%m%d-%H%M%S).git" git clone --mirror "$WORK/shared" "$BACKUP_PATH" git -C "$BACKUP_PATH" log -1 >/dev/null || { echo "backup unreadable — ABORT"; exit 1; } ``` Verify the mirror exists and reads before presenting the card — it is the card's recoverability line. **Step 2 — STOP. Present the [data-loss-gate](../data-loss-gate/SKILL.md) confirmation card and wait.** History rewrite + force-push is the most destructive operation in this skill: it permanently discards every prior version of the purged paths from the remote. Never run it without the card answered. Pre-filled for this operation: ``` ⚠️ DATA DELETION — Confirmation Required What: rewrite git history to remove all prior versions of [purged paths] from the SHARED repo, then force-push to [remote/branch] Count: [N commits rewritten; M files with history purged] Size: [repo size before → expected after] Location: [SHARED repo work dir; remote URL; branch] Target check: this is the SHARED repo, verified ≠ personal sync.repo_path ($PERSONAL) — the personal brain's history is never rewritten Why: prior commits contain pre-sanitization versions of pages that were just cleaned — team access to the repo means team access to history Recoverable? - [x] Mirror-clone backup at $BACKUP_PATH (verified: exists, `git -C "$BACKUP_PATH" log` works) - [ ] NOT recoverable from the rewritten remote — old SHAs become unreachable What we'd lose: - all pre-sanitization history for the purged paths (edit trail, blame, old versions) - every existing clone breaks — all collaborators must re-clone Alternative to deletion: - fresh-history export to a NEW team repo (Step 0) — personal repo untouched Proceed? (yes/no) ``` Per data-loss-gate: require a typed **"yes"** or **"do it"** — "ok", "sure", "go ahead" are not consent. If the user asks a question, answer and re-present the card. This gate is a routing convention, not a runtime enforcement — nothing in gbrain mechanically blocks `git filter-repo` — which is exactly why the agent following this skill must not skip it. **Step 3 — purge (only after the explicit typed yes).** Requires `git filter-repo` (not bundled with git; install separately). **Run this ONLY in the shared-repo work dir from Step 1 (`cd "$WORK/shared"`). NEVER run `git filter-repo` or `git push --force` in `sync.repo_path` — the personal brain's history must stay intact.** The commands below reuse `$WORK` and `$BACKUP_PATH` from Step 1; they never recompute a date-stamped path. ```bash cd "$WORK/shared" [ "$(git rev-parse --show-toplevel)" != "$PERSONAL" ] \ || { echo "target IS sync.repo_path — ABORT, do not filter-repo"; exit 1; } # The purge list derives from the COMPLETE set of sanitized paths — the same # directories Phases 1-4 scanned. A filter list narrower than the scan # (people/ + meetings/ only) leaves pre-sanitization history alive for every # other scanned directory. The restore carrier below MUST match this same # list — backed-up set, filtered set, and re-added set are identical. PURGE_DIRS="people meetings daily companies projects analysis" # Back up the clean working tree of every purged path to a DURABLE carrier # (under $WORK in ~/.gbrain/backups — never /tmp, which can vanish mid-rewrite). CLEAN="$WORK/clean" mkdir -p "$CLEAN" for d in $PURGE_DIRS; do [ -d "$d" ] || continue mkdir -p "$CLEAN/$d" && cp -r "$d/." "$CLEAN/$d/" done # Rewrite history: one --path per purged directory, derived from $PURGE_DIRS rm -rf .git/filter-repo git filter-repo --invert-paths $(for d in $PURGE_DIRS; do printf -- '--path %s/ ' "$d"; done) --force # Restore clean files and re-commit as a single new commit — same $PURGE_DIRS for d in $PURGE_DIRS; do [ -d "$CLEAN/$d" ] || continue mkdir -p "$d" && cp -r "$CLEAN/$d/." "$d/" done git remote add origin # filter-repo removes remotes for d in $PURGE_DIRS; do [ -d "$d" ] && git add "$d/"; done git commit -m "Re-add sanitized directories" # VERIFY RESTORE COMPLETENESS before the irreversible push — a partial restore # would ship a smaller tree than was sanitized. Compare file counts (and, for # extra safety, checksums) between the carrier and the restored tree. before=$(find "$CLEAN" -type f | wc -l | tr -d ' ') after=$(for d in $PURGE_DIRS; do [ -d "$d" ] && find "$d" -type f; done | wc -l | tr -d ' ') [ "$before" = "$after" ] \ || { echo "restore incomplete ($before → $after files) — ABORT, do not force-push"; exit 1; } # Optional stronger check: diff -r "$CLEAN/" "" for each purged dir. # RE-VERIFY the backup immediately before the irreversible step — card-time # verification is not enough; time has passed and the rewrite could have gone # sideways. Reuse $BACKUP_PATH (do NOT recompute $(date)); abort if unreadable. git -C "$BACKUP_PATH" log -1 >/dev/null \ || { echo "backup missing/unreadable — ABORT, do not force-push"; exit 1; } git push --force origin main ``` **Step 4 — log it (to the PERSONAL brain, NEVER the shared repo).** Per data-loss-gate, append the deletion under `## Data Deletions` — but write it to the PERSONAL brain's `$PERSONAL/daily/notes/YYYY-MM-DD.md` (or a local ops log), never into the shared repo. The log names the purged paths AND the backup location; in the shared repo those two facts would tell every team member exactly which paths held sensitive content and where the pre-sanitization backup lives — the audit trail becomes a treasure map. Record: timestamp, purged paths, commit counts, and `$BACKUP_PATH` as the recovery line. **After the force push:** - All existing clones must re-clone - Hosting providers may cache unreachable commits for a time (on the order of months); for immediate removal use the provider's sensitive-data removal process. For private/internal repos, the SHA being unreachable from any ref is usually sufficient - The sync cursor may reference a rewritten-away SHA; if the next `gbrain sync` errors or falls back to a full rescan, that is the cursor recovering — run `gbrain doctor` if it doesn't settle - **Backup retention:** once the rewrite is verified good (team has re-cloned, sync settled, no missing content reported), keep the mirror-clone backup in `~/.gbrain/backups/` for a retention window (~30 days is a sane default), then delete it — it contains the pre-sanitization history and should not accumulate indefinitely: `rm -rf ~/.gbrain/backups/shared-brain-history-backup-.git` (the glob must match the `shared-brain-history-backup-*` name the backup step created — a mismatched pattern deletes nothing and silently retains the pre-sanitization history forever) - If the repo carries push hooks or auto-hardening wiring, re-verify remotes and hooks survived the rewrite before handing the repo to the team ### Phase 6: Ongoing hygiene — periodic re-audit Sensitive data re-accumulates through meeting-transcript ingestion (candid assessments), enrichment pipelines pulling internal data, and manual writes during candid conversations. One clean pass is a snapshot, not a state. **Recommendation:** schedule a monthly re-audit (weekly for high-ingest brains) that re-runs Phases 1, 2, and 4 in report-only mode — scan and flag, no edits — and surfaces new hits for human review before they reach the shared repo. Wire it per [conventions/cron-via-minions.md](../conventions/cron-via-minions.md): the cron slot submits a background job (`gbrain jobs submit`), scheduling guidance in `skills/cron-scheduler/SKILL.md`, job-lane routing in `skills/minion-orchestrator/SKILL.md`. The report-only run writes its findings summary; a human (or a gated follow-up run) does the removal. ## Scaling Notes - **< 20 files:** process sequentially in one pass - **20-50 files:** 2-3 parallel subagents - **50-150 files:** 8-12 parallel subagents, batches of 10-15 - **150+ files:** scripted pattern removal for the rote cases only (frontmatter fields, phone numbers — machine-emitted shapes, per regex-discipline) + subagents for everything needing judgment ## Edge Cases - **Founders vs. employees:** founder/exec pages often carry the most sensitive content (board dynamics, investor relationships, assessments of their own team). These need the most careful review. - **Meeting notes:** meeting pages referencing employee performance need the same treatment as people pages — they are in scope, not an afterthought. - **Cross-references:** after sanitizing people pages, check that no other page (meetings, companies, dailies) still references the removed content; `gbrain check-backlinks check` plus a grep for the removed section titles. - **Takes with attribution:** a take like "the user believes charlie-example is underperforming" reveals both the opinion and who holds it. Remove the entire take, not just the attribution. - **Aliases and nicknames:** grep for the person's short name and initials, not just the slug — candid content rarely uses full names. ## Dedup (sharp boundaries) - **[data-loss-gate](../data-loss-gate/SKILL.md)** — supplies the confirmation-card mechanics and the explicit-yes discipline; company-brainify is a specialized caller of it at BOTH destructive steps: Phase 3 (bulk strip + take/fact removal) and Phase 5 (history purge + force-push), each with a pre-filled card. A standalone "delete/purge/clean up X" intent routes to data-loss-gate; the personal→team sanitization WORKFLOW routes here. - **[publish](../publish/SKILL.md)** — outbound sharing of ONE page as encrypted self-contained HTML. company-brainify is whole-brain inbound team access. "Share this page" → publish; "share my brain with the team" → here. - **[maintain](../maintain/SKILL.md)** — structural health (orphans, backlinks, stale pages). maintain checks whether the brain is HEALTHY; company-brainify checks whether it is SAFE TO SHARE. "Check brain health" routes to maintain. - **frontmatter-guard (host-side)** — validates frontmatter SHAPE. company-brainify strips sensitive frontmatter FIELDS; run frontmatter-guard after a large pass to confirm what remains still parses. ## Contract This skill guarantees: - Both destructive steps fire the data-loss-gate confirmation card and wait for an explicit typed "yes"/"do it" BEFORE running: Phase 3 (bulk strip + take/ fact removal) and Phase 5 (history purge + force-push). This is a routing convention the agent must follow — nothing in the runtime mechanically blocks a skipped gate, which is why skipping it is the cardinal violation of this skill. - Phase 3 defaults to sanitizing a STAGING COPY of the scanned scope, leaving the personal brain's working tree untouched; in-place edits are reserved for re-auditing an existing shared brain. - The Phase 5 history purge (Steps 3+) runs only on the SHARED repo cloned to a work dir — never `sync.repo_path` — after (a) a mirror-clone backup exists and is verified, and (b) a restore-completeness check passes before the force-push. The personal brain's history is never rewritten. - The deletion log is written to the PERSONAL brain (`daily/`) or a local ops log, never into the shared repo. - The scan covers the full scope (people, meetings, dailies, companies, projects, analysis, takes, facts, back-links), never `people/` alone. - Nothing unscanned ships: the fresh-export path includes ONLY directories covered by the sanitization scan; everything else is excluded by default, and the Phase 4 verification greps run against the exported tree before the first push. - Sensitive fact rows are deleted from the page's Facts fence, re-synced, and the facts index reconciled (extract-facts sweep) with the removal verified via `gbrain recall --grep`, never merely expired — `gbrain forget` retains the row (struck through, served via `--include-expired`) and can never certify clean. - The history-purge filter list and its restore manifest both derive from the COMPLETE set of sanitized paths, never a subset. - Every strip decision is a per-file model judgment grounded in a full read; grep output is triage and verification only. - A verification pass (Phase 4 greps + retrieval checks) runs before any commit is pushed to the shared repo. - Confirmed purges are logged to `daily/notes/YYYY-MM-DD.md` under `## Data Deletions` with the backup path as the recovery line. - Routing matches the canonical triggers in the frontmatter. - Output written under the directories listed in `writes_to:` (edits in place, plus the daily/ deletion log). - Privacy contract preserved: no real names, no fork-specific filesystem path literals, no upstream-fork references. The full behavior contract is documented in the body sections above; this section exists for the conformance test. ## Output Format Three artifacts: 1. **The sanitization report** (every run, including report-only re-audits): ```markdown ## Brainify Report — YYYY-MM-DD - Scope: [N files scanned across people/, meetings/, daily/, ...] - Flagged: [M files with hits] (triage list attached) - Edited: [K files sanitized; T takes removed; F fact rows removed + re-synced + facts index reconciled] - Verification: [grep residuals: 0 confirmed-sensitive; retrieval checks: clean] - History: [not purged | fresh-export | purged after confirmed gate — backup at ] - Next re-audit: [date / cron slot] ``` 2. **The confirmation card** (Phases 3 and 5) — the pre-filled fenced card, presented before the bulk destructive edits (Phase 3) and before any history rewrite (Phase 5); the turn stops until the user answers. 3. **The deletion log entry** (post-purge only) — appended to the PERSONAL brain's `daily/notes/YYYY-MM-DD.md` (never the shared repo) per data-loss-gate Step 4. ## Anti-Patterns - ❌ Scanning only `people/` — meetings, dailies, and cross-references leak the same content - ❌ Sanitizing working-tree files and calling it done — history still carries every sensitive version - ❌ Exporting the whole repo into the team brain — the export ships ONLY scanned directories; nothing unscanned ships - ❌ Using `gbrain forget` as sanitization — forget expires (struck-through row retained, served via `--include-expired`); delete the fence row and re-sync instead - ❌ Purging history for a subset of the sanitized paths — the filter list derives from the complete scan scope, not just `people/` + `meetings/` - ❌ Running `git filter-repo` / force-push without the mirror-clone backup and the typed confirmation — the card comes BEFORE the rewrite, always - ❌ Running `git filter-repo` / force-push in `sync.repo_path` — the purge targets the SHARED repo cloned to a work dir; the personal brain's history is never rewritten - ❌ Stripping the personal brain in place when standing up a NEW team brain — sanitize a staging copy; the founder's private comp/performance notes stay - ❌ Bulk-editing files and removing takes/facts without the Phase 3 data-loss-gate card — destructive edits are gated too, not just the purge - ❌ Writing the deletion log into the shared repo — it names the sensitive paths and the backup location; log it to the PERSONAL brain - ❌ Treating grep as the sensitivity judge — patterns triage, the model reads and decides (regex-discipline) - ❌ Removing the attribution but keeping the take — the claim itself is the leak; remove the whole row - ❌ Bulk-editing 150 files without a 3-5 file test first (test-before-bulk) - ❌ Tightening grep patterns to eliminate false positives — confirm the hits manually instead; a "clean" scan from an over-fitted pattern is a false certificate - ❌ One clean pass with no re-audit — ingestion and enrichment re-accumulate sensitive content; schedule Phase 6 ## Dónde encaja - Categoría: [Seguridad](https://skillsagentes.com/categorias/seguridad.md) — Auditorías, revisión de dependencias, manejo de secretos y modelado de amenazas. - Creador: [garrytan](https://skillsagentes.com/creators/garrytan.md) — 134 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Otras skills del mismo repositorio - [Setup](https://skillsagentes.com/skills/garrytan/gbrain/setup.md): Configura GBrain con auto-aprovisionamiento de Supabase o PGLite, inyección en AGENTS.md y primera importación. - [Maintain](https://skillsagentes.com/skills/garrytan/gbrain/maintain.md): Chequeos de salud del brain: aplicación de back-links, auditoría de citas, validación de filing, detección de info obsoleta, páginas huérfanas y benchmarks. - [Schema Unify](https://skillsagentes.com/skills/garrytan/gbrain/schema-unify.md): Migra un brain de gbrain-base a la taxonomía de 14 tipos canónicos de gbrain-base-v2 usando gbrain onboard --check y el handler Minion unify-types. - [Retrieval Reflex](https://skillsagentes.com/skills/garrytan/gbrain/retrieval-reflex.md): Cuándo y qué recuperar: abre la página del brain de una entidad relevante antes de responder desde memoria. - [Minion Orchestrator](https://skillsagentes.com/skills/garrytan/gbrain/minion-orchestrator.md): Skill unificado de Minions para jobs deterministas de shell y orquestación de subagentes LLM: cola durable, observable y controlable, más la doctrina de ejecución durable para operaciones largas. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)