agent-skillboard 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 0.2.3 — 2026-07-03
6
+
7
+ ### Added
8
+
9
+ - `skillboard uninstall --purge` removes SkillBoard config, reports, hooks,
10
+ bridge blocks, and empty generated directories while preserving local skill
11
+ files.
12
+
13
+ ### Changed
14
+
15
+ - Cleanup action cards now present the shorter purge command instead of the
16
+ three-flag reset form.
17
+ - Uninstall help and docs clarify the difference between conservative bridge
18
+ removal and full SkillBoard policy-footprint removal.
19
+
20
+ ## 0.2.2 — 2026-07-03
21
+
22
+ ### Changed
23
+
24
+ - High-risk runtime/plugin source action cards now recommend a one-time source review instead of defaulting to a block action.
25
+ - Reviewed quarantined runtime/plugin skills can be activated into a workflow as `manual-only` skills, keeping ask-after preference learning separate from source trust review.
26
+ - Bootstrap and install docs explain source review followed by manual activation for runtime/plugin skills.
27
+ - Generated guard hooks pin their install-time SkillBoard command, config, skills root, and workflow instead of accepting environment overrides for those trust-boundary values.
28
+ - README now surfaces public alpha and config schema v1 status near the quick product summary.
29
+ - npm package contents exclude historical planning documents under `docs/plans`.
30
+ - CI check matrix includes Node 24 before publish-time verification.
31
+
32
+ ## 0.2.1 — 2026-07-02
33
+
34
+ ### Added
35
+
36
+ - Ask-after skill routing guidance for ambiguous or fallback skill choices.
37
+ - Packaged runtime smoke coverage for npm-installed SkillBoard usage.
38
+
39
+ ### Changed
40
+
41
+ - Release automation now skips publishing only when the exact npm version already exists.
42
+ - AI bridge guidance emphasizes route candidates, post-use policy suggestions, and guard disclosure.
43
+
44
+ ## 0.2.0 — 2026-06-30
45
+
46
+ ### Added
47
+
48
+ - AI-mediated brief/action-card flow with current action IDs and post-apply brief refresh.
49
+ - Source inventory refresh, doctor/status summaries, source pin refresh, and install-output detection.
50
+ - Richer dry-run plans for lifecycle, import, hook, and cleanup workflows.
51
+
52
+ ### Changed
53
+
54
+ - README and install docs now lead with low-burden npm usage instead of source-tree setup.
55
+ - Workflow routing now separates installed skills from currently allowed skills more explicitly.
56
+
3
57
  ## 0.1.2 — 2026-06-29
4
58
 
5
59
  ### Added
package/README.md CHANGED
@@ -13,7 +13,11 @@ The burden stays low:
13
13
  - Most use is read-only: `brief`, `route`, `doctor`, and `guard use` answer
14
14
  what is safe now.
15
15
  - Nothing changes until you approve a policy action.
16
- - Project cleanup is conservative and previewable with `skillboard uninstall --dry-run`.
16
+ - Project cleanup is conservative and previewable with `skillboard uninstall --dry-run`;
17
+ `--purge` removes SkillBoard's policy footprint while preserving local skills.
18
+
19
+ Status: public alpha. The current config schema is config schema v1; breaking
20
+ changes may still happen before `1.0.0` and are documented in release notes.
17
21
 
18
22
  Under the hood, SkillBoard is workflow-scoped skill policy and routing for AI
19
23
  agents. It separates `installed` from `allowed`, checks workflow policy and
@@ -97,9 +101,12 @@ npx --yes --package agent-skillboard skillboard brief --workflow <workflow-from-
97
101
  and writes agent bridge instructions. It prints the workflows it found and a
98
102
  copyable workflow-scoped `brief` command. If `init` does not print a workflow,
99
103
  run the unscoped `brief` command it prints instead. Trusted user-local skills
100
- start as manual-only. Runtime, plugin, and external skills stay quarantined or
101
- blocked until reviewed. The explicit package/binary spelling avoids an extra npx
102
- install prompt and keeps the `skillboard` executable name clear.
104
+ start as manual-only. Runtime, plugin, and external skills stay quarantined
105
+ until their source is reviewed; the brief presents that as a one-time review
106
+ decision, then individual quarantined skills can be activated as manual-only
107
+ workflow skills before any later ask-after preference is recorded. The explicit
108
+ package/binary spelling avoids an extra npx install prompt and keeps the
109
+ `skillboard` executable name clear.
103
110
 
104
111
  Remove the project bridge when you are done:
105
112
 
@@ -111,6 +118,16 @@ npx --yes --package agent-skillboard skillboard uninstall --dir /path/to/your/pr
111
118
  Uninstall preserves local skills and policy files by default, and reports what
112
119
  it removed or preserved.
113
120
 
121
+ Remove SkillBoard's policy influence entirely while keeping local skill files:
122
+
123
+ ```bash
124
+ npx --yes --package agent-skillboard skillboard uninstall --dir /path/to/your/project --purge --dry-run
125
+ npx --yes --package agent-skillboard skillboard uninstall --dir /path/to/your/project --purge
126
+ ```
127
+
128
+ `--purge` deletes SkillBoard config, reports, hooks, bridge blocks, and empty
129
+ generated directories while leaving `skills/*/SKILL.md` in place.
130
+
114
131
  See [docs/install.md](docs/install.md) for global installs, `--dir`, GitHub
115
132
  builds, clone-based development, Hermes bridge setup, refresh, and uninstall.
116
133
 
package/docs/install.md CHANGED
@@ -28,11 +28,12 @@ npx --yes --package agent-skillboard skillboard brief --workflow <workflow-from-
28
28
 
29
29
  SkillBoard does not make installed skills automatically callable. It imports
30
30
  trusted local skills as manual-only and keeps runtime/plugin skills quarantined
31
- until reviewed. When `init` creates or discovers workflows, use one of the
32
- workflow names it prints for the first brief. If `init` does not print a
33
- workflow, run the unscoped `brief` command it prints instead. The explicit
34
- package/binary spelling avoids an extra npx install prompt and keeps the
35
- executable name clear.
31
+ until their source is reviewed. The brief presents unreviewed runtime sources as
32
+ one-time review decisions rather than default block recommendations; after
33
+ review, individual quarantined skills can be activated as manual-only workflow
34
+ skills. When `init` creates or discovers workflows, use one of the workflow names
35
+ it prints for the first brief. If `init` does not print a workflow, run the unscoped `brief` command it prints instead. The explicit package/binary spelling
36
+ avoids an extra npx install prompt and keeps the executable name clear.
36
37
 
37
38
  The equivalent `npm exec` spelling is also no-prompt and works well in scripts:
38
39
 
