mcpField
C
company-brainify

company-brainify

github.com/garrytan安全31.3k57 次安装今天更新
代码仓库

关于 company-brainify

company-brainify 是用于将个人 gbrain 整理为共享团队脑的技能,也可审计已有团队脑。它检查页面、takes、facts 和历史记录,指导逐步清理敏感信息并验证结果。

主要功能

  1. 01检索与结构化扫描敏感内容
  2. 02清理页面、takes 和 facts
  3. 03保留专业信息并移除敏感内容
  4. 04清理后检查反向链接
  5. 05分批测试并验证清理结果

适用场景

  1. 01从创始人个人脑建立团队脑
  2. 02审计共享脑中的敏感信息
  3. 03团队成员接入前验证脑内容
  4. 04定期清理重新积累的敏感数据

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/garrytan/gbrain --skill company-brainify

安装后在 Claude Code 中输入/company-brainify确认已加载。

附带文件routing-eval.jsonl

详细介绍

company-brainify — 个人大脑 → 团队大脑净化

**约定:**参见 conventions/brain-first.md — 通过大脑自身的检索进行发现,而不是凭猜测查找文件系统。 下方的 grep 流水线用于初步筛查;gbrain query 能找到关键词模式遗漏的内容。

**约定:**参见 conventions/test-before-bulk.md — 先净化 3-5 个文件,亲自阅读输出,然后再扩大范围。糟糕的批量 净化比不净化更糟:看起来做完了,实际上却没有。

**约定:**参见 conventions/regex-discipline.md — “这是否敏感?”需要判断,因此由模型逐个文件决定。grep 模式是经过实践验证的 筛查/核验工具,绝不能充当裁判。

**约定:**参见 _brain-filing-rules.md — 编辑应留在页面现有目录中;删除日志文件按日期命名,存放在 daily/ 下。

问题

个人大脑会不断积累各种内容——公司知识、会议记录、内部评估、 薪酬详情、管理策略,以及对共事人员的坦率看法。当你从个人大脑 建立共享团队大脑时(团队挂载拓扑参见 docs/architecture/brains-and-sources.md), 这些内容都必须清除。知识很有价值;敏感元数据却是负担。

仅清理工作树中的文件远远不够:git 历史仍然保留着每个 净化前的版本,而 gbrain 的 takes/facts 中也有页面正文之外的评估性说法。这项技能会处理全部三个方面——页面、 takes/facts 和历史记录。

适用场景

连接或索引现有公司仓库而不编辑它,并不属于净化。对于“连接我们的公司大脑”或“导入现有公司大脑”,请使用 migrate(主机端)公司工作流。在受信任的大脑主机上,先运行 gbrain sources inspect <path> --profile company-brain;并按照 docs/guides/company-brain-ingestion.md 进行目标预览和审批。 不要仅仅为了让现有仓库可搜索,就剥除元数据或清除历史记录。

  • 从创始人/高管的个人大脑建立共享公司大脑
  • 审计现有共享大脑,检查是否包含不应存在的敏感内容
  • 将新团队成员接入必须先确认已清理干净的大脑仓库
  • 定期清理重新积累敏感数据的共享大脑

要移除的内容

始终移除(不可妥协)
类别示例
内部评分/评级score:、rating:、skill:,或任何垂直领域特定的 *_score: frontmatter 字段;对个人的任何数值评级
薪酬工资、股权、carry、期权授予、薪酬变动、留任方案
绩效评估关于员工的优缺点章节、“有风险”标记、表现不佳的描述、“接手额外工作”的说法
离职/留任谁在考虑离职、谁被说服留下、离职传闻、留任谈话
管理策略如何管理某人的章节、“艰难谈话”记录、职责范围/职称管理计划
内部政治动态谁不喜欢谁、谁对谁感到紧张、对立关系、权力动态
个人身份信息电话号码、个人电子邮件地址、家庭住址、家人或医疗详情、个人法律事务、个人生活详情
Takes/facts任何涉及上述类别的 take 或 fact——绩效、薪酬、留任、弱点、管理风险。Facts 行应从页面的 Facts fence 中删除,绝不能仅用 gbrain forget 将其标记为过期
始终保留
类别示例
职业身份姓名、职位、头衔、工作邮箱、LinkedIn
正在构建的内容当前项目、产品工作、技术贡献
职业历程过往任职公司、教育经历、职业背景(公开信息)
职业理念他们对技术、战略、产品理念的看法
工作时间线会议出席情况、项目里程碑、发布(事实性内容,不含评价)
技能/专业知识技术能力、领域知识

