feat(skills): rebuild the skill system for the multi-user model
Nightly Build / build (push) Successful in 8m6s
Nightly Build / build (push) Successful in 8m6s
Per blueprint/skill-project.md: the old single-namespace, hand-maintained
index is gone, replaced by a read-only, two-scope tree whose index is a
runtime function of its content.
- skills/ index generated at runtime (crates/skald-core/src/skills/:
inventory, install, validate, watch), injected through the new
<!-- SKILLS_LIST --> placeholder in AGENT.md (agents/common/skills.md);
meta.json inject_skills flag removed. 11 chat/task agents carry the
include, the 4 system agents do not.
- Two trees, both read-only in both directions: skills/shared/{id} (the
group's) and skills/{username}/{id} (one member's own, on the stable
userid). The root is closed too: UserFs::SkillMounts + RouteError (alias
probe, plain-denied paths, no home fallback) and a per-user
.skills-root/{userid} container mount with the two scope mounts nested
inside, plus the fifth self-heal axis (skills_mounted).
- Agent verbs: skill_register/skill_delete (Config group, global scope
behind the new skill.manage capability), fetch_repo for public repos,
list_items(type="skills"); reads are plain read_file on the printed
path. Seeded @fs_read skills/* allow.
- Freshness: a digest-gated watcher on the two trees emits
SystemEvent::SkillsChanged, whose subscriber rebuilds the frozen prompt
prefix via Skald::invalidate_prompt_prefix; in-process writers invalidate
directly.
- The build ships no skills: the three bundled skills (ics2json,
mcp-builder, skill-creator) and skills/index.md are removed, skills/ is
instance data (gitignored, not packaged, no longer pruned by update.sh).
- Docs: skills.md, agents.md, shared-folders.md added; docs/index.md and
agents/README.md updated.
This commit is contained in:
@@ -105,6 +105,21 @@ pub enum SystemEvent {
|
||||
catalog_name: String,
|
||||
},
|
||||
|
||||
// ── Skills (blueprint skill-project §8) ───────────────────────────────────
|
||||
/// A skills tree changed on disk **in a way the index feels** — a skill was
|
||||
/// added, removed or re-described by someone editing files by hand on the
|
||||
/// box. Emitted by the freshness watcher after its digest gate: a change
|
||||
/// that leaves the index byte-identical (a script, a reference document)
|
||||
/// announces nothing, because the frozen system prefix citing that skill
|
||||
/// has not aged. The in-process writers (`skill_register`/`skill_delete`)
|
||||
/// never emit this — they invalidate directly.
|
||||
///
|
||||
/// Pure reconciliation, the contract this bus already promises: a lost
|
||||
/// event costs a stale skill index for the prefix TTL, never a wrong one.
|
||||
SkillsChanged {
|
||||
scope: SkillScope,
|
||||
},
|
||||
|
||||
// ── Reports (blueprint §13) ───────────────────────────────────────────────
|
||||
/// A background agent filed a report. Announced by whoever wrote the row,
|
||||
/// never delivered by it: *who* should hear about a report — the people
|
||||
@@ -125,6 +140,19 @@ pub enum SystemEvent {
|
||||
|
||||
// ── Bus ───────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Which skills tree a [`SystemEvent::SkillsChanged`] is about.
|
||||
///
|
||||
/// Distinct from the `"mine" | "global"` vocabulary of the skill tools: this
|
||||
/// names a *place on disk*, and a change to the group's tree concerns every
|
||||
/// member's prompt while a change to one member's tree concerns only theirs.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SkillScope {
|
||||
/// `{WD}/skills` — the group's tree, in every member's index.
|
||||
Global,
|
||||
/// `{WD}/skills-users/{userid}` — one member's own tree.
|
||||
User(String),
|
||||
}
|
||||
|
||||
pub struct SystemEventBus {
|
||||
tx: broadcast::Sender<SystemEvent>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user