@@ -119,12 +120,16 @@ manual-only` and attached to a generated local manual workflow when the project
119
120
  has no workflow metadata yet. That lets a first-time user keep their existing
120
121
  manual skills usable through `skillboard can-use` and guard checks without
121
122
  granting automatic model invocation or creating legacy-state warning noise.
122
- System, plugin, and other runtime-supplied skills are written with `status: quarantined` and
123
- `invocation: blocked`. Plugin hooks, MCP servers, commands, and modified config files are
124
- recorded on the owning install unit when manifest metadata exposes them, which
125
- lets policy checks flag high-risk runtime extensions without flattening them
126
- into loose skills. Use `--no-scan-installed` for a scaffold-only bootstrap, or
127
- `--scan-root <dir>[,<dir>]` to add server-specific skill roots during bootstrap.
123
+ System, plugin, and other runtime-supplied skills are written with `status:
124
+ quarantined` and `invocation: blocked`. Plugin hooks, MCP servers, commands, and
125
+ modified config files are recorded on the owning install unit when manifest
126
+ metadata exposes them, which lets policy checks flag high-risk runtime
127
+ extensions without flattening them into loose skills. After the owning source is
128
+ reviewed, action cards can activate a quarantined runtime skill into a workflow
129
+ as `manual-only`; automatic preference should still be remembered later through
130
+ the normal ask-after-use policy loop. Use `--no-scan-installed` for a
131
+ scaffold-only bootstrap, or `--scan-root <dir>[,<dir>]` to add server-specific
132
+ skill roots during bootstrap.
128
133
 
129
134
  After init, run:
130
135
 
@@ -178,7 +183,10 @@ so stale action ids and cached action-card shell text are not replayed.
178
183
  For hook action cards specifically, keep `apply-action` as the action-card
179
184
  primary flow. Raw `skillboard hook install ... --dry-run --json` previews and
180
185
  the matching non-dry-run command are underlying manual detail for operators who
181
- need to inspect or materialize an executable guard hook directly.
186
+ need to inspect or materialize an executable guard hook directly. Generated hooks
187
+ pin the install-time SkillBoard command, config, skills root, and workflow; set
188
+ those values with hook install options such as `--skillboard-bin`, not with
189
+ runtime environment overrides.
182
190
 
183
191
  ## Hermes System Prompt Bridge
184
192
 
@@ -303,6 +311,18 @@ Default uninstall behavior is conservative:
303
311
  hooks, and modified files by default. Empty generated directories can be
304
312
  removed.
305
313
 
314
+ Use `--purge` when you want SkillBoard's influence removed from the project
315
+ instead of merely disconnecting the bridge:
316
+
317
+ ```bash
318
+ skillboard uninstall --dir /path/to/your/project --purge --dry-run
319
+ skillboard uninstall --dir /path/to/your/project --purge
320
+ ```
321
+
322
+ `--purge` removes SkillBoard config, reports, hooks, bridge blocks, and empty
323
+ generated directories. It preserves local `skills/` files because skills that
324
+ were created or deleted are outside the uninstall scope.
325
+
306
326
  Use `--remove-config` to delete `skillboard.config.yaml` only when it still
307
327
  matches the untouched default config. If the config contains scanned skills or
308
328
  user edits, uninstall preserves it and reports it under `Preserved`.
@@ -322,7 +342,8 @@ Add `--remove-hooks` only when a reset should also delete the entire
322
342
  `.skillboard/hooks/` directory contents. This is explicit because hook scripts
323
343
  may be wired into local agent/runtime configuration. Combine `--reset-config`,
324
344
  `--remove-reports`, and `--remove-hooks` for a clean test reset that removes
325
- SkillBoard-owned lifecycle scaffolding while preserving local `skills/`.
345
+ SkillBoard-owned lifecycle scaffolding while preserving local `skills/`. The
346
+ equivalent short form is `--purge`.
326
347
 
327
348
  ## Upper-Layer Control
328
349
 
@@ -370,8 +391,8 @@ skillboard review install-unit github.mattpocock.skills \
370
391
 
371
392
  Automatic invocation remains blocked for unreviewed non-user sources. The user
372
393
  experience should still be a one-time decision queue: review, trust, or block
373
- the install unit once, then revisit only when the source, skill, or workflow
374
- changes.
394
+ the install unit once, activate only the needed quarantined skills as
395
+ manual-only, then revisit only when the source, skill, or workflow changes.
375
396
 
376
397
  ```yaml
377
398
  install_units:
package/docs/reference.md CHANGED
@@ -52,7 +52,7 @@ node bin/skillboard.mjs brief --dir /path/to/your/project --workflow <workflow-f
52
52
 
53
53
  ```bash
54
54
  skillboard init [--dir <path>] [--scan-root <dir>[,<dir>]] [--no-scan-installed]
55
- skillboard uninstall [--dir <path>] [--dry-run] [--remove-config|--reset-config] [--remove-reports] [--remove-hooks] [--keep-empty-dirs]
55
+ skillboard uninstall [--dir <path>] [--dry-run] [--purge] [--remove-config|--reset-config] [--remove-reports] [--remove-hooks] [--keep-empty-dirs]
56
56
  skillboard inventory refresh [--dir <path>] [--config <path>] [--scan-root <dir>[,<dir>]] [--dry-run] [--json]
57
57
  skillboard inventory detect --unit <id> --config <path> [--install-output <path>] [--config-file a,b] [--source <value>] [--kind <kind>] [--scope <scope>] [--dry-run] [--json]
58
58
  skillboard sources refresh [--dir <path>] [--config <path>] [--unit <id>[,<id>]] [--cache-dir <dir>] [--dry-run] [--json]
package/docs/user-flow.md CHANGED
@@ -191,7 +191,10 @@ skillboard hook install --workflow daily-workflow --config skillboard.config.yam
191
191
  ```
192
192
 
193
193
  For direct manual hook installation, inspect the JSON `planned.preview.shell`
194
- before an operator materializes the matching non-dry-run hook command.
194
+ before an operator materializes the matching non-dry-run hook command. Generated
195
+ hooks pin the install-time SkillBoard command, config, skills root, and workflow;
196
+ set those values with hook install options such as `--skillboard-bin`, not with
197
+ runtime environment overrides.
195
198
 
196
199
  ## 4. Enable, Disable, Or Prefer
197
200
 
@@ -258,8 +261,8 @@ skillboard remove skill user.helper \
258
261
  --force
259
262
  ```
260
263
 
261
- This removes SkillBoard policy references only. It does not delete
262
- `skills/user-helper/SKILL.md`.
264
+ This removes SkillBoard policy references only and leaves
265
+ `skills/user-helper/SKILL.md` in place.
263
266
 
264
267
  ## 6. Stop Using SkillBoard Safely
265
268
 
@@ -277,14 +280,16 @@ content in bridge files.
277
280
  For a fresh policy lifecycle during testing, use:
278
281
 
279
282
  ```bash
280
- skillboard uninstall --reset-config --remove-reports --remove-hooks --dry-run
281
- skillboard uninstall --reset-config --remove-reports --remove-hooks
283
+ skillboard uninstall --purge --dry-run
284
+ skillboard uninstall --purge
282
285
  skillboard init