扫描范围——不限于 people/

敏感内容泄漏的范围远超 people 页面。扫描范围如下:

  • people/ — 主要范围(frontmatter 字段、评估章节)
  • meetings/ — 含有坦率评价的会议记录和纪要
  • daily/ — 提及薪酬/绩效/留任对话的每日笔记
  • companies/、projects/、analysis/ — 对已移除内容的交叉引用
  • 观点 — 页面观点围栏中的评价性主张(gbrain takes search)
  • 事实 — 热记忆事实(gbrain recall --grep)
  • 反向链接 — 编辑后,gbrain check-backlinks check 可确认没有页面 仍指向已移除的章节

只检查 people/ 的流程,无法确认知识库中不再有信息泄漏。

流程

以下所有路径均相对于知识库仓库根目录:

BRAIN="$(gbrain config get sync.repo_path)"
cd "$BRAIN"
阶段 1:确定范围(优先检索)
  1. 检索发现——混合搜索能够发现关键词模式无法捕捉的、带有判断性质的内容:

    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"
    

    将每个返回的 slug 解析为相对于仓库的文件路径,并将路径写入 /tmp/brainify-scope.txt(每行一个)。此文件是范围清单;下方的结构化检查会将内容追加到其中——流程后续任何步骤都不得清空此文件,否则检索发现的页面会被 悄然移出范围。

  2. 结构化发现——属于该公司的人员文件,以及更广扫描范围内的关键词命中项:

    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. 与公司的公开人员页面(网站、 LinkedIn)交叉核对,以发现采用不同 frontmatter 约定的文件。

  4. 计数:wc -l /tmp/brainify-scope.txt

阶段 2:敏感性分类

按命中密度优先处理(使用可移植的 grep -E;不要使用 \b——BSD 和 GNU 的行为不同):

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

命中较多的文件需要进行完整的判断审查。零命中文件可能只需移除 frontmatter 字段,但仍须阅读(正则表达式负责初筛,模型负责判断)。

阶段 3:清理(优先使用暂存副本;先测试,再并行处理)

阶段 3 具有破坏性:它会清除多个文件中的内容、移除观点,并删除事实行。以下两条规则适用于此阶段。

先选择目标——复制,不要修改个人知识库。

  • 新建团队知识库(默认,优先):清理扫描目录的暂存副本,绝不要直接修改个人知识库。创始人的个人知识库本来就应该保留薪酬、绩效和坦诚笔记——从个人工作树中清除这些内容会破坏宝贵的私人数据。将阶段 1 的范围复制到一个持久的暂存目录,并在该副本中编辑。阶段 5 步骤 0 从暂存副本导出。影响范围:个人知识库不受影响。

    # 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
    
  • 重新审计现有共享知识库:共享知识库就是目标,因此要直接在共享仓库中编辑(切换到共享仓库目录,绝不要使用个人的 sync.repo_path)。事实行的移除和重新同步都针对共享源的数据库。

**在开始批量破坏性编辑之前,先触发 data-loss-gate 确认卡片。**两种目标都会产生破坏性影响(复制路径会从将交付给团队的目录树中移除内容;原地修改路径会从正在使用的知识库中移除内容)。阶段 3 的预填内容:

⚠️ DATA DELETION — Confirmation Required

What: strip sensitive content, remove takes, and delete fact rows across
      [N files] in [STAGING COPY at <path>  |  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)

