From dc9f990bddeee30b38660d3addb004623ac1a552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Mon, 20 Jul 2026 16:22:55 +0200 Subject: [PATCH] Clarify create/download/update/publish decision table for shared indexes Spell out explicitly, per run: check whether the shared index store already has a published index; if so, fetch it regardless of access level; a write-access user always continues to rebuild and publish back to that same store, and this is precisely what creates it there the first time the store is empty. A read-only user never rebuilds or publishes anything, whether or not the store already had content. Co-Authored-By: Claude Sonnet 5 --- .agents/skills/ckb-index-external/SKILL.md | 84 ++++++++++++++-------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/.agents/skills/ckb-index-external/SKILL.md b/.agents/skills/ckb-index-external/SKILL.md index ee06cd1..30d163a 100644 --- a/.agents/skills/ckb-index-external/SKILL.md +++ b/.agents/skills/ckb-index-external/SKILL.md @@ -27,9 +27,11 @@ Two refinements on top of that base design: - **Shared, pre-built indexes.** `source.yaml` can declare *where the already-built index lives* (a git repo, or a shared resource such as a - network path or another connector-reachable location), so a user doesn't - have to build the index from scratch — they just fetch what's already - there. + network path or another connector-reachable location). Every run checks + that location: if it already has an index, fetch it; if it doesn't yet, + a write-access user's run is what creates it there for the first time. + Either way, a read-only user just gets whatever's already there — they + never have to build the index from scratch themselves. - **Read vs. write access, per user, per source.** Building/refreshing an index from the live connector is gated by a **local, per-user** setting (`libs//source.local.yaml`, never committed) — read-only by @@ -118,32 +120,47 @@ this user is an admin for this one source; anything else (the field is **per connector-backed lib** — a user can be write-access for one source and read-only for another. -### Step 3 — Fetch a published index, if one is configured +### Step 3 — Check the shared index store, and fetch it if it exists -If `source.yaml` has an `index:` block, fetch/pull the latest published -index from `index.location` (per `index.store`: `git pull`/clone for -`git`, a plain file copy for a filesystem/network `shared` path, or the -matching connector tool for a `shared` location that needs one) and use it -to refresh `libs//{index.md,entities/,graph/,log.md}`. Do this -**regardless of this user's access level** — reading the published index -never requires write access, and it's exactly what lets a read-only user -skip building anything themselves. +If `source.yaml` has an `index:` block, check whether `index.location` +already has a published index (per `index.store`: a `git` remote with +commits/a reachable ref, or a filesystem/network/`shared` location with +files already in it): +- **It exists** → fetch/pull it (`git pull`/clone for `git`, a plain file + copy for a filesystem/network `shared` path, or the matching connector + tool for a `shared` location that needs one) and use it to refresh + `libs//{index.md,entities/,graph/,log.md}`. Do this **regardless + of this user's access level** — reading the published index never + requires write access, and it's exactly what lets a read-only user skip + building anything themselves. +- **It's empty / nothing published yet** → there's nothing to fetch. Don't + treat this as an error; it's the normal first-time state before anyone + with write access has run this. Continue to Step 4 — whether that turns + into "create it" or "nothing to report" depends entirely on this user's + access level. -If no `index:` block is configured, there's nothing to fetch — the index -(if any exists yet) already lives directly in `libs//`, same as -before. +If no `index:` block is configured at all, skip this check — the index (if +any exists yet) already lives directly in `libs//`, same as before. ### Step 4 — Decide whether to build or refresh from the live connector +This is the one place access level actually changes behavior: + - **Read-only** (the common case, and the default for anyone who hasn't - set `access: write` locally): stop here. Report what the fetched/existing - index already covers. If nothing has ever been indexed for this source - and this user is read-only, say so plainly — don't scan the live - connector on their behalf. Suggest asking whoever administers this - source to run it, or setting `access: write` locally if this user is - meant to be that admin. -- **Write access**: continue to Step 5 and actually build/refresh the - index from the live connector `location`. + set `access: write` locally): stop here, regardless of what Step 3 + found. Never touch the live connector on a read-only user's behalf. + - If Step 3 fetched something (or one already lived in `libs//` + with no `index:` block): report what it covers. + - If nothing exists anywhere yet (Step 3 found the shared store empty, + or there's no `index:` block and `libs//` is empty too): say so + plainly, and suggest asking whoever administers this source to run it, + or setting `access: write` locally if this user is meant to be that + admin. +- **Write access**: always continue to Step 5, whether Step 3 fetched an + existing index (refresh it) or found the store empty (build the very + first version from scratch) — the two cases are handled identically + from here on; Step 7 is what actually creates the remote copy either + way. ### Step 5 — Resolve the connector and enumerate/summarize documents @@ -215,11 +232,22 @@ If this user has `access: write` **and** `source.yaml` has an `index:` block, push the refreshed `libs//{index.md,entities/,graph/,log.md}` back out to `index.location` (`git push` for `store: git`, a file copy back for a filesystem/network `store: shared` path, or the matching -connector tool for a `shared` location that needs one) — so every other -user's next fetch (Step 3) picks up the update. If no `index:` block is -configured, there's nothing to publish; the refreshed files staying inside -this repo's own `libs//` (tracked by this repo's own git) *is* the -publish step, same as the original default behavior. +connector tool for a `shared` location that needs one) — **every single +run**, not just the first one, so every other user's next fetch (Step 3) +picks up the update. This is exactly how a shared index gets created in +the first place: if Step 3 found the store empty, this step's push is what +populates it for the first time; there's no separate "initialize" action. + +If no `index:` block is configured, there's nothing external to publish; +the refreshed files staying inside this repo's own `libs//` (tracked +by this repo's own git) *is* the publish step, same as the original +default behavior. + +If this user is **read-only**, this step never runs — nothing is ever +pushed or copied to `index.location` (or, in the no-`index:`-block case, +nothing is even rebuilt in `libs//` to begin with). A read-only user +has, by construction, nothing of their own to save back — Step 4 already +stopped them before anything was built. ### Step 8 — Remind to review and sync