283
286
  ```
284
287
 
285
- `--reset-config` discards the current SkillBoard config even if it contains
286
- imported skills or workflow edits. `--remove-reports` also discards generated
287
- dashboard and impact reports. `--remove-hooks` discards the entire
288
- `.skillboard/hooks/` directory contents when you explicitly want a full test or
289
- test reset, so `.skillboard/` can disappear when no other SkillBoard state
290
- remains. These reset flags do not delete local `skills/` files.
288
+ Use `--purge` when you want SkillBoard's allow/block/preference influence gone
289
+ from the project while keeping local skill files. It discards the current
290
+ SkillBoard config even if it contains imported skills or workflow edits,
291
+ discards generated dashboard and impact reports, and removes the entire
292
+ `.skillboard/hooks/` directory contents. It is equivalent to
293
+ `--reset-config --remove-reports --remove-hooks`, so `.skillboard/` can
294
+ disappear when no other SkillBoard state remains. Local `skills/` files stay in
295
+ place.
@@ -35,6 +35,10 @@ examples/skillboard.config.yaml
35
35
  examples/skills
36
36
  ```
37
37
 
38
+ `examples/skillboard.config.yaml` is an intentional policy-failure fixture. It
39
+ is not the passing starter example; it exists to prove that SkillBoard refuses a
40
+ raw-list availability claim when policy health fails.
41
+
38
42
  Workflow:
39
43
 