按 data-loss-gate 的要求,必须键入 "yes" 或 "do it";"ok" 或 "sure" 不算同意。

按照先测试再批量处理的原则:先处理 3-5 个文件,查看结果,然后再扩大范围。对于较大的集合(50 个以上文件),按每组 10-12 个文件分批,并启动并行子 Agent。每个文件:

  1. 完整阅读文件
  2. 移除所有符合“始终清除”类别的内容
  3. Frontmatter:彻底删除评级/薪酬字段所在行
  4. 章节:移除整个章节(评估中的弱点、团队动态、管理策略)
  5. 观点和事实围栏:移除所有涉及敏感类别的完整行——像“alice-example 认为 charlie-example 表现不佳”这样的观点,会同时泄露意见和持有该意见的人;应移除整行,绝不要只删除归属信息
  6. 行内提及:精准编辑句子/段落
  7. 将清理后的文件写回

**决策规则:**仅需移除少数几个章节时,使用 Edit 精准编辑。只有在敏感内容遍布全文、难以分离时,才使用 Write 重写整个文件。

事实:forget 不等于移除。gbrain forget <fact-id> 会使事实过期——该行仍会保留在页面的 Facts 围栏中并显示删除线,而且数据库仍会通过 --include-expired 提供该事实。过期事实是被保留,而非被删除。清理时,必须实际移除敏感事实行:先查找它们(gbrain recall --grep),再从页面的 Facts 围栏中删除该行(步骤 5),与处理敏感观点相同。对于原地修改的共享知识库,随后必须重新同步页面编辑内容(gbrain sync 会重新导入已编辑的页面),并协调事实索引——同步的收敛契约仅涵盖页面导入;下游事实提取明确解耦(src/commands/sync.ts,“CONVERGENCE CONTRACT”),因此在运行事实提取协调之前,数据库仍会提供已删除的行。触发协调(运行 gbrain sweep,或等待常驻服务中的 sweep),然后通过 gbrain recall --grep 确认该行确实已消失。事实索引尚未协调时,即使页面已编辑,检索仍可能泄露内容。仅执行 forget 绝不能证明知识库已清理干净。

编辑后:对于暂存副本路径,直接编辑副本中的 Markdown 来移除事实行(此时还没有可重新同步的在线数据库——团队数据库会在阶段 5 步骤 0 将导出内容转换为源时全新构建)。对于原地修改共享知识库路径,运行 gbrain sync,使页面内容与 Markdown 一致,然后按上述说明协调并验证事实索引。无论采用哪种方式,都要运行 gbrain check-backlinks check,检查是否仍有页面指向已移除的内容。

第 4 阶段:验证

重新运行第 2 阶段的初步筛查——被标记文件的数量应降至(接近)零。然后执行针对性 grep:

# 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

误报(例如 “carry the torch”)没关系——请逐一手动确认剩余匹配项,而不是收紧模式(正则表达式纪律)。

验证将要交付的树。 在暂存副本路径上,这些 grep 会针对已清理的 $STAGING 树运行(第 5 阶段的第 0 步会将其转换为导出内容)——个人工作树不会被交付,因此认证它毫无意义。若要对共享知识库进行原地重新审计,共享仓库的树就是将要交付的树,本次检查可照常进行。

然后进行最严格的检查——团队实际会使用的检索。针对已清理的知识库/源(当共享源与个人内容一起挂载时,使用 --source <team-source-id> 限定范围):

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

这些检索的结果必须全部为空,或只包含保留类别的内容。

第 5 阶段:提交并清除历史记录 — 需经确认

如果仓库包含历史记录,仅清理文件还不够:旧提交中仍包含敏感版本。

第 0 步 — 首选替代方案(非破坏性)。 建立新的团队仓库时,完全跳过历史重写:将第 3 阶段已清理的暂存树作为全新仓库,并使用全新的历史记录。个人仓库保留其完整历史记录和完整工作树,不作任何更改。

