/bedrock:sync — Vault Synchronization
Plugin Paths
Entity definitions and templates are in the plugin directory, not in the vault root. Use the "Base directory for this skill" provided at invocation to resolve paths:
- Entity definitions:
<base_dir>/../../entities/ - Templates:
<base_dir>/../../templates/{type}/_template.md - Plugin CLAUDE.md:
<base_dir>/../../CLAUDE.md(already injected automatically into context)
Where <base_dir> is the path provided in "Base directory for this skill".
Vault Resolution
Resolve which vault to sync. This skill can be invoked from any directory.
Step 1 — Parse --vault flag:
Check if the input arguments include --vault <name>. If found, extract the vault name and remove it from the arguments before parsing --people or --github.
Step 2 — Resolve vault path:
-
If
--vault <name>was provided: Read the vault registry at<base_dir>/../../vaults.json. Find the entry matching the name. If not found: error — "Vault<name>is not registered. Run/bedrock:vaultsto see available vaults." If found: setVAULT_PATHto the entry'spathvalue. Store the resolved vault name asVAULT_NAME. -
If no
--vaultflag — CWD detection: Read<base_dir>/../../vaults.json. Check if the current working directory is inside any registered vault path (CWD starts with a registered vault's absolute path). If multiple match, use the longest path (most specific). If found: setVAULT_PATHto the matching vault'spath. Store its name asVAULT_NAME. -
If CWD detection fails — default vault: From the registry, find the vault with
"default": true. If found: setVAULT_PATHto the default vault'spath. Store its name asVAULT_NAME. -
If no resolution: Error — "No vault resolved. Available vaults:" followed by the registry listing. "Use
--vault <name>to specify, or run/bedrock:setupto register a vault."
Step 3 — Validate vault path:
test -d "<VAULT_PATH>" && echo "exists" || echo "missing"
If missing: error — "Vault path <VAULT_PATH> does not exist on disk. Run /bedrock:setup to re-register."
Step 4 — Read vault config:
cat <VAULT_PATH>/.bedrock/config.json 2>/dev/null
Extract language, git.strategy, and other relevant fields for use in later phases.
From this point forward, ALL vault file operations use <VAULT_PATH> as the root.
- Entity directories:
<VAULT_PATH>/actors/,<VAULT_PATH>/people/, etc. - Git operations:
git -C <VAULT_PATH> <command> - When delegating to
/bedrock:preserve, pass--vault <VAULT_NAME>
Overview
This skill synchronizes the vault with external sources. It operates in three modes:
| Mode | Flag | Description |
|---|---|---|
| Sources (default) | (none) | Re-synchronizes entities with a populated sources field |
| People | --people | Scans actor repositories and identifies active contributors |
| GitHub | --github | Detects activity in repos and correlates PRs with topics/projects |
Routing
Analyze the argument passed by the user:
- If argument contains
--people→ go to Mode: Sync People (below) - If argument contains
--github→ go to Mode: Sync GitHub (below) - Otherwise → go to Mode: Sync Sources (default) (below)
Note: If no argument is passed, or the argument does not contain recognized flags, execute the default mode (Sync Sources).
Mode: Sync Sources (default)
Overview
This skill scans the sources field of all vault entities, deduplicates by URL,
fetches updated content from each external source, compares with existing entities
in the vault (incremental diff), and delegates all changes to /bedrock:preserve for centralized writing.
/bedrock:sync does NOT write entities directly — all entity writing goes through /bedrock:preserve.
After re-sync, /bedrock:preserve updates synced_at in the sources field of affected entities.
/bedrock:sync does NOT ingest new sources — for that, use /bedrock:learn.
You are an execution agent. Follow the phases below in order, without skipping steps.
Phase 0 — Synchronize the Vault
Execute:
git -C <VAULT_PATH> pull --rebase origin main
If the pull fails:
- No remote configured: warn "No remote configured. Working locally." and proceed.
- Pull conflict:
git -C <VAULT_PATH> rebase --abortand warn the user. Do NOT proceed without resolving. - Otherwise: proceed.
Phase 1 — Collect Syncable Sources
Provenance is recorded in the sources field of each entity's frontmatter.
Scan all entities to collect unique URLs.
- Use Grep to find entities with a non-empty
sourcesfield:Grep pattern "^sources:" in directories: actors/, people/, teams/, topics/, discussions/, projects/, fleeting/ - For each file found, use Read to extract the
sourcesfield from the YAML frontmatter. Each entry has:{url, type, synced_at} - Build URL → entities map:
Deduplicate by URL. For each unique URL, record all entities that reference it:
{ "https://mycompany.atlassian.net/...": { type: "confluence", synced_at: "2026-04-09", entities: ["actors/billing-api.md", "topics/2026-04-feature-x.md"] }, "https://github.com/acme-corp/billing-api": { type: "github-repo", synced_at: "2026-04-10", entities: ["actors/billing-api.md"] } } - Filter syncable sources:
- Keep only URLs with
typein (confluence,gdoc,github-repo,markdown) - Ignore URLs with
type=csvormanual(log: "URL X ignored — non-syncable type")
- Keep only URLs with
- Store the list of syncable URLs with their entity maps
Report: "Phase 1: N entities with sources, M unique URLs found, K syncable, J ignored (non-syncable type)."
Phase 2 — Re-read Sources
For each syncable source, fetch updated content:
2.1 Confluence
For sources with source_type: confluence:
- Read the internal fetcher at
<base_dir>/../confluence-to-markdown/SKILL.md - Follow its instructions to parse the URL, choose layer (MCP → API → browser), and extract content
- The fetcher returns Markdown content and page title
2.2 Google Docs
For sources with source_type: gdoc:
- Read the internal fetcher at
<base_dir>/../gdoc-to-markdown/SKILL.md - Follow its instructions to parse the URL, detect document type, choose layer (MCP → API/public export → browser), and extract content
- The fetcher returns Markdown content and document metadata
2.3 GitHub Repository
For sources with source_type: github-repo:
- Extract
owner/repofrom the URL (path segments aftergithub.com/) - Use GitHub MCP directly (NOT via subagent — MCP permissions are not inherited):
mcp__plugin_github_github__get_file_contents→ read the repo's README.mdmcp__plugin_github_github__list_commits→ last 10 commitsmcp__plugin_github_github__list_pull_requests→ last 5 PRs (state=all, sort=updated)
- Compile everything into a single markdown text
Best-effort: If any MCP call fails, continue with what was obtained. Do NOT block the sync.
2.4 Local Markdown
For sources with source_type: markdown:
- Extract the path from the
urlfield - Use Read to read the file directly
- If the file does not exist: log and skip
2.5 Error handling
- If reading a source fails (MCP unavailable, broken URL, missing file):
- Log the error: "Source X failed — reason"
- Continue with remaining sources
- Do NOT abort the entire execution for one source
Report: "Phase 2: N sources read successfully, M failed (list)."
Phase 3 — Incremental Diff + Entity Extraction
3.1 Load entity definitions
Use Read to read ALL entity definition files from the plugin (see "Plugin Paths" section):
<base_dir>/../../entities/*.md
These files define what each entity type is, when to create, and how to disting