40
44
  ```bash
@@ -8,7 +8,7 @@ source profiles, and the generated lockfile.
8
8
 
9
9
  ## Status
10
10
 
11
- Current package version: `0.2.1`
11
+ Current package version: `0.2.3`
12
12
 
13
13
  Current config schema version:
14
14
 
@@ -59,7 +59,8 @@ must call them out clearly.
59
59
  Suggested tags:
60
60
 
61
61
  - `v0.1.0-alpha`: first public GitHub alpha.
62
- - `v0.2.1`: ask-after skill routing, README benefit-first positioning,
62
+ - `v0.2.3`: one-time runtime source review before manual activation, ask-after
63
+ skill routing, purge uninstall, README benefit-first positioning,
63
64
  source inventory refresh, doctor/status, source pin refresh,
64
65
  installer/config detection, resilient detector warnings, and richer dry-run
65
66
  plans.
@@ -193,8 +194,8 @@ Before tagging a public release:
193
194
  provenance with GitHub Actions OIDC, so keep `permissions.id-token: write`,
194
195
  the npm registry URL in `setup-node`, and
195
196
  `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}` on the publish step.
196
- - Push a version tag that exactly matches `package.json`, for example `v0.2.1`
197
- for package version `0.2.1`.
197
+ - Push a version tag that exactly matches `package.json`, for example `v0.2.3`
198
+ for package version `0.2.3`.
198
199
  - Let `.github/workflows/publish.yml` publish from the tag. The workflow runs
199
200
  the full check suite, validates that the tag matches the package version, and
200
201
  skips `npm publish` only when that exact version already exists on npm.
@@ -228,8 +229,21 @@ completion notes:
228
229
  - update README quick-start to verify the installed version before running
229
230
  policy commands.
230
231
 
231
- ## 0.2.1 Completion Notes
232
+ ## 0.2.3 Completion Notes
232
233
 
234
+ - add `skillboard uninstall --purge` for users who want SkillBoard's policy
235
+ influence and generated footprint removed while preserving local skill files;
236
+ - document the lifecycle split between conservative bridge cleanup and full
237
+ SkillBoard policy-footprint removal;
238
+ - show purge in cleanup action cards so users do not need to remember the
239
+ equivalent `--reset-config --remove-reports --remove-hooks` sequence.
240
+
241
+ ## 0.2.2 Completion Notes
242
+
243
+ - recommend one-time review, not default blocking, for high-risk runtime/plugin
244
+ install units;
245
+ - after source review, allow quarantined runtime/plugin skills to be activated
246
+ as `manual-only` workflow skills before any ask-after preference is recorded;
233
247
  - add ask-after route policy suggestions for safe ambiguous workflow skill
234
248
  matches while preserving the public route JSON contract;
235
249
  - carry route candidate guard and capability roles into AI-facing brief
@@ -1,6 +1,11 @@
1
- version: 1
2
-
3
- defaults:
1
+ # Intentional policy-failure fixture.
2
+ # This file is used by the value-proof tests to show why a raw skill list can
3
+ # look usable while SkillBoard correctly reports policy errors. Use
4
+ # examples/multi-source.config.yaml for a passing multi-source example.
5
+
6
+ version: 1
7
+
8
+ defaults:
4
9
  invocation_policy: deny-by-default
5
10
  allow_model_invocation: false
6
11
  require_explicit_workflow: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-skillboard",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Let AI agents pick and use allowed skills in each workflow.",
5
5
  "keywords": [
6
6
  "ai-agent",
@@ -25,7 +25,6 @@
25
25
  "bin",
26
26
  "src",
27
27
  "docs/*.md",
28
- "docs/plans",
29
28
  "examples",
30
29
  "profiles",
31
30
  "README.md",
@@ -12,6 +12,7 @@ import { buildSetupGuidanceActions } from "./setup-actions.mjs";
12
12
  import { trustRecommendationAction } from "./trust-policy.mjs";
13
13
 
14
14
  const WRITABLE_MODES = new Set(["manual-only", "router-only", "workflow-auto"]);
15
+ const NON_ACTIVATABLE_STATUSES = new Set(["deprecated", "archived", "removed"]);
15
16
 
16
17
  export function buildInitActions(paths) {
17
18
  return [makeAction({
@@ -82,7 +83,10 @@ function reviewInstallUnitActions({ paths, workflow, reviewQueue }) {
82
83
  }
83
84
 
84
85
  function activateSkillActions({ paths, workflow, skills, workspace }) {
85
- const candidates = [...skills.not_in_workflow, ...skills.blocked.filter((skill) => missingProvenance(workspace, skill.id))];
86
+ const candidates = [
87
+ ...skills.not_in_workflow,
88
+ ...skills.blocked.filter((skill) => missingProvenance(workspace, skill.id) || canActivate(skill))
89
+ ];
86
90
  return candidates.flatMap((skill) => {
87
91
  if (missingProvenance(workspace, skill.id)) {
88
92
  return [blockedActivateAction(paths, workflow, skill)];
@@ -90,7 +94,7 @@ function activateSkillActions({ paths, workflow, skills, workspace }) {
90
94
  if (!canActivate(skill)) {
91
95
  return [];
92
96
  }
93
- const mode = skill.advanced.invocation;
97
+ const mode = activationMode(skill);
94
98
  const risk = riskFromSkill(skill);
95
99
  const dryRun = command([
96
100
  "skillboard", "activate", skill.id, "--workflow", workflow.selected, "--mode", mode,
@@ -169,6 +173,7 @@ function hookInstallActions({ paths, workflow }) {
169
173
  function removeSkillForceActions({ paths, workflow, skills, workspace }) {
170
174
  return skills.blocked
171
175
  .filter((skill) => !missingProvenance(workspace, skill.id))
176
+ .filter((skill) => !canActivate(skill))
172
177
  .map((skill) => {
173
178
  const dryRun = command([
174
179
  "skillboard", "remove", "skill", skill.id, "--force",
@@ -194,19 +199,17 @@ function removeSkillForceActions({ paths, workflow, skills, workspace }) {
194
199
 
195
200
  function resetCleanupAction({ paths, workflow, cleanup }) {
196
201
  const dryRun = command([
197
- "skillboard", "uninstall", "--dir", paths.root, "--dry-run",
198
- "--reset-config", "--remove-reports", "--remove-hooks"
202
+ "skillboard", "uninstall", "--dir", paths.root, "--purge", "--dry-run"
199
203
  ]);
200
204
  return makeAction({
201
205
  kind: "reset-cleanup",
202
206
  targetId: paths.root,
203
- label: "Reset SkillBoard generated project files",
204
- reason: "Preview full SkillBoard cleanup before applying it.",
207
+ label: "Purge SkillBoard project footprint",
208
+ reason: "Preview full SkillBoard policy cleanup before applying it.",
205
209
  risk: "destructive",
206
210
  dryRun,
207
211
  apply: applyOrNull(workflow, dryRun, [
208
- "skillboard", "uninstall", "--dir", paths.root,
209
- "--reset-config", "--remove-reports", "--remove-hooks"
212
+ "skillboard", "uninstall", "--dir", paths.root, "--purge"
210
213
  ]),
211
214
  appliesTo: { kind: "project", id: paths.root },
212
215
  blockedReason: blockedByWorkflow(workflow),
@@ -230,7 +233,24 @@ function blockedActivateAction(paths, workflow, skill) {
230
233
  }
231
234
 
232
235
  function canActivate(skill) {
233
- return WRITABLE_MODES.has(skill.advanced.invocation) && skill.advanced.trust.reviewed === true;
236
+ return activationMode(skill) !== null && skill.advanced.trust.reviewed === true;
237
+ }
238
+
239
+ function activationMode(skill) {
240
+ if (NON_ACTIVATABLE_STATUSES.has(skill.advanced.status)) {
241
+ return null;
242
+ }
243
+ if (WRITABLE_MODES.has(skill.advanced.invocation)) {
244
+ return skill.advanced.invocation;
245
+ }
246
+ if (
247
+ skill.advanced.owner_install_unit !== undefined
248
+ && skill.advanced.owner_install_unit !== null
249
+ && (skill.advanced.status === "quarantined" || skill.advanced.invocation === "blocked")
250
+ ) {
251
+ return "manual-only";
252
+ }
253
+ return null;
234
254
  }
235
255
 
236
256
  function missingProvenance(workspace, skillId) {
@@ -21,9 +21,11 @@ export function recommendTrustLevel(unit) {
21
21
  return "trusted";
22
22
  }
23
23
 
24
- // High-risk sources should not be activated from advisor suggestions without explicit blocking/review.
24
+ // High-risk sources require explicit review, not a default block. Blocking is
25
+ // still available as a recorded trust policy, but the advisor keeps the work
26
+ // moving by asking for a one-time source review first.
25
27
  if (risk === "high") {
26
- return "blocked";
28
+ return "reviewed";
27
29
  }
28
30
 
29
31
  // Unknown risk always requires at least a review before any automatic use.
@@ -54,7 +56,7 @@ export function trustRecommendationAction(recommended) {
54
56
  return {
55
57
  kind: "block-install-unit",
56
58
  label: "Decide whether to block source",
57
- reason: "High-risk or runtime-extending source needs a one-time decision before its skills appear again."
59
+ reason: "Source is blocked by trust policy and needs an explicit decision before its skills appear again."
58
60
  };
59
61
  }
60
62
  return {
package/src/cli.mjs CHANGED
@@ -61,7 +61,7 @@ const VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.u
61
61
 
62
62
  const APPLY_ACTION_VALUE_OPTIONS = new Set(["workflow", "dir", "config", "skills", "out", "skillboard-bin"]);
63
63
  const COMMAND_USAGE = new Map([
64
- ["uninstall", ["uninstall [--dir <path>] [--dry-run] [--remove-config|--reset-config] [--remove-reports] [--remove-hooks] [--keep-empty-dirs]"]],
64
+ ["uninstall", ["uninstall [--dir <path>] [--dry-run] [--purge] [--remove-config|--reset-config] [--remove-reports] [--remove-hooks] [--keep-empty-dirs]"]],
65
65
  [
66
66
  "inventory",
67
67
  [
@@ -1501,7 +1501,7 @@ function helpText() {
1501
1501
  "",
1502
1502
  "AI/automation operations:",
1503
1503
  " init [--dir <path>] [--scan-root <dir>[,<dir>]] [--no-scan-installed]",
1504
- " uninstall [--dir <path>] [--dry-run] [--remove-config|--reset-config] [--remove-reports] [--remove-hooks] [--keep-empty-dirs]",
1504
+ " uninstall [--dir <path>] [--dry-run] [--purge] [--remove-config|--reset-config] [--remove-reports] [--remove-hooks] [--keep-empty-dirs]",
1505
1505
  " inventory refresh [--dir <path>] [--config <path>] [--scan-root <dir>[,<dir>]] [--dry-run] [--json]",
1506
1506
  " inventory detect --unit <id> --config <path> [--install-output <path>] [--config-file a,b] [--source <value>] [--kind <kind>] [--scope <scope>] [--dry-run] [--json]",
1507
1507
  " sources refresh [--dir <path>] [--config <path>] [--unit <id>[,<id>]] [--cache-dir <dir>] [--dry-run] [--json]",
@@ -1560,6 +1560,9 @@ function commandHelpText(command) {
1560
1560
  if (command === "init") {
1561
1561
  return initHelpText();
1562
1562
  }
1563
+ if (command === "uninstall") {
1564
+ return uninstallHelpText();
1565
+ }
1563
1566
  if (command === "doctor" || command === "status") {
1564
1567
  return doctorHelpText();
1565
1568
  }
@@ -1601,7 +1604,7 @@ function initHelpText() {
1601
1604
  "What changes:",
1602
1605
  " Writes skillboard.config.yaml, skills/, .skillboard/, AGENTS.md, and CLAUDE.md as needed.",
1603
1606
  " Imports trusted user-local skills as on-request skills.",
1604
- " Keeps runtime, plugin, system, and external skills quarantined until reviewed.",
1607
+ " Keeps runtime, plugin, system, and external skills behind source review before manual activation.",
1605
1608
  "",
1606
1609
  "Next:",
1607
1610
  " Run skillboard doctor --summary.",
@@ -1610,6 +1613,33 @@ function initHelpText() {
1610
1613
  ].join("\n");
1611
1614
  }
1612
1615
 
1616
+ function uninstallHelpText() {
1617
+ return [
1618
+ "Usage: skillboard uninstall [--dir <path>] [--dry-run] [--purge] [--remove-config|--reset-config] [--remove-reports] [--remove-hooks] [--keep-empty-dirs]",
1619
+ "",
1620
+ "This help is read-only. It does not load config or change project files.",
1621
+ "",
1622
+ "Removes SkillBoard project bridge files and generated lifecycle scaffolding.",
1623
+ "Default cleanup is conservative and preserves policy, reports, hooks, local skills, and user-authored content.",
1624
+ "",
1625
+ "Options:",
1626
+ " --dir <path> Project root to clean up; defaults to the current directory.",
1627
+ " --dry-run Preview the cleanup without writing changes.",
1628
+ " --purge Remove SkillBoard policy influence and generated footprint while preserving local skills.",
1629
+ " --remove-config Delete skillboard.config.yaml only if it still matches the generated default.",
1630
+ " --reset-config Delete skillboard.config.yaml even when it contains policy choices.",
1631
+ " --remove-reports Delete .skillboard/reports/.",
1632
+ " --remove-hooks Delete .skillboard/hooks/.",
1633
+ " --keep-empty-dirs Preserve empty generated directories.",
1634
+ "",
1635
+ "Purge:",
1636
+ " Equivalent to --reset-config --remove-reports --remove-hooks.",
1637
+ " It removes SkillBoard config, reports, hooks, bridge blocks, and empty generated dirs.",
1638
+ " It does not delete local skills under skills/.",
1639
+ ""
1640
+ ].join("\n");
1641
+ }
1642
+
1613
1643
  function doctorHelpText() {
1614
1644
  return [
1615
1645
  "Usage: skillboard doctor [--dir <path>] [--config <path>] [--skills <dir>] [--verify] [--strict] [--summary] [--json]",
package/src/hook-plan.mjs CHANGED
@@ -58,10 +58,10 @@ function renderGuardHookScript(options) {
58
58
  return `#!/usr/bin/env sh
