# Sync

> >

- **Type:** Skill
- **Install:** `agentstack add skill-iurykrieger-claude-bedrock-sync`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [iurykrieger](https://agentstack.voostack.com/s/iurykrieger)
- **Installs:** 0
- **Category:** [Productivity](https://agentstack.voostack.com/c/productivity)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [iurykrieger](https://github.com/iurykrieger)
- **Source:** https://github.com/iurykrieger/claude-bedrock/tree/main/skills/sync
- **Website:** https://claude-bedrock.vercel.app

## Install

```sh
agentstack add skill-iurykrieger-claude-bedrock-sync
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# /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: `/../../entities/`
- Templates: `/../../templates/{type}/_template.md`
- Plugin CLAUDE.md: `/../../CLAUDE.md` (already injected automatically into context)

Where `` 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 `. If found, extract the vault name and remove it from the arguments before parsing `--people` or `--github`.

**Step 2 — Resolve vault path:**

1. **If `--vault ` was provided:**
   Read the vault registry at `/../../vaults.json`. Find the entry matching the name.
   If not found: error — "Vault `` is not registered. Run `/bedrock:vaults` to see available vaults."
   If found: set `VAULT_PATH` to the entry's `path` value. Store the resolved vault name as `VAULT_NAME`.

2. **If no `--vault` flag — CWD detection:**
   Read `/../../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: set `VAULT_PATH` to the matching vault's `path`. Store its name as `VAULT_NAME`.

3. **If CWD detection fails — default vault:**
   From the registry, find the vault with `"default": true`.
   If found: set `VAULT_PATH` to the default vault's `path`. Store its name as `VAULT_NAME`.

4. **If no resolution:**
   Error — "No vault resolved. Available vaults:" followed by the registry listing.
   "Use `--vault ` to specify, or run `/bedrock:setup` to register a vault."

**Step 3 — Validate vault path:**
```bash
test -d "" && echo "exists" || echo "missing"
```
If missing: error — "Vault path `` does not exist on disk. Run `/bedrock:setup` to re-register."

**Step 4 — Read vault config:**
```bash
cat /.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 `` as the root.**
- Entity directories: `/actors/`, `/people/`, etc.
- Git operations: `git -C  `
- When delegating to `/bedrock:preserve`, pass `--vault `

---

## 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:

1. If argument contains `--people` → go to **Mode: Sync People** (below)
2. If argument contains `--github` → go to **Mode: Sync GitHub** (below)
3. 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:
```bash
git -C  pull --rebase origin main
```

If the pull fails:
- No remote configured: warn "No remote configured. Working locally." and proceed.
- Pull conflict: `git -C  rebase --abort` and 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.

1. Use Grep to find entities with a non-empty `sources` field:
   ```
   Grep pattern "^sources:" in directories: actors/, people/, teams/, topics/, discussions/, projects/, fleeting/
   ```
2. For each file found, use Read to extract the `sources` field from the YAML frontmatter.
   Each entry has: `{url, type, synced_at}`
3. **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"]
     }
   }
   ```
4. **Filter syncable sources:**
   - Keep only URLs with `type` in (`confluence`, `gdoc`, `github-repo`, `markdown`)
   - Ignore URLs with `type` = `csv` or `manual` (log: "URL X ignored — non-syncable type")
5. 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`:

1. Read the internal fetcher at `/../confluence-to-markdown/SKILL.md`
2. Follow its instructions to parse the URL, choose layer (MCP → API → browser), and extract content
3. The fetcher returns Markdown content and page title

### 2.2 Google Docs

For sources with `source_type: gdoc`:

1. Read the internal fetcher at `/../gdoc-to-markdown/SKILL.md`
2. Follow its instructions to parse the URL, detect document type, choose layer (MCP → API/public export → browser), and extract content
3. The fetcher returns Markdown content and document metadata

### 2.3 GitHub Repository

For sources with `source_type: github-repo`:

1. Extract `owner/repo` from the URL (path segments after `github.com/`)
2. Use GitHub MCP directly (NOT via subagent — MCP permissions are not inherited):
   - `mcp__plugin_github_github__get_file_contents` → read the repo's README.md
   - `mcp__plugin_github_github__list_commits` → last 10 commits
   - `mcp__plugin_github_github__list_pull_requests` → last 5 PRs (state=all, sort=updated)