导出规则:未经扫描的内容一律不得交付。 由于第 3 阶段只将已扫描的目录复制到 $STAGING,暂存树中不会包含清理流程未读取的内容——仅包含指定内容的规则从结构上就能得到保证。切勿复制额外目录:所有扫描范围之外的内容(conversations/、originals/、sources/、inbox/)都必须排除。复制整个仓库是最典型的泄露方式——这会交付未经过任何流程检查的原始转录、原件和收件箱捕获内容。若要交付新目录,先将其加入扫描范围(第 1 至第 4 阶段),使其在经过清理后进入 $STAGING。

# 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"  # gbrain-allow-shared-tree-git: first commit of a fresh single-writer export repo
git remote add origin <TEAM_REPO_URL>
gbrain git commit-push --push-only

首次提交使用普通 git,因为 $STAGING 是全新的仓库,只有本次运行会写入。推送通过 gbrain git commit-push --push-only 执行:它会推送到 origin/main,如果推送未成功则会明确报错。如果退出码非零,请停止并告知用户错误内容:通常是 git_push_unavailable(检查团队仓库 URL 和凭据,然后重新运行),或者团队仓库已包含提交(此次导出需要空仓库;继续之前先询问用户)。切勿强制推送。

只有在共享仓库已存在且包含敏感历史记录时,才需要进行以下清除操作。

第 1 步 — 以共享仓库为目标,提交清理后的树,然后镜像克隆。 清除操作针对共享仓库,绝不能针对 sync.repo_path(个人知识库)——第 0 步承诺个人仓库保留完整历史记录,取决于此。将共享仓库克隆到持久工作目录,在下方所有步骤中都留在该目录内,并在进行任何操作前断言目标不是个人仓库。

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 <SHARED_REPO_URL> "$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; pushing it means
# the remote stops serving the sensitive current versions even if the purge
# below is declined. Only the sanitized directories are committed. On a
# non-zero exit stop: retry once on commit_lock_busy; on integrate_conflict
# someone changed the shared repo meanwhile, so ask the user before going on.
for d in people meetings daily companies projects analysis; do
  [ -d "$STAGING/$d" ] && rsync -a "$STAGING/$d/" "./$d/"   # or sanitize in place here
done
SANITIZED=""
for d in people meetings daily companies projects analysis; do [ -d "$d" ] && SANITIZED="$SANITIZED $d"; done
gbrain git commit-push -m "Sanitize: strip sensitive content before history purge" -- $SANITIZED

# 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; }

在展示确认卡之前,请验证镜像存在且可读取——这是卡片中关于可恢复性的说明依据。

第 2 步 — 停止。展示 data-loss-gate 确认卡并等待。 重写历史记录并强制推送是此技能中破坏性最大的操作:它会从远程永久丢弃所有已清除路径的旧版本。未收到卡片确认,绝不能执行。此操作的预填内容如下:

⚠️ 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)

按照 data-loss-gate 的要求,必须收到用户明确输入 "yes" 或 "do it"——"ok"、"sure"、"go ahead" 不算同意。如果用户提出问题,请先回答,再重新展示确认卡。此门禁是流程约定,并非运行时强制执行——gbrain 并不会以机制阻止执行 git filter-repo——这正是遵循此技能的 Agent 绝不能跳过确认步骤的原因。 步骤 3 — 清除(仅在明确输入 yes 后执行)。 需要 git filter-repo(git 未捆绑此工具;需单独安装)。仅在步骤 1 中的共享仓库工作目录运行此命令 (cd "$WORK/shared")。切勿在 sync.repo_path 中运行 git filter-repo 或 git push --force — 个人知识库的历史记录必须保持完整。 以下命令会复用步骤 1 中的 $WORK 和 $BACKUP_PATH;绝不会重新计算带日期的路径。

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 <SHARED_REPO_URL>   # 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/<d>" "<d>" 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  # gbrain-allow-shared-tree-git: the confirmed history purge of a private single-writer clone (data-loss-gate answered)