59
59
  set -eu
60
60
 
61
- SKILLBOARD_BIN=\${SKILLBOARD_BIN:-${shellQuote(options.command)}}
62
- SKILLBOARD_CONFIG=\${SKILLBOARD_CONFIG:-${shellQuote(options.configPath)}}
63
- SKILLBOARD_SKILLS=\${SKILLBOARD_SKILLS:-${shellQuote(options.skillsRoot)}}
64
- SKILLBOARD_WORKFLOW=\${SKILLBOARD_WORKFLOW:-${shellQuote(options.workflow)}}
61
+ SKILLBOARD_BIN=${shellQuote(options.command)}
62
+ SKILLBOARD_CONFIG=${shellQuote(options.configPath)}
63
+ SKILLBOARD_SKILLS=${shellQuote(options.skillsRoot)}
64
+ SKILLBOARD_WORKFLOW=${shellQuote(options.workflow)}
65
65
 
66
66
  if [ "\${SKILLBOARD_SKILL_ID:-}" != "" ]; then
67
67
  skill_id="$SKILLBOARD_SKILL_ID"
@@ -72,8 +72,8 @@ else
72
72
  exit 64
73
73
  fi
74
74
 
75
- # Split SKILLBOARD_BIN so local hook configs can use commands like:
76
- # SKILLBOARD_BIN="node bin/skillboard.mjs"
75
+ # Split the install-time command so hooks can use commands like:
76
+ # --skillboard-bin "node bin/skillboard.mjs"
77
77
  # Paths containing spaces should be provided through an environment wrapper.
78
78
  set -- $SKILLBOARD_BIN
79
79
  exec "$@" guard use "$skill_id" --workflow "$SKILLBOARD_WORKFLOW" --config "$SKILLBOARD_CONFIG" --skills "$SKILLBOARD_SKILLS"
@@ -37,17 +37,23 @@ export async function runInitCommand(options, stdout, runtime = defaultRuntime()
37
37
  }
38
38
 
