From f1868b3a960472bcceefb5b914d140691aa2144e Mon Sep 17 00:00:00 2001 From: David Christensen Date: Thu, 29 Oct 2026 11:51:16 -0400 Subject: [PATCH 1/5] docs: add Bob install requirements document Records the minimum file tree, plugin-root resolution behaviour, symlink-following caveats, skill naming, collision/idempotency rules, Bob-unsupported features, and open blocking decisions for a future Bob installer. Each claim is marked verified or unverified with the environment used. Closes #478 --- docs/bob-install-requirements.md | 219 ++++++++++++++++++ .../specs/478-bob-install-requirements.md | 40 ++++ 2 files changed, 259 insertions(+) create mode 100644 docs/bob-install-requirements.md create mode 100644 docs/workflow/specs/478-bob-install-requirements.md diff --git a/docs/bob-install-requirements.md b/docs/bob-install-requirements.md new file mode 100644 index 0000000..6628352 --- /dev/null +++ b/docs/bob-install-requirements.md @@ -0,0 +1,219 @@ +# IBM Bob install requirements + +This document records what a Bob user must supply to make adept skills work, and what +open decisions block a future installer. Each claim is marked **verified** or **unverified** +with the environment in which it was checked. + +Verification key: +- **verified** — confirmed by static inspection of this repository (source code, documentation). + Environment: macOS arm64, repository HEAD at `feat/bob-install-requirements-478` + (2026-10-29), no live Bob session. +- **unverified** — not yet confirmed against a live Bob instance or documented by IBM. + The stated behaviour is derived from Bob's published documentation, repository source, + or logical inference and should be tested before an installer is written. + +Related: issue #478, ADR 0001 (`docs/adr/0001-distribution-via-plugin-marketplace.md`). + +--- + +## 1. Minimum file tree + +A Bob install must produce the following tree for adept skills to work. +All paths are verified from repository source unless noted otherwise. + +### Global install (`~/.bob/skills/`) + +``` +~/.bob/ +└── skills/ + ├── attunement/ # all files from skills/attunement/ + ├── bounty/ + ├── campaign/ + ├── … (one directory per skill) … + └── quest/ +references/ # all 11 files from references/ at repo root + ├── dispatch-liveness.md + ├── heed-counsel.md + ├── merge-gate.md + ├── model-mapping.md + ├── model-selection.md + ├── network-bounds.md + ├── numbered-reservations.md + ├── review-depth.md + ├── review-lenses.md + ├── trial-by-fire.md + └── true-seeing.md +scripts/ +└── check-public-safety.sh # root-level wrapper +``` + +**Note on `scripts/check-public-safety.sh`:** **verified** — this file +(`scripts/check-public-safety.sh:3–9`) resolves `ROOT` as the directory two levels above +itself and then `exec`s `$ROOT/skills/quest/scripts/check-public-safety "$@"`. A Bob install +that copies only the `skills/` tree will not have this wrapper and will not have the inner +scanner. A full tree copy is required. The inner scanner lives at +`skills/quest/scripts/check-public-safety`. + +**Note on `references/` location:** **verified** — every script that addresses shared +standards uses a path like `../../references/` relative to a skill's own subdirectory +(e.g. `skills/quest/SKILL.md:57`, `skills/forge/SKILL.md:239`). The directory must be a +sibling of `skills/`, not nested inside it. + +### Project install (`/.bob/skills/`) + +Same tree as the global install, but rooted at `/.bob/` instead of `~/.bob/`. Bob's +skill location docs state that project skills take precedence over global ones on name +collision (see §4 below), so a project install can shadow a global one. + +--- + +## 2. `` resolution: copy install vs symlink install + +The `` convention is defined in skill text as "the directory two levels above +this skill's own directory" (e.g. `skills/attunement/SKILL.md:33–36`). Scripts resolve it at +runtime using `$BASH_SOURCE[0]`. + +**Copy install** (all files copied into `~/.bob/`): **verified** — all scripts resolve +ROOT correctly because the physical directory three levels up from any script is the copy +root. Both logical (`cd --`) and physical (`cd -P`) resolution agree when no symlinks are +present. + +**Symlink install** (skill directories symlinked into `~/.bob/skills/`): +**unverified** — behaviour depends on whether each script uses logical or physical `cd`: + +| Script | Resolution | Expected symlink behaviour | +|--------|-----------|---------------------------| +| `skills/deliver/scripts/deliver-write` | logical (`cd -- "$SCRIPT_DIR/../../.."`) | Resolves to the directory the symlink points into, i.e. the checkout, not `~/.bob/` | +| `skills/return-to-town/scripts/publish-handoff` | physical (`cd -P -- "$SCRIPT_DIR/../../.."`) | Resolves to the physical checkout directory | +| `skills/return-to-town/scripts/refresh-merge` | physical (`cd -P -- "$SCRIPT_DIR/../../.."`) | Resolves to the physical checkout directory | +| `skills/quest/scripts/publish-forge-review` | logical (`cd "$SCRIPT_DIR"`) then `../../..` | Resolves to checkout | +| `skills/bounty/scripts/create-verified-issue.sh` | physical (`pwd -P`) | Resolves to physical checkout | + +The issue evidence section (`Evidence:Symlink sensitivity`) measured this on macOS arm64 and +found that logical resolution (`deliver-write`) resolved ROOT to the Bob directory while +physical resolution (`publish-handoff`) resolved it to the checkout. Both approaches break +the assumption that ROOT contains `scripts/check-public-safety.sh` and `references/`, +unless those paths exist in both the checkout and the install target, or a symlink forest +replicates the full expected tree. + +**Supported path:** A copy install (no symlinks) is the only configuration where all +scripts agree on ROOT. A symlink install requires additional work to ensure ROOT-relative +lookups resolve consistently across scripts; this work has not been done. + +--- + +## 3. Symlink following and reload behaviour + +**Bob IDE (symlinks):** **unverified** — Bob's sandboxing documentation states that "symlinks +pointing outside the project directory may not work correctly" (Bob Shell sandboxing page, +File system limitations). Bob IDE's analogous sandboxing behaviour for skill directories is +not separately documented. Whether a symlinked `~/.bob/skills/` directory is followed +when loading skill content is not confirmed. + +**Bob Shell (symlinks):** **unverified** — same caveat as above applies to Bob Shell's file +system access model. + +**Reload:** **unverified** — the Bob IDE skills documentation states that "Skills load once +per conversation to avoid duplicate prompts." Whether newly added skill directories appear +without restarting Bob (IDE or Shell) is not documented. Best practice assumption: open a +new conversation or restart Bob after placing new skill directories. + +--- + +## 4. How a skill's directory is named to the model + +**verified (from Bob documentation):** The `name` field in `SKILL.md` frontmatter is "the +skill's display name used in the Bob interface." The `use_skill` tool takes a `skill_name` +parameter that Bob matches against this `name` field, not against the directory name. + +**Consequence for adept:** Each adept skill already sets its `name` field in its `SKILL.md` +frontmatter (e.g. `name: attunement`, `name: quest`). The directory name under +`~/.bob/skills/` does not need to match the `name` field, but using the same name as the +directory (as adept already does) avoids confusion. + +**Harness naming at load time:** **verified** — skills refer to a `` that +"the harness names when it loads the skill" (e.g. `skills/attunement/SKILL.md:35–36`, +`skills/quest/SKILL.md:174–175`). Under Claude Code, the harness injects the plugin cache +path as this root. Under Bob, no equivalent injection exists; scripts that rely on this +convention will not receive a harness-supplied root, so ROOT derivation falls to the +`cd`-based resolution described in §2. + +--- + +## 5. Collision and idempotency rules + +**Priority:** **verified (from Bob documentation)** — if both `/.bob/skills/` and +`~/.bob/skills/` contain a skill with the same `name` field, the project-level skill takes +precedence. Since adept's skill names are unique within the repository but not globally +reserved, a user with a pre-existing skill using the same name would have it silently shadowed +(global → project) or shadow adept's copy (project pre-existing → new global install). + +**Pre-existing `~/.bob/skills/` content:** **unverified** — no documentation describes what +happens if the target directory exists and contains files adept did not create. A copy-based +install would need to merge directories rather than replace them. Idempotency and +non-destructive behaviour of a copy install have not been tested. + +**Pre-existing `~/.bob/references/`:** **unverified** — adept's `references/` tree is +at the repository root, not under `~/.bob/references/`. How to install it (copy to +`~/.bob/references/`, a separate path sibling to `skills/`, or another location) has not +been decided. If `~/.bob/references/` already contains user-authored files, a naive copy +could clobber them. + +**Re-running after an update:** **unverified** — update semantics (overwrite, merge, skip) +for an already-installed tree are undefined. Any installer must define an explicit update +strategy. + +--- + +## 6. adept features with no Bob equivalent + +The following adept capabilities are Claude Code– and Codex-specific and have no Bob +equivalent at the time of writing: + +| Feature | adept location | Bob status | +|---------|---------------|-----------| +| Slash-command syntax (`$quest`, `$forge`, etc.) | Skill descriptions reference these as invocation patterns used by Claude Code / Codex operators | **unverified** — Bob supports slash commands but adept's skills are invoked via `use_skill`, not slash commands; the `$name` shorthand is a Claude Code convention | +| `agents/openai.yaml` per-skill worker manifests | `skills/*/agents/openai.yaml` (22 skills ship these) | **verified** — no Bob equivalent: Bob has no plugin system that reads per-skill worker manifests; these files are Codex CLI–specific | +| Plugin marketplace manifest | `.claude-plugin/marketplace.json`, `.codex-plugin/plugin.json` | **verified** — Bob has no plugin marketplace; skills must be placed manually | +| Version field | `.claude-plugin/marketplace.json` (via ADR 0022) | **verified** — not relevant to Bob install | + +**`agents/openai.yaml` detail:** Each file provides a Codex CLI interface definition (display +name, short description, default prompt) used when a skill is invoked as an OpenAI Codex +agent. Bob does not read these files. A Bob install does not need to place them, but +including them as part of a full-tree copy is harmless. + +--- + +## 7. Open decisions blocking an installer + +Two existing records conflict with writing a Bob installer: + +### ADR 0001 — Distribution via a plugin marketplace + +`docs/adr/0001-distribution-via-plugin-marketplace.md` (Accepted 2026-08-11) states: +> "There is no install script and there will not be one. The harness owns install, update, +> uninstall, and caching." + +This decision was made in the context of Claude Code and Codex. It did not anticipate a +Bob user who must hand-place files. A new ADR would need to supersede or amend this +decision before an install script targeting Bob could be added to this repository. + +### Plan note — "Bob is retired" (2026-08-11) + +`docs/workflow/plans/2026-08-11-adept-dotfiles-separation.md:18` states: +> "Bob is retired. Task 9 is skipped in full; nothing under `$OLD/agents/bob/` is +> carried into either new repo, and Bob-related issues close as obsolete in Task 11." + +Line 979 of the same plan records that Bob "has no plugin system" and a +clone-plus-symlink approach "was never executed." + +### Resolution required + +An installer cannot be written and reviewed until either: +1. An ADR supersedes the "no install script" clause of ADR 0001 for the Bob target, **and** +2. The project explicitly reverses the "Bob is retired" decision, opening Bob as a + supported target. + +This document records the requirements and constraints; it does not resolve these +decisions. See issue #478 for the proposed approach: file the installer as a separate +follow-up only after these decisions are made. diff --git a/docs/workflow/specs/478-bob-install-requirements.md b/docs/workflow/specs/478-bob-install-requirements.md new file mode 100644 index 0000000..ece9ed8 --- /dev/null +++ b/docs/workflow/specs/478-bob-install-requirements.md @@ -0,0 +1,40 @@ +# Light Spec: Bob Install Requirements Document (issue #478) + +## Problem + +adept has no written record of what a Bob user must supply to make its skills work. +The skills depend on a `` layout that the Claude Code and Codex harnesses provide +automatically; Bob has no equivalent plugin system, so the layout must be hand-supplied and is +currently undocumented. An installer cannot be specified or reviewed until these requirements +are written down and verified. + +## Scope + +One new file: `docs/bob-install-requirements.md`. No changes to existing files. +Not in scope: writing an installer, resolving the ADR 0001 / "Bob is retired" contradiction, +or live Bob environment verification (items requiring runtime observation are marked unverified). + +## Success + +`docs/bob-install-requirements.md` exists and covers all seven items from issue #478 §Expected: +1. Minimum file tree for global (`~/.bob`) and project (`.bob`) scope, including `references/` + and `scripts/check-public-safety.sh`. +2. `` resolution for copy vs symlink install, per script, with supported path stated. +3. Whether Bob IDE and Bob Shell follow symlinked skill folders; reload behavior. +4. How a skill's directory is named to the model under Bob. +5. Collision and idempotency rules for pre-existing content and re-runs. +6. adept features with no Bob equivalent (slash-command syntax, `agents/openai.yaml`). +7. Open decisions blocking an installer (ADR 0001 conflict, "Bob is retired" plan note). + +Each claim carries a `verified` or `unverified` marker and the environment it was checked in. + +## Validation + +- `docs/bob-install-requirements.md` exists and is tracked by git. +- All seven items from the issue appear in the document. +- Every factual claim carries a verification marker. +- `just verify` passes (lint, test, records, shape). + +## Failure model + +N/A — this is a documentation-only change. No executable failure model applies. From f7a347bf34f6cadd34624398ab8e436b7bd0ca4b Mon Sep 17 00:00:00 2001 From: David Christensen Date: Thu, 29 Oct 2026 11:54:32 -0400 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20address=20review=20findings=20?= =?UTF-8?q?=E2=80=94=20correct=20citations,=20markers,=20and=20version=20b?= =?UTF-8?q?ump?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add 'documented' verification marker for Bob-docs-sourced claims - Fix file tree ASCII diagram to show references/ and scripts/ as siblings of skills/ inside ~/.bob/ - Correct ADR 0001 quote attribution (text is from CLAUDE.md, not ADR) - Fix version-field table row to cite plugin.json, not marketplace.json - Fix plan citation from line 979 to line 969 for the SKIPPED header - Attribute symlink measurement to issue body, not a re-run - Bump plugin version to 7.12.3 (required per-PR edit, ADR 0022) --- .claude-plugin/plugin.json | 2 +- docs/bob-install-requirements.md | 74 +++++++++++++++++--------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 66e9f89..bc959ef 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "adept", - "version": "7.12.2", + "version": "7.12.3", "icon": "docs/assets/adept-logo-grimoire.png", "description": "Development-workflow skills: design, TDD, adversarial review, shipping, and campaign orchestration for Claude Code and Codex.", "author": { diff --git a/docs/bob-install-requirements.md b/docs/bob-install-requirements.md index 6628352..a32f77a 100644 --- a/docs/bob-install-requirements.md +++ b/docs/bob-install-requirements.md @@ -6,11 +6,12 @@ with the environment in which it was checked. Verification key: - **verified** — confirmed by static inspection of this repository (source code, documentation). - Environment: macOS arm64, repository HEAD at `feat/bob-install-requirements-478` - (2026-10-29), no live Bob session. + Environment: macOS arm64, 2026-10-29, no live Bob session. +- **documented** — stated in Bob's published documentation but not tested against a live Bob + instance in this run. - **unverified** — not yet confirmed against a live Bob instance or documented by IBM. - The stated behaviour is derived from Bob's published documentation, repository source, - or logical inference and should be tested before an installer is written. + The stated behaviour is derived from repository source or logical inference and should be + tested before an installer is written. Related: issue #478, ADR 0001 (`docs/adr/0001-distribution-via-plugin-marketplace.md`). @@ -25,26 +26,26 @@ All paths are verified from repository source unless noted otherwise. ``` ~/.bob/ -└── skills/ - ├── attunement/ # all files from skills/attunement/ - ├── bounty/ - ├── campaign/ - ├── … (one directory per skill) … - └── quest/ -references/ # all 11 files from references/ at repo root - ├── dispatch-liveness.md - ├── heed-counsel.md - ├── merge-gate.md - ├── model-mapping.md - ├── model-selection.md - ├── network-bounds.md - ├── numbered-reservations.md - ├── review-depth.md - ├── review-lenses.md - ├── trial-by-fire.md - └── true-seeing.md -scripts/ -└── check-public-safety.sh # root-level wrapper +├── skills/ +│ ├── attunement/ # all files from skills/attunement/ +│ ├── bounty/ +│ ├── campaign/ +│ ├── … (one directory per skill) … +│ └── quest/ +├── references/ # all 11 files from references/ at repo root +│ ├── dispatch-liveness.md +│ ├── heed-counsel.md +│ ├── merge-gate.md +│ ├── model-mapping.md +│ ├── model-selection.md +│ ├── network-bounds.md +│ ├── numbered-reservations.md +│ ├── review-depth.md +│ ├── review-lenses.md +│ ├── trial-by-fire.md +│ └── true-seeing.md +└── scripts/ + └── check-public-safety.sh # root-level wrapper ``` **Note on `scripts/check-public-safety.sh`:** **verified** — this file @@ -89,9 +90,10 @@ present. | `skills/quest/scripts/publish-forge-review` | logical (`cd "$SCRIPT_DIR"`) then `../../..` | Resolves to checkout | | `skills/bounty/scripts/create-verified-issue.sh` | physical (`pwd -P`) | Resolves to physical checkout | -The issue evidence section (`Evidence:Symlink sensitivity`) measured this on macOS arm64 and -found that logical resolution (`deliver-write`) resolved ROOT to the Bob directory while -physical resolution (`publish-handoff`) resolved it to the checkout. Both approaches break +The issue body (`Evidence: Symlink sensitivity`) reported a measurement on macOS arm64 +(not re-run in this review) finding that logical resolution (`deliver-write`) resolved ROOT +to the Bob directory while physical resolution (`publish-handoff`) resolved it to the +checkout. Both approaches break the assumption that ROOT contains `scripts/check-public-safety.sh` and `references/`, unless those paths exist in both the checkout and the install target, or a symlink forest replicates the full expected tree. @@ -122,7 +124,7 @@ new conversation or restart Bob after placing new skill directories. ## 4. How a skill's directory is named to the model -**verified (from Bob documentation):** The `name` field in `SKILL.md` frontmatter is "the +**documented (Bob documentation):** The `name` field in `SKILL.md` frontmatter is "the skill's display name used in the Bob interface." The `use_skill` tool takes a `skill_name` parameter that Bob matches against this `name` field, not against the directory name. @@ -142,7 +144,7 @@ convention will not receive a harness-supplied root, so ROOT derivation falls to ## 5. Collision and idempotency rules -**Priority:** **verified (from Bob documentation)** — if both `/.bob/skills/` and +**Priority:** **documented (Bob documentation)** — if both `/.bob/skills/` and `~/.bob/skills/` contain a skill with the same `name` field, the project-level skill takes precedence. Since adept's skill names are unique within the repository but not globally reserved, a user with a pre-existing skill using the same name would have it silently shadowed @@ -175,7 +177,7 @@ equivalent at the time of writing: | Slash-command syntax (`$quest`, `$forge`, etc.) | Skill descriptions reference these as invocation patterns used by Claude Code / Codex operators | **unverified** — Bob supports slash commands but adept's skills are invoked via `use_skill`, not slash commands; the `$name` shorthand is a Claude Code convention | | `agents/openai.yaml` per-skill worker manifests | `skills/*/agents/openai.yaml` (22 skills ship these) | **verified** — no Bob equivalent: Bob has no plugin system that reads per-skill worker manifests; these files are Codex CLI–specific | | Plugin marketplace manifest | `.claude-plugin/marketplace.json`, `.codex-plugin/plugin.json` | **verified** — Bob has no plugin marketplace; skills must be placed manually | -| Version field | `.claude-plugin/marketplace.json` (via ADR 0022) | **verified** — not relevant to Bob install | +| Version field | `.claude-plugin/plugin.json` (via ADR 0022) | **verified** — not relevant to Bob install | **`agents/openai.yaml` detail:** Each file provides a Codex CLI interface definition (display name, short description, default prompt) used when a skill is invoked as an OpenAI Codex @@ -190,9 +192,10 @@ Two existing records conflict with writing a Bob installer: ### ADR 0001 — Distribution via a plugin marketplace -`docs/adr/0001-distribution-via-plugin-marketplace.md` (Accepted 2026-08-11) states: -> "There is no install script and there will not be one. The harness owns install, update, -> uninstall, and caching." +`docs/adr/0001-distribution-via-plugin-marketplace.md` (Accepted 2026-08-11) records +that the harness owns "install, update, uninstall, caching, and version resolution" and +that `install.sh` (1,337 lines) has no successor. `.claude/CLAUDE.md:7` restates this as +"There is no install script and there will not be one." This decision was made in the context of Claude Code and Codex. It did not anticipate a Bob user who must hand-place files. A new ADR would need to supersede or amend this @@ -204,8 +207,9 @@ decision before an install script targeting Bob could be added to this repositor > "Bob is retired. Task 9 is skipped in full; nothing under `$OLD/agents/bob/` is > carried into either new repo, and Bob-related issues close as obsolete in Task 11." -Line 979 of the same plan records that Bob "has no plugin system" and a -clone-plus-symlink approach "was never executed." +Line 969 of the same plan records Task 9 as "SKIPPED (Bob retired 2026-08-11)." Line 979 +records that Bob "has no plugin system" and describes a clone-plus-symlink approach that +was planned but never executed. ### Resolution required From 35179234fa17a11e7a6d210190a49ac8b3484ae5 Mon Sep 17 00:00:00 2001 From: David Christensen Date: Thu, 29 Oct 2026 12:02:00 -0400 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20address=20second=20review=20?= =?UTF-8?q?=E2=80=94=20correct=20symlink=20direction,=20markers,=20and=20r?= =?UTF-8?q?efs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix §2 symlink table: logical-cd scripts resolve to ~/.bob/, not checkout; physical-cd scripts resolve to checkout (split, not both fail) - Fix §4 harness injection claim: mark as unverified under Bob - Fix §6 table: use 'documented' for Bob-docs claims; correct marketplace description to 'skills marketplace'; fix convention attribution - Fix §1 cross-reference from §4 to §5 - Fix plan line citation from 979 to 969 for SKIPPED header - Update spec scope note to account for mandatory plugin.json bump --- docs/bob-install-requirements.md | 53 +++++++++---------- .../specs/478-bob-install-requirements.md | 2 + 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/docs/bob-install-requirements.md b/docs/bob-install-requirements.md index a32f77a..041f1b8 100644 --- a/docs/bob-install-requirements.md +++ b/docs/bob-install-requirements.md @@ -64,7 +64,7 @@ sibling of `skills/`, not nested inside it. Same tree as the global install, but rooted at `/.bob/` instead of `~/.bob/`. Bob's skill location docs state that project skills take precedence over global ones on name -collision (see §4 below), so a project install can shadow a global one. +collision (see §5 below), so a project install can shadow a global one. --- @@ -82,25 +82,25 @@ present. **Symlink install** (skill directories symlinked into `~/.bob/skills/`): **unverified** — behaviour depends on whether each script uses logical or physical `cd`: -| Script | Resolution | Expected symlink behaviour | -|--------|-----------|---------------------------| -| `skills/deliver/scripts/deliver-write` | logical (`cd -- "$SCRIPT_DIR/../../.."`) | Resolves to the directory the symlink points into, i.e. the checkout, not `~/.bob/` | -| `skills/return-to-town/scripts/publish-handoff` | physical (`cd -P -- "$SCRIPT_DIR/../../.."`) | Resolves to the physical checkout directory | -| `skills/return-to-town/scripts/refresh-merge` | physical (`cd -P -- "$SCRIPT_DIR/../../.."`) | Resolves to the physical checkout directory | -| `skills/quest/scripts/publish-forge-review` | logical (`cd "$SCRIPT_DIR"`) then `../../..` | Resolves to checkout | -| `skills/bounty/scripts/create-verified-issue.sh` | physical (`pwd -P`) | Resolves to physical checkout | +| Script | Resolution | ROOT under a symlink install | +|--------|-----------|------------------------------| +| `skills/deliver/scripts/deliver-write` | logical (`cd -- "$SCRIPT_DIR/../../.."`) | Resolves to `~/.bob/` (the directory containing `skills/`) | +| `skills/return-to-town/scripts/publish-handoff` | physical (`cd -P -- "$SCRIPT_DIR/../../.."`) | Resolves to the physical checkout | +| `skills/return-to-town/scripts/refresh-merge` | physical (`cd -P -- "$SCRIPT_DIR/../../.."`) | Resolves to the physical checkout | +| `skills/quest/scripts/publish-forge-review` | logical (`cd "$SCRIPT_DIR"`) then `../../..` | Resolves to `~/.bob/` | +| `skills/bounty/scripts/create-verified-issue.sh` | physical (`pwd -P`) | Resolves to the physical checkout | The issue body (`Evidence: Symlink sensitivity`) reported a measurement on macOS arm64 -(not re-run in this review) finding that logical resolution (`deliver-write`) resolved ROOT -to the Bob directory while physical resolution (`publish-handoff`) resolved it to the -checkout. Both approaches break -the assumption that ROOT contains `scripts/check-public-safety.sh` and `references/`, -unless those paths exist in both the checkout and the install target, or a symlink forest -replicates the full expected tree. +(not re-run in this review) confirming the table's split result: logical-`cd` scripts +resolve ROOT to `~/.bob/`, while physical-`cd` scripts resolve it to the checkout. The +scripts therefore disagree with each other. A logical-`cd` script expects to find +`references/` and `scripts/check-public-safety.sh` inside `~/.bob/`; a physical-`cd` script +expects them in the checkout. Neither assumption holds for both script types simultaneously. **Supported path:** A copy install (no symlinks) is the only configuration where all -scripts agree on ROOT. A symlink install requires additional work to ensure ROOT-relative -lookups resolve consistently across scripts; this work has not been done. +scripts agree on ROOT. A symlink install requires additional work (e.g. a symlink forest in +`~/.bob/` that mirrors `references/` and `scripts/`) to satisfy both; this work has not been +done. --- @@ -126,19 +126,18 @@ new conversation or restart Bob after placing new skill directories. **documented (Bob documentation):** The `name` field in `SKILL.md` frontmatter is "the skill's display name used in the Bob interface." The `use_skill` tool takes a `skill_name` -parameter that Bob matches against this `name` field, not against the directory name. +parameter; Bob matches it against this `name` field. -**Consequence for adept:** Each adept skill already sets its `name` field in its `SKILL.md` -frontmatter (e.g. `name: attunement`, `name: quest`). The directory name under -`~/.bob/skills/` does not need to match the `name` field, but using the same name as the -directory (as adept already does) avoids confusion. +**unverified:** Whether the directory name under `~/.bob/skills/` affects resolution (vs the +`name` field) is inferred, not confirmed by Bob documentation. Each adept skill already sets +a `name` field matching its directory name (e.g. `name: attunement`), so this ambiguity +does not affect adept in practice. **Harness naming at load time:** **verified** — skills refer to a `` that "the harness names when it loads the skill" (e.g. `skills/attunement/SKILL.md:35–36`, `skills/quest/SKILL.md:174–175`). Under Claude Code, the harness injects the plugin cache -path as this root. Under Bob, no equivalent injection exists; scripts that rely on this -convention will not receive a harness-supplied root, so ROOT derivation falls to the -`cd`-based resolution described in §2. +path as this root. **unverified** — under Bob, whether an equivalent injection exists is not +documented; if it does not, ROOT derivation falls to the `cd`-based resolution in §2. --- @@ -174,9 +173,9 @@ equivalent at the time of writing: | Feature | adept location | Bob status | |---------|---------------|-----------| -| Slash-command syntax (`$quest`, `$forge`, etc.) | Skill descriptions reference these as invocation patterns used by Claude Code / Codex operators | **unverified** — Bob supports slash commands but adept's skills are invoked via `use_skill`, not slash commands; the `$name` shorthand is a Claude Code convention | -| `agents/openai.yaml` per-skill worker manifests | `skills/*/agents/openai.yaml` (22 skills ship these) | **verified** — no Bob equivalent: Bob has no plugin system that reads per-skill worker manifests; these files are Codex CLI–specific | -| Plugin marketplace manifest | `.claude-plugin/marketplace.json`, `.codex-plugin/plugin.json` | **verified** — Bob has no plugin marketplace; skills must be placed manually | +| `$name` invocation shorthand (e.g. `$quest`) | Skill descriptions reference these as shorthand used by Claude Code / Codex operators | **unverified** — Bob has slash commands but adept's skills are invoked via `use_skill`; the `$name` shorthand is a Codex agent convention, not a Bob convention | +| `agents/openai.yaml` per-skill worker manifests | `skills/*/agents/openai.yaml` (22 skills) | **documented** — Bob has no feature for per-skill worker manifests; these files are Codex CLI-specific (Bob docs describe no equivalent) | +| Skills plugin marketplace | `.claude-plugin/marketplace.json`, `.codex-plugin/plugin.json` | **documented** — Bob's marketplace covers MCP servers and modes, not skills; adept skills must be placed manually | | Version field | `.claude-plugin/plugin.json` (via ADR 0022) | **verified** — not relevant to Bob install | **`agents/openai.yaml` detail:** Each file provides a Codex CLI interface definition (display diff --git a/docs/workflow/specs/478-bob-install-requirements.md b/docs/workflow/specs/478-bob-install-requirements.md index ece9ed8..b5e1fc7 100644 --- a/docs/workflow/specs/478-bob-install-requirements.md +++ b/docs/workflow/specs/478-bob-install-requirements.md @@ -13,6 +13,8 @@ are written down and verified. One new file: `docs/bob-install-requirements.md`. No changes to existing files. Not in scope: writing an installer, resolving the ADR 0001 / "Bob is retired" contradiction, or live Bob environment verification (items requiring runtime observation are marked unverified). +One existing-file change is required: the mandatory `plugin.json` version bump (ADR 0022, +`just version-check`) that every PR touching the repository must include. ## Success From a3bb4f7c499d77b4ed33e99ff0a27c5c9c9c18ab Mon Sep 17 00:00:00 2001 From: David Christensen Date: Thu, 29 Oct 2026 12:03:29 -0400 Subject: [PATCH 4/5] fix: correct citation line numbers and check-public-safety.sh reference --- docs/bob-install-requirements.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/bob-install-requirements.md b/docs/bob-install-requirements.md index 041f1b8..36d3fcb 100644 --- a/docs/bob-install-requirements.md +++ b/docs/bob-install-requirements.md @@ -49,7 +49,7 @@ All paths are verified from repository source unless noted otherwise. ``` **Note on `scripts/check-public-safety.sh`:** **verified** — this file -(`scripts/check-public-safety.sh:3–9`) resolves `ROOT` as the directory two levels above +(`scripts/check-public-safety.sh:4,11`) resolves `ROOT` as the directory two levels above itself and then `exec`s `$ROOT/skills/quest/scripts/check-public-safety "$@"`. A Bob install that copies only the `skills/` tree will not have this wrapper and will not have the inner scanner. A full tree copy is required. The inner scanner lives at @@ -206,9 +206,10 @@ decision before an install script targeting Bob could be added to this repositor > "Bob is retired. Task 9 is skipped in full; nothing under `$OLD/agents/bob/` is > carried into either new repo, and Bob-related issues close as obsolete in Task 11." -Line 969 of the same plan records Task 9 as "SKIPPED (Bob retired 2026-08-11)." Line 979 -records that Bob "has no plugin system" and describes a clone-plus-symlink approach that -was planned but never executed. +Line 967 of the same plan carries the section heading "SKIPPED (Bob retired 2026-08-11)." +Line 969 records that "Bob is retired, `~/.bob` does not exist on this machine, and no Bob +deployment manifest is present." Line 979 records that Bob "has no plugin system" and +describes a clone-plus-symlink approach that was planned but never executed. ### Resolution required From 95913ccaed1f70f4957ba4762f497d72fb8b51c1 Mon Sep 17 00:00:00 2001 From: David Christensen Date: Thu, 29 Oct 2026 12:05:12 -0400 Subject: [PATCH 5/5] =?UTF-8?q?docs:=20simplify=20prose=20=E2=80=94=20tigh?= =?UTF-8?q?ten=20verification=20key,=20=C2=A73,=20=C2=A75,=20and=20spec=20?= =?UTF-8?q?scope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/bob-install-requirements.md | 43 ++++++------------- .../specs/478-bob-install-requirements.md | 8 ++-- 2 files changed, 16 insertions(+), 35 deletions(-) diff --git a/docs/bob-install-requirements.md b/docs/bob-install-requirements.md index 36d3fcb..2d1a403 100644 --- a/docs/bob-install-requirements.md +++ b/docs/bob-install-requirements.md @@ -1,17 +1,14 @@ # IBM Bob install requirements This document records what a Bob user must supply to make adept skills work, and what -open decisions block a future installer. Each claim is marked **verified** or **unverified** -with the environment in which it was checked. +open decisions block a future installer. Each claim is marked with one of three markers: -Verification key: - **verified** — confirmed by static inspection of this repository (source code, documentation). Environment: macOS arm64, 2026-10-29, no live Bob session. - **documented** — stated in Bob's published documentation but not tested against a live Bob instance in this run. -- **unverified** — not yet confirmed against a live Bob instance or documented by IBM. - The stated behaviour is derived from repository source or logical inference and should be - tested before an installer is written. +- **unverified** — neither tested against a live Bob instance nor documented by IBM. + Behaviour is inferred from repository source or logical inference. Related: issue #478, ADR 0001 (`docs/adr/0001-distribution-via-plugin-marketplace.md`). @@ -20,7 +17,6 @@ Related: issue #478, ADR 0001 (`docs/adr/0001-distribution-via-plugin-marketplac ## 1. Minimum file tree A Bob install must produce the following tree for adept skills to work. -All paths are verified from repository source unless noted otherwise. ### Global install (`~/.bob/skills/`) @@ -32,7 +28,7 @@ All paths are verified from repository source unless noted otherwise. │ ├── campaign/ │ ├── … (one directory per skill) … │ └── quest/ -├── references/ # all 11 files from references/ at repo root +├── references/ # files from references/ at repo root │ ├── dispatch-liveness.md │ ├── heed-counsel.md │ ├── merge-gate.md @@ -106,14 +102,11 @@ done. ## 3. Symlink following and reload behaviour -**Bob IDE (symlinks):** **unverified** — Bob's sandboxing documentation states that "symlinks -pointing outside the project directory may not work correctly" (Bob Shell sandboxing page, -File system limitations). Bob IDE's analogous sandboxing behaviour for skill directories is -not separately documented. Whether a symlinked `~/.bob/skills/` directory is followed -when loading skill content is not confirmed. - -**Bob Shell (symlinks):** **unverified** — same caveat as above applies to Bob Shell's file -system access model. +**Symlinks (IDE and Shell):** **unverified** — Bob Shell's sandboxing docs state that +"symlinks pointing outside the project directory may not work correctly" (sandboxing page, +File system limitations). Bob IDE has no separately documented sandboxing rule for skill +directories. Whether a symlinked `~/.bob/skills/` directory is followed when loading +skill content is not confirmed for either surface. **Reload:** **unverified** — the Bob IDE skills documentation states that "Skills load once per conversation to avoid duplicate prompts." Whether newly added skill directories appear @@ -149,20 +142,10 @@ precedence. Since adept's skill names are unique within the repository but not g reserved, a user with a pre-existing skill using the same name would have it silently shadowed (global → project) or shadow adept's copy (project pre-existing → new global install). -**Pre-existing `~/.bob/skills/` content:** **unverified** — no documentation describes what -happens if the target directory exists and contains files adept did not create. A copy-based -install would need to merge directories rather than replace them. Idempotency and -non-destructive behaviour of a copy install have not been tested. - -**Pre-existing `~/.bob/references/`:** **unverified** — adept's `references/` tree is -at the repository root, not under `~/.bob/references/`. How to install it (copy to -`~/.bob/references/`, a separate path sibling to `skills/`, or another location) has not -been decided. If `~/.bob/references/` already contains user-authored files, a naive copy -could clobber them. - -**Re-running after an update:** **unverified** — update semantics (overwrite, merge, skip) -for an already-installed tree are undefined. Any installer must define an explicit update -strategy. +**Pre-existing content and update semantics:** **unverified** — no documentation describes +what happens if `~/.bob/skills/` already exists, if `~/.bob/references/` already contains +user-authored files, or what "re-run after an update" means (overwrite, merge, skip). A +copy-based install would need to address all three. None has been tested. --- diff --git a/docs/workflow/specs/478-bob-install-requirements.md b/docs/workflow/specs/478-bob-install-requirements.md index b5e1fc7..2398f2d 100644 --- a/docs/workflow/specs/478-bob-install-requirements.md +++ b/docs/workflow/specs/478-bob-install-requirements.md @@ -10,11 +10,9 @@ are written down and verified. ## Scope -One new file: `docs/bob-install-requirements.md`. No changes to existing files. -Not in scope: writing an installer, resolving the ADR 0001 / "Bob is retired" contradiction, -or live Bob environment verification (items requiring runtime observation are marked unverified). -One existing-file change is required: the mandatory `plugin.json` version bump (ADR 0022, -`just version-check`) that every PR touching the repository must include. +One new file (`docs/bob-install-requirements.md`) plus the mandatory `plugin.json` version +bump (ADR 0022). Not in scope: writing an installer, resolving the ADR 0001 / "Bob is +retired" contradiction, or live Bob environment verification. ## Success