步骤 4 — 记录(写入个人知识库,绝不写入共享仓库)。 根据 data-loss-gate,将删除记录追加到 ## Data Deletions 下 — 但要写入 个人知识库的 $PERSONAL/daily/notes/YYYY-MM-DD.md(或本地运维 日志),绝不写入共享仓库。日志会列出清除的路径和 备份位置;如果记录在共享仓库中,这两项信息会让每位团队成员准确知道哪些路径包含敏感内容,以及预清理备份存放在哪里 — 审计记录就成了一张藏宝图。 记录:时间戳、清除的路径、提交数量,以及作为恢复信息的 $BACKUP_PATH。

强制推送后:

  • 所有现有克隆都必须重新克隆
  • 托管服务商可能会将无法访问的提交缓存一段时间(数月左右);如需立即移除,请使用服务商的敏感数据移除流程。对于私有/内部仓库,只要该 SHA 无法通过任何引用访问,通常就足够了
  • 同步游标可能指向已被改写掉的 SHA;如果下一次 gbrain sync 报错或回退到完整重新扫描,这表示游标正在恢复 — 如果未能恢复,请运行 gbrain doctor
  • 备份保留: 确认改写结果无误后(团队已重新克隆、同步已稳定,且未报告内容缺失),将镜像克隆备份保留在 ~/.gbrain/backups/ 中一段时间(默认约 30 天较为合理),然后删除 — 其中包含预清理历史记录,不应无限期累积: rm -rf ~/.gbrain/backups/shared-brain-history-backup-<date>.git (匹配模式必须与备份步骤创建的 shared-brain-history-backup-* 名称相符 — 模式不匹配会导致什么都不删除,并悄然让预清理历史记录永久保留)
  • 如果仓库配置了推送钩子或自动加固机制,在移交给团队之前,请重新确认远程仓库和钩子在改写后仍然正常

将仓库移交给团队 — 先标记为共享。 无论团队仓库是通过哪种方式生成的(步骤 0 中的全新历史导出,或清除后的强制推送),移交前都要设置已发布知识库的受众: gbrain config set brain.audience shared — 对团队知识库执行,绝不要对个人知识库执行。此标记声明这是公司/团队知识库,因此不会触发仅适用于个人知识库的环境记忆写回征求同意提示。如果团队成员会在此标记设置前为共享知识库运行 gbrain init(例如,新克隆后初始化自己的引擎),请让他们为这条命令加上前缀 GBRAIN_NO_ONBOARD_NUDGE=1 — 未设置标记的新知识库会被归类为个人知识库,而初始化时的提示只会触发一次,因此如果让它在此时触发,就既会询问错误的问题,也会消耗掉那个哨兵标记。

阶段 6:持续维护 — 定期重新审计

会议文字记录的摄取(坦诚评估)、提取内部数据的丰富化流水线,以及坦诚交流期间的手动写入,都会让敏感数据重新累积。一次干净的检查只是某个时点的快照,不代表持续保持干净。

建议: 安排每月重新审计一次(对于高摄取量知识库,每周一次),以仅报告模式重新运行阶段 1、2 和 4 — 扫描并标记,不做修改 — 在新命中项进入共享仓库前提交人工审核。按照 conventions/cron-via-minions.md 配置:cron 时段会提交后台任务(gbrain jobs submit),调度指南见 skills/cron-scheduler/SKILL.md,任务通道的路由方式见 skills/minion-orchestrator/SKILL.md。仅报告运行会写入发现摘要;由人工(或设有门控的后续运行)执行移除操作。

扩展说明

  • 少于 20 个文件: 单次顺序处理
  • 20–50 个文件: 使用 2–3 个并行子 Agent
  • 50–150 个文件: 使用 8–12 个并行子 Agent,每批处理 10–15 个文件
  • 150 个以上文件: 仅对机械性处理的情况使用脚本移除模式 (frontmatter 字段、电话号码——机器生成的格式,遵循 正则表达式规范),其余需要判断的内容交由子 Agent 处理