39
39
  export async function runUninstallCommand(options, stdout) {
40
- if (options.get("remove-config") === "true" && options.get("reset-config") === "true") {
40
+ const removeConfig = options.get("remove-config") === "true";
41
+ const resetConfig = options.get("reset-config") === "true";
42
+ const purge = options.get("purge") === "true";
43
+ if (removeConfig && resetConfig) {
41
44
  throw new Error("--remove-config and --reset-config are mutually exclusive");
42
45
  }
46
+ if (removeConfig && purge) {
47
+ throw new Error("--remove-config cannot be combined with --purge");
48
+ }
43
49
  const root = resolve(options.get("dir") ?? ".");
44
50
  const result = await uninstallProject({
45
51
  root,
46
52
  dryRun: options.get("dry-run") === "true",
47
- removeConfig: options.get("remove-config") === "true",
48
- resetConfig: options.get("reset-config") === "true",
49
- removeReports: options.get("remove-reports") === "true",
50
- removeHooks: options.get("remove-hooks") === "true",
53
+ removeConfig,
54
+ resetConfig: resetConfig || purge,
55
+ removeReports: options.get("remove-reports") === "true" || purge,
56
+ removeHooks: options.get("remove-hooks") === "true" || purge,
51
57
  removeEmptyDirs: options.get("keep-empty-dirs") !== "true"
52
58
  });
53
59
  stdout.write(`${result.dryRun ? "Dry run: " : ""}Uninstalled SkillBoard: ${root}\n`);
@@ -86,7 +92,7 @@ function writeSafetyDefault(stdout, safety) {
86
92
  stdout.write(`- ${safety.automatic} automatic skills enabled by existing policy.\n`);
87
93
  }
88
94
  stdout.write("- Imported local skills are manual-only.\n");
89
- stdout.write("- Runtime/plugin/system skills are quarantined until reviewed.\n");
95
+ stdout.write("- Runtime/plugin/system skills require source review before manual activation.\n");
90
96
  stdout.write(`- ${safety.automatic} automatic skills enabled\n`);
91
97
  stdout.write(`- ${safety.manualOnly} manual-only skills available\n`);
92
98
  stdout.write(`- ${safety.routerOnly} router-only skills available\n`);
@@ -47,9 +47,9 @@ Your responsibility is to answer skill availability questions from SkillBoard, t
47
47
 
48
48
  ## Operations
49
49
 
50
- - Source trust: run \`skillboard audit sources --config skillboard.config.yaml --skills skills\` before trusting newly imported external skill sources; after review, use \`skillboard review install-unit <unit-id> --trust-level reviewed --config skillboard.config.yaml --skills skills\`.
50
+ - Source trust: run \`skillboard audit sources --config skillboard.config.yaml --skills skills\` before trusting newly imported external skill sources; after review, use \`skillboard review install-unit <unit-id> --trust-level reviewed --config skillboard.config.yaml --skills skills\`. Unreviewed runtime sources are a one-time review decision, not a default block recommendation; after review, activate only the needed quarantined skills as manual-only workflow skills and use ask-after policy suggestions for future preferences.
51
51
  - Health: run \`skillboard doctor --config skillboard.config.yaml --skills skills\` or \`skillboard status --config skillboard.config.yaml --skills skills --json\`; add \`--strict\` when review-needed safe mode should fail automation.
52
- - Hook action cards: prefer \`skillboard apply-action <action-id> --yes --json\`. The underlying manual preview is \`skillboard hook install --workflow <name> --config skillboard.config.yaml --skills skills --out .skillboard/hooks/<name>-guard.sh --dry-run --json\`; inspect \`planned.preview.shell\` before materializing an executable guard hook outside the action-card control loop.
52
+ - Hook action cards: prefer \`skillboard apply-action <action-id> --yes --json\`. The underlying manual preview is \`skillboard hook install --workflow <name> --config skillboard.config.yaml --skills skills --out .skillboard/hooks/<name>-guard.sh --dry-run --json\`; inspect \`planned.preview.shell\` before materializing an executable guard hook outside the action-card control loop. Generated hooks pin the install-time SkillBoard command, config, skills root, and workflow; set those values with hook install options such as \`--skillboard-bin\`, not runtime environment overrides.
53
53
  - Inventory/import growth: run \`skillboard inventory refresh --dry-run --config skillboard.config.yaml\` after installing local skill packs, plugins, workflow bundles, or harnesses; run \`skillboard import --profile <id-or-path> --source-root <repo> --out .skillboard/reports/import-fragment.yaml\` after installing a new skill repository, then review the fragment before merging it into \`skillboard.config.yaml\`.
54
54
  - Prefer workflow-scoped skills over global skill invocation. Only \`global-meta\` skills may be treated as globally available.
55
55
 
@@ -88,7 +88,10 @@ For hook action cards, prefer the bridge control loop with
88
88
  \`skillboard apply-action <action-id> --yes --json\`. These raw hook commands
89
89
  are the underlying manual detail: preview the JSON plan first and inspect
90
90
  \`planned.preview.shell\` before materializing an executable guard hook.
91
- The generated script delegates to \`skillboard guard use\` and can be wired into
92
- the hook mechanism of the active harness.
91
+ Generated hooks pin the install-time SkillBoard command, config, skills root,
92
+ and workflow; set those values with hook install options such as
93
+ \`--skillboard-bin\`, not runtime environment overrides. The generated script
94
+ delegates to \`skillboard guard use\` and can be wired into the hook mechanism of
95
+ the active harness.
93
96
  `;
94
97
  }
@@ -1,189 +0,0 @@
1
- # skillboard-mvp-review
2
-
3
- - Skill: tdd-work-continuity
4
- - Agent: hermes
5
- - Created: 2026-06-25T08:00:25Z
6
- - Updated: 2026-06-25T10:05:00Z
7
- - Workdir: /home/nyxxir/skillboard
8
- - Status: completed
9
-
10
- ## Goal
11
-
12
- SkillBoard(`skill-control-plane`)의 MVP 기능과 낶부 도메인 설계를 검토하고, **처음 사용자가 skill을 가져다 붙이고 이용 및 삭제하는 불편을 해소하는 방향인지**, **도메인 설계가 적합하고 확장 가능한지**를 평가한다. 이전 대화에서 제안한 4.1~4.3 UX 개선 항목도 포함된 실행 계획을 문서화한다.
13
-
14
- ## Context
15
-
16
- - Repo: `/home/nyxxir/skillboard`
17
- - Relevant files:
18
- - `src/cli.mjs` — CLI 라우터
19
- - `src/control.mjs` — skill/workflow/harness/capability CRUD, `can-use`, `guard`, trust/source 분류
20
- - `src/domain/rules/*.mjs` — 정책 규칙 엔진
21
- - `src/workspace.mjs` — config 파싱, `SKILL.md` frontmatter 파싱
22
- - `src/agent-inventory.mjs` — 설치된 agent skill 자동 스캔/병합
23
- - `src/brief-cli.mjs`, `src/brief-renderer.mjs`, `src/advisor.mjs` — AI/사용자 브리핑
24
- - `src/impact.mjs`, `src/reconcile.mjs` — 영향도/재조정 분석
25
- - `src/init.mjs`, `src/uninstall.mjs` — 생명주기
26
- - Constraints:
27
- - MVP 단계, npm publish 전 (`version: 0.1.0`)
28
- - Node.js >= 20, ESM, yaml 의존성 하나
29
- - cross-platform CI (ubuntu/macOS/windows × node 20/22)
30
-
31
- ## Findings Summary
32
-
33
- ### 1. 도메인 설계: 적합하고 확장 가능함 (Score: 8/10)
34
-
35
- **핵심 엔티티 5개**가 skill 생태계의 실제 관심사를 잘 반영한다.
36
-
37
- | Entity | 역할 | 적합성 |
38
- |--------|------|--------|
39
- | `skills` | 선언된 스킬의 상태/호출방식/노출범위 | ✅ 적절. status/invocation/exposure 3중 분리로 정책 표현력 높음 |
40
- | `capabilities` | 역할 기반 스킬 추상화 | ✅ 적절. canonical/alternatives/default_policy로 교체/대안 추천 가능 |
41
- | `workflows` | 스킬이 활성화되는 맥락 | ✅ 적절. active_skills/blocked_skills/required_capabilities로 명시적 제어 |
42
- | `harnesses` | runtime/command 제공자 추적 | ✅ 적절. harness 제거 시 workflow 영향도 파악 가능 |
43
- | `install_units` | plugin/marketplace/harness 등의 부모 단위 | ✅ 매우 적절. skill 평탄화 문제 해결 |
44
-
45
- **확장 가능성**
46
- - `INSTALL_UNIT_KIND_VALUES`에 `skill`, `plugin`, `marketplace`, `harness`, `mcp-server`, `hook`, `agent`, `lsp`, `custom`을 두어 새로운 runtime primitive 추가가 용이함.
47
- - `source_classes.mjs`의 우선순위/분류 함수가 데이터 기반으로 되어 있어 새 source class 추가가 쉬움.
48
- - `source profile` 어댑터 모델이 하드코딩을 피하고 데이터 주도 import를 지향함.
49
-
50
- **위험 요소**
51
- - `src/control.mjs`가 1000줄에 달해 단일 책임 위반. `can-use`, CRUD, trust/source, YAML 쓰기, hook 설치 등이 한 파일에 있어 장기 유지보수 부담.
52
- - `status` 값이 14개로 많고, `status`와 `invocation` 간의 유효 조합 규칙이 복잡(`SKILL-STATUS-001`). 새로운 상태 추가 시 규칙 행렬이 기하급수적으로 늘어날 수 있음.
53
- - `capability`가 workflow-scoped `required_capabilities`와 global `capabilities`로 이중 정의됨. 의도는 명확하지만 사용자 입장에서 학습 곡선이 있음.
54
-
55
- ### 2. 사용자 불편 해소 vs 가중
56
-
57
- #### 해소하는 설계
58
-
59
- | 기능 | 불편 해소 메커니즘 |
60
- |------|------------------|
61
- | `init` 시 자동 스캔 + `active-manual` 연결 | 기존 수동 스킬을 따로 등록하지 않아도 `can-use`/`guard`로 계속 사용 가능 |
62
- | `deny-by-default` + quarantine | 설치만으로 AI가 스킬을 부르는 것을 원천 차단 |
63
- | `impact disable` | 스킬 제거 전 영향받는 workflow/capability를 사전에 노출 |
64
- | 대부분의 mutating 명령에 `--dry-run` | 실수로 config를 망치는 위험 감소 |
65
- | `brief --json` | 에이전트가 정책을 직접 해석하지 않고 control plane에 질의 |
66
- | `uninstall`이 사용자 파일 보존 | 도구를 빼도 skill 파일과 사용자 config는 남음 |
67
-
68
- #### 가중할 수 있는 설계
69
-
70
- | 지점 | 불편 가능성 | 심각도 |
71
- |------|------------|--------|
72
- | 매번 `--config skillboard.config.yaml --skills skills` 필요 | 일상 명령이 번거로움 | 중간 |
73
- | `SKILL.md` frontmatter 누락 시 메시지가 모호함 | 처음 사용자가 문서를 찾아야 함 | 높음 |
74
- | `doctor` 출력이 길고 `--summary` 부재 | 매일 보기에 피로함 | 중간 |
75
- | `add workflow` 시 `--harness`를 명시해야 함 | harness 개념을 모르는 사용자에게 진입 장벽 | 중간 |
76
- | `status`/`invocation`/`exposure`/`trust_level` 용어가 많음 | 정책 도구이므로 불가피하지만, 온볭딩 문서가 중요 | 중간 |
77
- | `init` 후 생성되는 config가 수십 개 스킬로 즉시 커짐 | 실제로 설치된 게 많으면 압도적 | 낮음~중간 |
78
-
79
- **종합 판단**: 보안/통제를 얻는 대가로 적정 수준의 복잡성을 요구한다. 다만 **처음 사용자의 첫 5분**을 더 부드럽게 만들면 Adoption이 크게 올라갈 것이다.
80
-
81
- ### 3. MVP 기능 검증 결과
82
-
83
- | 기능 | 상태 | 비고 |
84
- |------|------|------|
85
- | `init` | ✅ 정상 | bridge 파일, config, 디렉토리 생성, 자동 스캔 |
86
- | `doctor`/`status` | ✅ 정상 | safe-mode, strict 모드, JSON 출력 |
87
- | `brief` | ✅ 정상 | text/JSON, action cards, unknown workflow 처리 |
88
- | `add skill/workflow/harness` | ✅ 정상 | dry-run, 자동 status 승격 |
89
- | `activate`/`block`/`quarantine` | ✅ 정상 | workflow-scoped |
90
- | `can-use`/`guard` | ✅ 정상 | 정책 위반 시 거부 |
91
- | `impact disable` | ✅ 정상 | affected workflows/alternatives/risk |
92
- | `remove skill` | ✅ 정상 | 참조 시 거부, `--force`로 정리 |
93
- | `uninstall` | ✅ 정상 | 보수적 제거, dry-run |
94
- | `inventory refresh`/`detect` | ✅ 정상 | runtime component 감지 |
95
- | `sources refresh`/`audit` | ✅ 정상 | Git source digest pin |
96
- | `import`/`merge` | ✅ 정상 | built-in profiles |
97
- | `check` | ✅ 정상 | policy reference/rules |
98
- | `dashboard` | ✅ 정상 | markdown 보고서 |
99
- | `hook install` | ✅ 정상 | dry-run preview |
100
-
101
- ### 4. 핵심 코드 품질 관찰
102
-
103
- - **정책 엔진**: `src/domain/rules/*.mjs`가 rule-id 기반으로 깔끔하게 분리되어 있어 새 규칙 추가가 쉬움.
104
- - **workspace 로딩**: `workspace.mjs`가 config 파싱과 설치 skill discovery를 분리. `SKILL.md` frontmatter 강제는 정합성을 위해 필요하지만, 에러 메시지가 개선되어야 함.
105
- - **control.mjs**: 거대 파일. CRUD, policy runtime, source classification, hook 설치 등을 분리하면 가독성과 테스트 용이성이 향상.
106
- - **writeCheckedConfig**: 임시 파일에 쓰고 policy + usability 검증 후 rename하는 방식은 안전함. dry-run과 실제 적용의 경계도 명확.
107
- - **agent-inventory**: detector 기반 스캔이 확장 가능. 다만 detector matching이 경로 suffix에 의존해 Windows/Linux 경로를 모두 고려한 점은 긍정적.
108
-
109
- ## Plan
110
-
111
- ### Phase 1: 첫 5분 UX 다듬기 (4.1)
112
-
113
- - [x] `workspace.mjs`의 `parseSkillFrontmatter` 에러 메시지 개선
114
- - "SKILL.md is missing YAML frontmatter" → 필요한 frontmatter 예시와 docs/user-flow.md 링크 포함
115
- - 예상 영향: `src/workspace.mjs` 1함수, test 1~2개 추가
116
- - [x] `add workflow`에서 `--harness` 누락 시 usage dump 대신 사용 가능한 harness 목록 제시
117
- - 예상 영향: `src/cli.mjs` 또는 `src/control.mjs`의 `addWorkflow`
118
- - [x] `doctor`에 `--summary` 플래그 추가 (또는 기본 출력에서 1줄 status + 핵심 warnings만)
119
- - 예상 영향: `src/doctor.mjs`, `src/report.mjs` 수정
120
- - [x] CLI 글로벌 defaults 파일/디렉토리 탐지: `--config`, `--skills` 미지정 시 현재 디렉토리의 `skillboard.config.yaml`과 `skills/`를 기본으로 사용하도록 개선
121
- - 예상 영향: `src/cli.mjs` option parser, test 보강
122
-
123
- ### Phase 2: 생태계 연결 및 문서 (4.2)
124
-
125
- - [x] `CONTRIBUTING.md` 작성: 개발 환경, 테스트 실행, source profile 추가 방법
126
- - [x] built-in profile 추가 가이드 문서화 (`docs/adapters.md` 보강 또는 `docs/profiles.md` 신규)
127
- - [x] README의 install 전/후 명령어 섹션 정리 (`skillboard` vs `node bin/skillboard.mjs` 구분 강조)
128
- - [x] 본 프로젝트에 `AGENTS.md`/`CLAUDE.md` bridge 적용 검토 (dogfooding)
129
-
130
- ### Phase 3: 성능 및 구조 (4.3)
131
-
132
- - [x] `npm test` 실행 시간 프로파일링
133
- - 병목이 되는 CLI 통합 테스트 식별
134
- - 가능하다면 독립적인 단위 테스트와 통합 테스트 분리 (`npm run test:unit`, `npm run test:integration`)
135
- - [x] `src/control.mjs` 분리
136
- - `skill-crud.mjs`, `workflow-crud.mjs`, `trust-source.mjs`, `can-use-guard.mjs`, `config-write.mjs` 등으로 쪼개기
137
- - 예상 영향: 낶부 구조 개선, 기존 테스트 그대로 통과해야 함
138
- - [x] `doctor`/`brief`의 중복 workspace 로딩 최소화 (cache 또는 단일 로드 경로)
139
-
140
- ### Phase 4: 도메인 정제 (선택, 높은 가치)
141
-
142
- - [x] `status`/`invocation` 매트릭스 검토: 14×7 조합 중 실제로 사용되는 조합을 문서화하고, 불필요한 조합은 deprecate 또는 명시적 금지
143
- - [x] `capability`의 global 정의와 workflow-scope `required_capabilities` 관계를 docs에 명확히 시각화
144
- - [x] `install_unit`의 `trust_level`과 `permission_risk` 조합에 따른 자동 권고 정책을 advisor action cards로 노출
145
-
146
- ## TDD Notes
147
-
148
- - Red: Add failing tests for newly invalid status/invocation combos, capability docs, trust/risk action cards.
149
- - Green: Implement matrix, docs, and action card logic.
150
- - Refactor: `control.mjs` split into `src/control/*.mjs` modules; public API preserved.
151
-
152
- ## Verification
153
-
154
- - Commands to run:
155
- - `npm run diagnostics`
156
- - `npm run test:unit`
157
- - `npm run test:integration`
158
- - `npm run check`
159
- - `node bin/skillboard.mjs brief --config skillboard.config.yaml --skills skills`
160
- - `git diff --check`
161
- - Results:
162
- - TypeScript diagnostics: ✅
163
- - `npm run test:unit`: 47 passed
164
- - `npm run test:integration`: 103 passed
165
- - `npm run check`: 161 passed
166
- - CLI smoke test: ✅
167
- - `git diff --check`: ✅
168
-
169
- ## Decisions
170
-
171
- - **즉시 개선 권장**: 4.1 frontmatter 에러 메시지, `--config/--skills` 기본값, `doctor --summary`
172
- - **중기 개선 권장**: `control.mjs` 분리, test suite 분리, `CONTRIBUTING.md`
173
- - **도메인 설계는 유지**: 5개 엔티티 구조와 deny-by-default 정책은 변경하지 않음. 세부 상태/호출 매트릭스만 정제
174
- - **변경사항은 unstaged로 보관**: 사용자가 직접 커밋 지시 전까지 git index에 추가하지 않음
175
-
176
- ## Resume State
177
-
178
- - Done: Phase 1~4 모두 완료. 모든 테스트 통과. 문서/워크로그 정리 완료.
179
- - In progress: 없음.
180
- - Next command: 사용자가 커밋/푸시 지시 또는 추가 개선 항목 제시
181
- - Open risks:
182
- - `.skillboard/`와 `.omo/` 등 untracked artifact는 별도 정리 필요
183
- - npm pack 시 포함 여부는 `test/package.test.mjs`에서 검증 완료
184
-
185
- ## Progress Log
186
-
187
- - 2026-06-25T08:00:25Z: Plan created.
188
- - 2026-06-25T08:45:00Z: Domain audit, friction analysis, and improvement plan written.
189
- - 2026-06-25T10:05:00Z: Phase 1~4 implementation completed. All 161 tests passing.
@@ -1,20 +0,0 @@
1
- # Agent Handoff Plans
2
-
3
- This directory contains durable plans that can be picked up by another agent
4
- (such as Hermes) when the original author is not available.
5
-
6
- ## Conventions
7
-
8
- - Each plan file is named `<timestamp>-<slug>.md`.
9
- - The `Status:` field in the frontmatter controls the lifecycle:
10
- - `pending` — waiting for an agent to pick it up
11
- - `assigned` — an agent is currently working on it
12
- - `consumed` — the agent has finished the planned work
13
- - Agents should only pick up files with `Status: pending`.
14
- - After picking up a plan, change the status to `assigned` and commit.
15
- - After completing the work, change the status to `consumed` and commit.
16
-
17
- ## Current Plans
18
-
19
- - `20260625-080025-skillboard-mvp-review.md` — SkillBoard MVP feature/domain
20
- review and UX improvement plan (Status: completed)
@@ -1,56 +0,0 @@
1
- # SkillBoard Variant Lifecycle Handoff Plan
2
-
3
- This document was the handoff point for continuing the SkillBoard variant lifecycle implementation in `/home/nyxxir/skillboard`.
4
-
5
- ## Status
6
-
7
- Completed on 2026-06-29.
8
-
9
- The authoritative execution plan was `.omo/plans/skillboard-variant-lifecycle.md`; all Todos 1-8 and final verification wave F1-F4 were completed. Ignored orchestration artifacts under `.omo/` and `.agent-work/` contain the detailed evidence and continuity logs.
10
-
11
- ## Implemented Scope
12
-
13
- The feature adds a manual, auditable lifecycle for cross-agent skill variants:
14
-
15
- - `skillboard variant fork`
16
- - `skillboard variant status`
17
- - `skillboard variant approve`
18
- - `skillboard variant reset`
19
- - nested `skills.<id>.variant` metadata
20
- - digest-backed raw `SKILL.md` snapshots
21
- - documentation and tests for manual cross-agent adaptation
22
-
23
- ## Product Decisions Preserved
24
-
25
- - `variant add` remains the existing immediate policy-registration command.
26
- - New lifecycle commands are additive: `fork`, `status`, `approve`, `reset`.
27
- - A draft fork is policy-valid but not callable:
28
- - top-level `status: candidate`
29
- - top-level `invocation: manual-only`
30
- - no workflow active/preferred/fallback role until approval
31
- - `variant.status` is nested lifecycle metadata only. Top-level skill statuses were not expanded with `draft` or `approved`.
32
- - Snapshot files are raw `SKILL.md` content only.
33
- - Snapshot paths are config-relative and stay under `.skillboard/variant-snapshots/`.
34
- - Drift is computed from file digests; `drifted` is not persisted in config.
35
- - The implementation does not add automatic prompt conversion, LLM calls, new dependencies, or prompt rewriting.
36
-
37
- ## Verification Summary
38
-
39
- Final verification passed:
40
-
41
- - `npm run check` → 244/244 tests pass.
42
- - Focused lifecycle suite → 24/24 tests pass.
43
- - Manual CLI QA evidence was written under `.omo/evidence/manual-variant-lifecycle/`.
44
- - F1-F4 evidence files were written under `.omo/evidence/`.
45
- - Independent final no-edit review passed with no blockers.
46
- - `git diff --check` and untracked whitespace checks passed.
47
-
48
- ## Final Commit
49
-
50
- Planned commit message:
51
-
52
- ```text
53
- feat(control): add variant lifecycle management
54
- ```
55
-
56
- Do not push unless the user explicitly asks.