3. 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`:

1. Extract the path from the `url` field
2. Use Read to read the file directly
3. 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):
`/../../entities/*.md`
These files define what each entity type is, when to create, and how to distinguish them.
Internalize these definitions — you will use them to classify content.

### 3.2 Catalog existing entities

Use Glob to list all files in each entity directory (excluding `_template.md`):
- `/actors/*.md`
- `/people/*.md`
- `/teams/*.md`
- `/topics/*.md`
- `/discussions/*.md`
- `/projects/*.md`
- `/fleeting/*.md`

For each file found:
- Extract the filename without extension (e.g.: `billing-api`)
- Use Read to extract the `name` (or `title`) and `aliases` fields from the YAML frontmatter
- Store: `{filename, name, aliases, type}` for matching

### 3.3 Analyze content and detect changes

For each source successfully read in Phase 2:

1. **Identify entities mentioned in the updated content:**
   - For each entity cataloged in Phase 3.2, check if the filename, name, or alias appears in the content
   - Match rules:
     - Normalize for comparison: lowercase, no accents, no hyphens
     - Partial match acceptable for compound names (e.g.: "billing api" matches "billing-api")
     - Do NOT match substrings of 3 letters or fewer (e.g.: "api" does NOT match "billing-api")
     - Do NOT match generic words (e.g.: "company", "service", "system")

2. **Compare with the source's `entities_generated`:**
   - Entity in content AND already in vault → candidate for `update` (if there is new info in the content)
   - Entity in content but NOT in vault → candidate for `create`
   - Entity in `entities_generated` but NOT in updated content → **keep** (do not delete)

3. **Classify new entities:**
   - For `create` candidates, consult the entity definitions:
     - "When to create" section → positive criteria
     - "When NOT to create" section → exclusion criteria
     - "How to distinguish from other types" section → disambiguation

   > **Projects:** `project` is a valid type in extraction. When classifying new entities,
   > pay special attention to signals of initiatives with closed scope (deadline, deliverables,
   > focal points). Consult `entities/project.md` for creation criteria. An excerpt that
   > mentions migration with a deadline and responsible person is probably a project, not a topic.

4. **Record** for each detected entity:
   - Type (actor, person, team, topic, discussion, project)
   - Canonical name (filename or suggested slug)
   - Action: `create` or `update`
   - Extracted info: excerpt of the content where it appears
   - Source of origin: source slug

Report: "Phase 3: N entities detected (P creates, Q updates) across M sources."

---

## Phase 4 — Consolidated Confirmation

**REQUIRED:** Before creating/updating any entity, present a SINGLE list
with all changes from ALL sources:

```
## Sync — Proposed Changes

| # | Source | Type | Name | Action | Info |
|---|---|---|---|---|---|
| 1 | roadmap-26q1 | topic | 2026-04-feature-x | create | New topic mentioned |
| 2 | eventos-cobranca | actor | webhook-receiver | update | Description updated |
| ... | ... | ... | ... | ... | ... |

Total: N creates, M updates across P sources.
Confirm? (yes/no/adjust)
```

- **yes**: proceed to Phase 5
- **no**: abort with "Sync cancelled. No entities modified."
- **adjust**: ask what to adjust, modify list, re-present

**If no changes detected in any source:**
- Report: "No changes detected in any source. Vault is already up to date."
- Skip to Phase 6 (update `last_synced` anyway)

**Do NOT proceed without explicit user confirmation.**

---

## Phase 5 — Delegate to /bedrock:preserve

### 5.1 Compile structured list

Build the entity list in the format accepted by `/bedrock:preserve`:

```yaml
entities:
  - type: topic
    name: "2026-04-feature-x"
    action: create
    content: "relevant excerpt from content extracted in Phase 3..."
    relations:
      actors: ["actor-slug-1"]
      people: ["person-slug-1"]
    source: "confluence"
  - type: actor
    name: "webhook-receiver"
    action: update
    content: "new context extracted in Phase 3..."
    source: "github-repo"
```

**Compilation rules:**
- `type` and `name`: extracted from Phase 3
- `action`: `create` or `update` as identified
- `content`: excerpt of the source content that justifies the entity
- `relations`: infer relationships between entities in the list (if A mentions B, include B in A's relations)
- `source`: use the `source_type` of the originating source

### 5.2 Invoke /bedrock:preserve

Use the Skill tool to invoke `/bedrock:preserve --vault ` passing the structured list as argument.
The `--vault ` flag ensures preserve writes to the same vault.

`/bedrock:preserve` handles:
- Textual matching with existing entities
- Creation of new entities following templates
- Updating existing entities (merge/append-only)
- Bidirectional linking (wikilinks)
- Git commit of entities

### 5.3 Await result

`/bedrock:preserve` returns:
- List of created/updated entities
- Commit hash (if there was a commit)
- Any errors or warnings

Record the result for use in the final report (Phase 7).

---

## Phase 6 — Update synced_at in Entities

After re-sync of each URL, `/bedrock:preserve` has already updated the entities with new content.
Additionally, for each URL processed successfully, pass `source_url` and `source_type`
to `/bedrock:preserve` so it updates `synced_at` in the `sources` field of each mapped entity.

The URL → entities map (built in Phase 1) indicates which entities need
`synced_at` updated for each re-synced URL.

> **Note:** `/bedrock:preserve` already handles the entity commit. `/bedrock:sync` does NOT make a separate commit.

---

## Phase 7 — Report

Present to the user:

```
## Report

| Metric | Value |
|---|---|
| Sources found | N |
| Sources synchronized | N |
| Sources ignored (type) | N |
| Sources with error | N |
| Entities created | N |
| Entities updated | N |

### Per source
| Source | Type | Entities | Status |
|---|---|---|---|
| roadmap-26q1 | confluence | 3 creates, 2 updates | ✅ |
| acme-corp-billing-api | github-repo | 0 creates, 1 update | ✅ |
| manual-notes | manual | — | ⏭️ ignored |
| broken-source | confluence | — | ❌ error (reason) |

### Git
- Commit (entities): 
- Commit (sources): vault: syncs N sources [source: sync]
- Push: ✅ success / ❌ failed (reason)

### Suggestions
- [sources with errors that can be fixed]
- [entities mentioned in content but not created, if any]
```

---

## Critical Rules

| # | Rule |
|---|---|
| 1 | **NEVER write entities directly** — all entity writing goes through `/bedrock:preserve` |
| 2 | **NEVER create sources** — `/bedrock:sync` only processes URLs already registered in entities' `sources` field |
| 3 | **NEVER delete entities** — entities absent from updated content are kept |
| 4 | **ALWAYS confirm** consolidated proposal with user before executing (Phase 4) |
| 5 | **Best-effort for external sources** — never block due to unavailable MCP or broken URL |
| 6 | **MCP in main context** — do NOT use subagents for GitHub/Atlassian MCP calls |
| 7 | **csv and manual sources are ignored** — static types with no URL to re-fetch |
| 8 | **Maximum 2 push attempts** — after that, abort and inform |
| 9 | **Sensitive data** — NEVER include credentials, tokens, passwords, PANs, CVVs |
| 10 | **Frontmatter keys in English**, values in the vault's configured language |
| 11 | **Bare wikilinks** — `[[name]]`, never `[[dir/name]]` |

---
---

# Mode: Sync People (--people)

Skill that populates `people/` from recent commits in repositories listed in `actors/`.

**You are an execution agent.** Follow the phases below in order, without skipping steps.
Do not make git commit/push. Do not update `topics/` or `actors/`. Do not read CLAUDE.md from repositories.

---

## Phase 1 — Actor collection

1. Use Glob to list all files `/actors/*.md`
2. Exclude `/actors/_template.md`
3. For each file, use Read to extract from the YAML frontmatter:
   - `repository` — GitHub URL (e.g.: `https://github.com/acme-corp/billing-api/`)
   - `team` — squad wikilink (e.g.: `[[squad-payments]]`)
   - `name` — canonical name of the actor (e.g.: `billing-api`)
4. Parse `owner/repo` from the URL: extract the two path segments after `github.com/`
5. **Skip** actors without a `repository` field, with an empty URL, or with a URL that does not contain `github.com`
6. Store the list of valid actors:

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [iurykrieger](https://github.com/iurykrieger)
- **Source:** [iurykrieger/claude-bedrock](https://github.com/iurykrieger/claude-bedrock)
- **License:** MIT
- **Homepage:** https://claude-bedrock.vercel.app

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-iurykrieger-claude-bedrock-sync
- Seller: https://agentstack.voostack.com/s/iurykrieger
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