边缘情况

  • 创始人与员工: 创始人/高管页面通常包含最敏感的内容(董事会动态、投资者关系、对自己团队的评价)。这些内容需要最仔细的审查。
  • 会议记录: 提及员工绩效的会议页面需要按照人物页面的同等标准处理——这些页面也在范围内,不应被忽略。
  • 交叉引用: 清理人物页面后,检查其他页面(会议、公司、每日记录)是否仍引用已移除的内容;使用 gbrain check-backlinks check,并搜索已移除的章节标题。
  • 带有归属信息的观点: 像“用户认为 charlie-example 表现不佳”这样的观点,会同时泄露观点内容和持有该观点的人。应移除整条观点,而不只是归属信息。
  • 别名与昵称: 搜索此人的简称和姓名首字母,而不仅是 slug——坦率的内容很少使用全名。

功能边界(明确区分)

  • data-loss-gate — 提供确认卡片机制和明确同意规范;company-brainify 在两个破坏性步骤中都会调用它:Phase 3(批量剥离以及观点/事实移除)和 Phase 5(清除历史记录并强制推送),每个步骤都附带预填的卡片。独立的“删除/清除/清理 X”意图应路由至 data-loss-gate;个人→团队的清理工作流应路由至此处。
  • publish — 将单个页面作为加密、自包含的 HTML 对外分享。company-brainify 处理的是整个知识库的团队访问。“分享此页面” → publish;“与团队分享我的知识库” → 此处。
  • maintain — 结构健康状况(孤立项、反向链接、过时页面)。maintain 检查知识库是否健康;company-brainify 检查分享是否安全。“检查知识库健康状况”应路由至 maintain。
  • frontmatter-guard(宿主端) — 验证 frontmatter 的结构。company-brainify 会剥离敏感的 frontmatter 字段;完成大规模处理后运行 frontmatter-guard,确认剩余内容仍能正确解析。

合约

此技能保证:

  • 两个破坏性步骤都会触发 data-loss-gate 确认卡,并在执行前等待用户明确输入“yes”/“do it”:Phase 3(批量清除 + 移除 take/fact)和 Phase 5(清除历史记录 + 强制推送)。这是 Agent 必须遵守的路由约定——运行时不会以机制阻止跳过确认门,因此跳过确认门是违反此技能的首要行为。
  • Phase 3 默认对已扫描范围的临时副本进行清理,不改动个人知识库的工作树;仅在重新审计现有共享知识库时才允许就地编辑。
  • Phase 5 的历史记录清除(步骤 3 及之后)只对克隆到工作目录中的共享仓库执行——绝不对 sync.repo_path 执行——且必须先 (a) 创建并验证镜像克隆备份,以及 (b) 在强制推送前通过完整性恢复检查。个人知识库的历史记录绝不重写。
  • 删除日志写入个人知识库(daily/)或本地运维日志,绝不写入共享仓库。
  • 扫描必须覆盖完整范围(people、meetings、dailies、companies、projects、analysis、takes、facts、back-links),绝不只扫描 people/。
  • 未扫描的内容不得发布:新导出路径仅包含经清理扫描覆盖的目录;默认排除其他所有内容;并且首次推送前,Phase 4 验证 grep 必须针对导出树运行。
  • 从页面的 Facts 区块中删除敏感事实行、重新同步,并通过 extract-facts 扫描协调 facts 索引;使用 gbrain recall --grep 验证已移除,绝不能仅使其过期——gbrain forget 会保留该行(划掉但仍可通过 --include-expired 返回),因此绝不能据此确认内容已清理干净。
  • 历史记录清除过滤列表和恢复清单都必须根据完整的已清理路径集合生成,绝不能使用子集。
  • 每项清除决策都必须基于完整阅读文件后作出逐文件模型判断;grep 输出仅用于分类筛查和验证。
  • 将任何提交推送到共享仓库前,必须先运行验证流程(Phase 4 grep + 检索检查)。
  • 已确认的清除操作须记录到 daily/notes/YYYY-MM-DD.md 的 ## Data Deletions 下,并以备份路径作为恢复行。
  • 转为共享用途的知识库在交接时须标记 brain.audience=shared,且绝不收到启用环境写回的提示——此类同意询问仅适用于个人知识库。
  • 路由与 frontmatter 中的规范触发条件一致。
  • 输出写入 writes_to: 中列出的目录(就地编辑,以及 daily/ 删除日志)。
  • 保持隐私合约:不得包含真实姓名、特定分支的文件系统路径字面量或上游分支引用。

完整行为合约已在上文各正文部分中说明;本节用于一致性测试。

输出格式

三个产物:

  1. 清理报告(每次运行都生成,包括仅报告的重新审计):
## 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 <path>]
- Next re-audit: [date / cron slot]
  1. 确认卡(Phase 3 和 Phase 5)——预填充的围栏卡片,须在批量破坏性编辑(Phase 3)前以及任何历史记录重写(Phase 5)前展示;在用户回复前不得继续。
  2. 删除日志条目(仅在清除后)——根据 data-loss-gate Step 4,追加到个人知识库的 daily/notes/YYYY-MM-DD.md(绝不写入共享仓库)。

失败时的处理

出现任何 gbrain 错误 code、退出代码、[AGENT] 块或通知块时,请遵循Agent 操作员协议。此技能的特定要求:

  • 批量脱敏或删除需要数据丢失关卡卡片;如果 CLI 以代码 3 退出或要求确认,请停止操作,并先向用户展示可恢复性卡片。
  • 检索优先的范围扫描结果为空,并附有降级通知:仅靠关键词搜索会漏计敏感页面。请保留结构化扫描,并告知用户此次扫描仅基于关键词。
  • forget / put_page 返回 write_pending(退出代码 10)时:轮询 gbrain write-request <request_id>;在回执提交前,不要报告页面已完成脱敏。

反模式

  • ❌ 只扫描 people/ —— 会议、每日记录和交叉引用中也会泄露相同内容
  • ❌ 只对工作树文件进行脱敏就称大功告成 —— 历史记录仍保留着所有敏感版本
  • ❌ 将整个仓库导出到团队知识库 —— 导出只会包含已扫描的目录;未扫描的内容不会导出
  • ❌ 将 gbrain forget 用作脱敏手段 —— forget 会使内容过期(保留删除线标记的行,并通过 --include-expired 提供);请改为删除围栏行并重新同步
  • ❌ 仅清除部分已脱敏路径的历史记录 —— 过滤列表应根据完整扫描范围生成,而非仅根据 people/ + meetings/
  • ❌ 未进行镜像克隆备份且未获得明确确认,就运行 git filter-repo / force-push —— 必须始终先展示卡片,再重写历史
  • ❌ 在 sync.repo_path 中运行 git filter-repo / force-push —— 清除操作针对的是克隆到工作目录中的共享仓库;绝不能重写个人知识库的历史记录
  • ❌ 建立新的团队知识库时直接清理个人知识库 —— 请脱敏暂存副本;创始人的私人薪酬/绩效记录必须保留
  • ❌ 批量编辑文件并删除观点/事实,却不先展示 Phase 3 的数据丢失关卡卡片 —— 破坏性编辑也必须设置关卡,不只是历史清除操作
  • ❌ 将删除日志写入共享仓库 —— 日志会列出敏感路径和备份位置;请将其记录到个人知识库
  • ❌ 将 grep 当作敏感性判定依据 —— 模式只用于分流,模型负责读取并判断(regex-discipline)
  • ❌ 删除归属信息却保留观点 —— 泄露的是声明本身;请删除整行
  • ❌ 未先测试 3-5 个文件就批量编辑 150 个文件(test-before-bulk)
  • ❌ 为消除误报而收紧 grep 模式 —— 应改为手动确认命中结果;用过度拟合的模式得到的“干净”扫描结果只是假证明
  • ❌ 只进行一次干净的扫描,不再审计 —— 摄取和丰富过程会再次引入敏感内容;请安排 Phase 6

评论

支持 Markdown