@mindrian_os/install 1.13.0-beta.11 → 1.13.0-beta.13

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.
Files changed (33) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +68 -3
  3. package/bin/cli.js +114 -57
  4. package/commands/act.md +16 -2
  5. package/commands/auto-explore.md +1 -0
  6. package/commands/doctor.md +1 -1
  7. package/commands/operator.md +1 -1
  8. package/commands/pipeline.md +16 -1
  9. package/commands/setup.md +7 -3
  10. package/commands/suggest-next.md +17 -3
  11. package/lib/core/active-plugin-root.cjs +207 -0
  12. package/lib/core/brain-client.cjs +451 -36
  13. package/lib/core/cache-prune.cjs +208 -0
  14. package/lib/core/framework-chain-composer.cjs +156 -43
  15. package/lib/core/migrations/phase-109-nodes-provenance.cjs +47 -0
  16. package/lib/core/navigation/memory-events.cjs +17 -1
  17. package/lib/core/navigation/neighborhood.cjs +5 -4
  18. package/lib/core/navigation/packet.cjs +87 -1
  19. package/lib/core/navigation.cjs +6 -0
  20. package/lib/core/resolve-brain-key.cjs +201 -0
  21. package/lib/hmi/jtbd-taxonomy.json +2 -1
  22. package/lib/memory/framework-chain-composer.test.cjs +54 -20
  23. package/lib/memory/navigation-hook-resolver.test.cjs +177 -0
  24. package/lib/memory/run-feynman-tests.cjs +102 -0
  25. package/lib/memory/security-trifecta.test.cjs +23 -6
  26. package/lib/memory/suggest-next-workflow.test.cjs +176 -0
  27. package/lib/memory/workflow-layer-e2e.test.cjs +262 -0
  28. package/lib/workflow/ROOM.md +1 -1
  29. package/package.json +4 -1
  30. package/references/brain/command-triggers-schema.md +10 -221
  31. package/references/methodology/index.md +11 -74
  32. package/skills/brain-connector/SKILL.md +12 -8
  33. package/skills/pws-methodology/SKILL.md +7 -5
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mos",
3
3
  "description": "MindrianOS -- Your AI innovation co-founder. Larry thinks with you through PWS methodology, builds your Data Room as you explore, and chains frameworks intelligently. Install and go.",
4
- "version": "1.13.0-beta.11",
4
+ "version": "1.13.0-beta.13",
5
5
  "author": {
6
6
  "name": "Jonathan Sagir",
7
7
  "url": "https://mindrian.ai"
package/CHANGELOG.md CHANGED
@@ -9,17 +9,82 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
  <!-- When onboarding: true, the onboard_steps list is shown to returning users in the What's New flow -->
10
10
  <!-- This allows new releases to automatically surface relevant guidance without code changes -->
11
11
 
12
- ## [Unreleased] -- v1.13.0-beta.11 (in progress)
12
+ ## [1.13.0-beta.13] - 2026-05-13
13
13
 
14
- beta.11 is the v1.13.0 CAPSTONE -- its headline content is the **Workflow Layer** (framework <-> command registry + reliable invocation; spec at `.planning/WORKFLOW-LAYER-SPEC.md`), not yet built. The items below are what has landed on `main` toward the capstone so far; the entry will be finalized (dated, full feature list) when the Workflow Layer ships. The capstone was re-numbered from beta.10 to beta.11 on 2026-05-12: `1.13.0-beta.10` had already been published to npm that day as a token-validation build (dist-tag `@next`, no git tag, not on the marketplace), so the tagged + marketplace'd capstone takes the next number.
14
+ ### Added
15
+
16
+ - **Install-state contract (Phase 123 Plans 02 + 03 -- HARNESS-123-05..10).** **One record** is the truth (`~/.mindrian/install-state.json`, written by `scripts/session-start` as the single writer in earliest steps; full D-04 snapshot incl. the 4 version-of-record cross-check values). **One manifest** says what should be on disk (`data/deployment-surfaces.json`, 6 hand-maintained surfaces with the D-07 schema -- id / `$HOME`-tokenized path / owner / topology_scope / check_kind / expected / reconcile / remediation; reused `data/` layout convention from Phase 122). **One command** enforces the contract: `mindrian-os doctor` gains two new drift classes -- **class I** (install-state record present + internally consistent + topology classification + 6-way version-of-record consistency tolerating non-semver 4-component versions like `1.12.5.1` via string-equality) + **class J** (deployment-surface manifest reconciliation with `path_within_file` extraction for JSON sub-fields like `settings.json.statusLine.command`) -- under one new flag `--install-state`; `--all` activates both. **Bug 7 dies**: a marketplace-cache-only install is a *healthy* topology, not drift -- "no legacy clone dir on a marketplace box" is expected, not a finding. Aggressive `doctor --fix` with hard guardrails (D-13): auto-recover missing record + drifted owned surfaces + wrong `~/.mindrian-last-version`; legacy-clone migration is backup-then-verify-then-remove and REFUSES on a dev-clone, uncommitted/unpushed work, or `MINDRIAN_OS_ROOT` pointing at the legacy dir; conservative `installed_plugins.json` repair (repoint at newest valid marketplace-cache dir, never wholesale rewrite, always back up first); 3 flag-only cases (`topology: not-found`, `$PATH` entry vanished, statusline-renders-wrong-version) reported with explicit remediation strings. `lib/core/active-plugin-root.cjs` extended with a `topology` field exposing `marketplace-cache | dev-clone | legacy | not-found`. Hermetic Wave-0 fixtures: `tests/test-install-state-record.cjs` (6/6) + `tests/test-doctor-class-i.cjs` (11/11) + `tests/test-doctor-class-j.cjs` (8/8) all green. (`scripts/session-start`, `lib/core/active-plugin-root.cjs`, `data/deployment-surfaces.json` [new], `data/ROOM.md`, `scripts/doctor.cjs`, `tests/test-install-state-record.cjs` [new], `tests/test-doctor-class-i.cjs` [new], `tests/test-doctor-class-j.cjs` [new], `lib/memory/run-feynman-tests.cjs`.)
17
+
18
+ - **`mindrian-os doctor --acceptance` release-gate command (Phase 123 Plan-04 -- HARNESS-123-11 + HARNESS-123-12).** Seven-point contract: (1) install-state record present + matches a live spot-check; (2) every owned deployment surface reconciled; (3) version-of-record consistent across `plugin.json` / `package.json` / CHANGELOG top entry / git tag / marketplace `source.ref` / published npm version; (4) `npx @mindrian_os/install` round-trip works (`mktemp -d`-backed `HOME`-sandbox -- the live install is never clobbered; `--light-npx` flag for slow networks asserts `npm view ... && npx ... --help` instead); (5) `doctor --all` exits 0. Two sub-modes: `--pre-tag` runs the 5 points knowable BEFORE the release (1, 2, 3-repo-half, 4-wrap-via-verify-release, 5); full `--acceptance` adds the 2 post-publish points (version-of-record-published + npx round-trip). Wraps `scripts/verify-release` -- no duplication. Wired into `scripts/release.sh` at Step 6.6 (`--pre-tag` before the tag) and Step 9.6 (full after the push); both HARD aborts, no override. Orchestration is node, shell-agnostic. "Release infrastructure ALWAYS ships as a beta validated by an external operator" now *means* "the operator ran `mindrian-os doctor --acceptance`, all green" -- not "the operator eyeballed the statusline." Hermetic Wave-0 test `tests/test-doctor-acceptance.cjs` (6/6) green. (`scripts/doctor.cjs`, `scripts/release.sh`, `tests/test-doctor-acceptance.cjs` [new], `scripts/release-beta-smoke.sh` [deleted].)
19
+
20
+ - **`scripts/release.sh` owns ALL version bumps incl. pre-releases (Phase 123 Plan-01 -- HARNESS-123-01..04).** Pre-release algebra via the `semver` npm package added as a **devDependency** (NOT a runtime dep -- stays out of the `files` allowlist; the published `@mindrian_os/install` tarball is still zero-runtime-dep). New flags: `--prerelease` (`beta.N -> beta.N+1` via `semver.inc(v, 'prerelease', 'beta')`); `--finalize` (promote a beta to its core via `semver.inc(v, 'patch')` -- which *strips* the suffix, so `1.13.0-beta.11 -> 1.13.0`, NOT `1.13.1`); `--start-prerelease <core> <channel>` (open a fresh series via `semver.inc(v, 'preminor', 'beta')`); `--allow-ahead` (escape hatch for the dirty-repo guard). **TWO-COMMIT next-bump form** (per RESEARCH override 1 -- verified against Claude Code's Version Management spec; `plugin.json` wins over the marketplace entry for installed-version reporting): commit A finalizes `CHANGELOG [vN]`, sets `plugin.json` + `package.json` to `vN`, the `vN` git tag points at commit A; commit B bumps to `vN+1` + resets the CHANGELOG `[Unreleased] -- vN+1` heading; `main` HEAD lands on commit B. `marketplace.json` `version` + `source.ref` pin to `vN` -- so an install via `ref: vN` checks out commit A and self-reports `vN`. **Dirty-repo / ahead-of-origin guard**: before pushing, `release.sh` snapshots `git log origin/main..HEAD --oneline`, prints it, aborts unless the only commits ahead are the release commits it just made (or `--allow-ahead` set); blocks on dirty tracked files except the bumped ones; no author heuristics. **Step 9.5 renamed** `@mindrian_os/cli` -> `@mindrian_os/install` (publish target + `next`/`latest` dist-tag derivation + `npm pack --dry-run` payload-allowlist gate + recovery instructions). Hermetic Wave-0 test `tests/test-release-bump-algebra.cjs` (7/7) green; `tests/test-release-npm-gate.sh` updated to the `@mindrian_os/install` expectations (6/6 gates green). beta.13 is the first `release.sh`-cut pre-release after the run of hand-rolled beta.10 / 11 / 12. (`scripts/release.sh`, `package.json`, `tests/test-release-bump-algebra.cjs` [new], `tests/test-release-npm-gate.sh`.)
21
+
22
+ - **Cache pruning on update (Phase 123 Plan-05 -- HARNESS-123-13).** `lib/core/cache-prune.cjs` keeps the active version + N=2 most recent `<pluginsDir>/cache/<marketplace>/mos/<version>/` dirs; NEVER deletes the active (belt-and-suspenders -- the active is unconditionally in the keep-set regardless of mtime); skips entirely if `installed_plugins.json` is missing, unparseable, or has no `mos@mindrian-marketplace` entry. Runs in `scripts/session-start` on version change (best-effort, `|| true`) AND in `scripts/doctor.cjs::performClassJFix` unconditionally on `--fix`. Hermetic Wave-0 test `tests/test-cache-prune.cjs` (6/6) green. (`lib/core/cache-prune.cjs` [new], `scripts/session-start`, `scripts/doctor.cjs`, `tests/test-cache-prune.cjs` [new].)
23
+
24
+ - **Phase 123 Plan-07 -- single Brain-key resolver + positive session-start status (HARNESS-123-15 + HARNESS-123-16).** Three independent Brain-key lookups (`brain-client.cjs::getApiKey`, `scripts/session-start`'s shell test of `MINDRIAN_BRAIN_KEY`, the `brain-connector` skill's detection order) are collapsed into one source of truth, `lib/core/resolve-brain-key.cjs`. The resolver mirrors `lib/core/active-plugin-root.cjs`'s shape (`{ key, source, available, reason }`) and order (env -> `~/.mindrian.env` -> CWD `.env` -> not-found, the D-31 precedence); SEC-02 POSIX `0o077` permission rejection routes through an explicit `reason` string -- never a silent null. `brain-client.cjs::getApiKey()` is now a one-liner delegating to the resolver (the previous inline 3-path lookup is gone; the docstring is fixed; `Authorization: Bearer` at L218 + L279 and the `BRAIN_REQUEST_TIMEOUT_MS` / `AbortSignal.timeout` / memoized `schema()` / `async function ask` precondition are all upstream of this and untouched). `scripts/session-start`'s Brain block (~L1290-1313) replaces the pre-Plan-7 MCP-centric WARN that tested only the shell env var with a positive 3-case status line: `Brain: HTTP client active (mindrian-brain.onrender.com)` when the key resolves; `Brain: NOT loaded -- permissions too open: ... (run: chmod 600 ~/.mindrian.env)` when SEC-02 rejects; `Brain: not configured (Tier 0)` when nothing is found. The `brain-connector/SKILL.md` Detection section gains a new step 0 (HTTP-path detection via the resolver) and a CLI row in the Tool Names table. `commands/setup.md`'s `~/.mindrian.env` write is now followed by `chmod 600` (SEC-02 fix; no-op on Windows). `install.sh` is annotated -- it does NOT write `~/.mindrian.env` today; if a future code path adds a write, it MUST chmod 600 the file. `docs/install/BRAIN-SETUP.md` and `.env.brain.template` state Bearer-only explicitly and surface the `https://mindrianos.vercel.app/brain-access` request URL + `MINDRIAN_BRAIN_URL` override. Wave-0 hermetic test `tests/test-resolve-brain-key.cjs` (9 scenarios -- env wins / mindrian-env wins over CWD / CWD fallback / not-found / SEC-02 reject / Canon Part 8 grep / getApiKey delegation / brain-client preconditions / FLAG-3 home-default structural assertion) all green; registered in `lib/memory/run-feynman-tests.cjs`. (`lib/core/resolve-brain-key.cjs` [new], `lib/core/brain-client.cjs`, `scripts/session-start`, `skills/brain-connector/SKILL.md`, `commands/setup.md`, `install.sh`, `docs/install/BRAIN-SETUP.md`, `.env.brain.template`, `tests/test-resolve-brain-key.cjs` [new], `lib/memory/run-feynman-tests.cjs`, `lib/memory/security-trifecta.test.cjs`.)
25
+
26
+ ### Fixed
27
+
28
+ - **Statusline deployment-topology gap (the last thread in the install-machinery family).** A Windows live test on beta.12 confirmed: the statusline-wrapper fix shipped in the plugin cache, but `~/.claude/settings.json` runs the *deployed* `~/.claude/statusline-mos`, which `scripts/session-start` had been re-copying from this hook's `PLUGIN_ROOT` every session -- so when the running hook lagged the just-updated version, the deployed copy stayed stale. Fix: `~/.claude/statusline-mos` is now a **dumb dispatcher shim** (`scripts/statusline-mos-dispatch`, marker `MINDRIAN-STATUSLINE-DISPATCH`) -- zero logic, it just finds an installed plugin version and `exec`s that version's `scripts/statusline-mos`, which does the real (installed_plugins.json-first) resolution and rendering. So a wrapper fix in plugin vN+1 reaches every user on their next session with no re-stamp, and a wrapper bug can never sit stale on the deployment surface. `scripts/session-start` Step A now deploys/migrates the dispatcher: one-time migration from an old logic-bearing `~/.claude/statusline-mos`; no-op once it's already the dispatcher; never touches a non-MindrianOS file at that path (it must contain `MindrianOS statusline` to be replaced). Falls back to the prior full-wrapper copy for plugin versions predating the dispatcher. (`scripts/statusline-mos-dispatch` [new], `scripts/session-start`, `scripts/statusline-mos` header.)
29
+
30
+ - **`scripts/release.sh:40`'s `IFS='.' read -r MAJOR MINOR PATCH`** mangled pre-release versions (`PATCH=0-beta` from `1.13.0-beta.11`), which is why beta.10 / 11 / 12 were hand-rolled and beta.13 is the first `release.sh`-cut pre-release. Replaced with `semver.inc()` (Plan 123-01).
31
+ - **`scripts/doctor.cjs:40`'s hardcoded `INSTALL_DIR = ~/.claude/plugins/mindrian-os/`** was the `MODULE_NOT_FOUND` source on marketplace-only installs (the disease that surfaced Bug 7). NEW code (class I + class J + new wire-ins) resolves via `resolveActivePluginRoot()`; `INSTALL_DIR` is preserved for existing class A but no longer the source of truth for new code (Plan 123-03).
32
+ - **`scripts/session-start:419`'s `~/.mindrian-last-version` write inside the cold-start `else` branch** never fired on a session WITH an active room -- which is why room-sessions read stale (Pitfall 7). The new install-state record block writes it unconditionally as the single writer in earliest steps; the line-419 write is removed; the line-101 read of the PREVIOUS value is preserved for the transition banner (Plan 123-02).
33
+ - **`commands/setup.md:145`'s stale URL `mindrianos-jsagirs-projects.vercel.app/brain-access`** -> `mindrianos.vercel.app/brain-access` (Plan 123-05; reaffirmed Plan 123-07).
34
+ - **Brain client CHANGELOG prose softened** -- the client currently calls `mindrian-brain.onrender.com`; `brain.mindrian.ai` is the future host; `MINDRIAN_BRAIN_URL` overrides either (Plan 123-07).
35
+ - **`scripts/release-beta-smoke.sh`** retired -- hard-pinned to a stale Phase-89.6 artifact `EXPECTED_VERSION="1.11.0-beta.1"`; `doctor --acceptance --pre-tag` supersedes it (Plan 123-04).
36
+ - **`brain-client.cjs::getApiKey()` precedence** -- was env -> CWD `.env` -> `~/.mindrian.env`; now (via the resolver delegation) env -> `~/.mindrian.env` -> CWD `.env` per D-31. Deliberate: on a maintainer's machine the home file is the canonical key, the CWD file is project-local override (Plan 123-07).
37
+ - **Plan-02 amendment: install-state record `active_version` derivation** -- the original session-start block preferred the dev workspace's `plugin.json` version over the resolver's root basename, so on a maintainer's box (where the workspace can lead the live install) the record contained an internal contradiction (`active_root` pointed at the live install dir; `active_version` named a different version). Surfaced by Plan-06's pre-flight class-I gate 2026-05-13 (commit `69a5240`).
38
+ - **Plan-06 release-flight: `scripts/verify-release` Step 12 "Git State"** died silently on a clean working tree (`git status --porcelain | grep -v "^??" | wc -l` exited non-zero with no tracked uncommitted changes; `set -e` killed the script). Wrapped the grep in `{ ... || true; }` (commit `267d395`).
39
+ - **Plan-06 release-flight: `commands/operator.md` + `commands/doctor.md` YAML frontmatter parse error** -- `argument-hint: [history] [set <op>] [reset] [--json]` confused YAML (multiple flow-sequence-looking tokens on one line); the parser bailed at line 3 and both commands loaded with empty metadata. Wrapped both argument-hint values in double-quoted strings. Latent in `main` for at least a session before Plan-06's stricter pre-flight caught it (commit `b41f232`).
40
+
41
+ ### Changed
42
+
43
+ - **`data/deployment-surfaces.json`** added -- hand-maintained static manifest; 6 surfaces; reuses the `data/` layout convention from Phase 122 but NOT the generator/`--check` pattern (this file isn't derived from anything; nothing to `--check` it against). Schema extension in Plan-03: optional `path_within_file` field on `exact-value` surfaces points at a JSON sub-field (e.g. `statusLine.command` inside `settings.json`); class-J's `exact-value` check extracts via that path before comparing.
44
+ - **`docs/install/BRAIN-SETUP.md`** + **`.env.brain.template`**: state explicitly that auth is `Authorization: Bearer <key>` only (NOT `x-api-key`); surface the `https://mindrianos.vercel.app/brain-access` URL in the no-key fallback (Plan 123-07).
45
+ - **`docs/CANON-PHASE-MAP.md`**: Phase 123 mapped under **Part 6** (dog-fooding the install lifecycle -- one record + one manifest + one command + one release script; the plugin's own install state honors the plugin's canon) and **Part 7** (reuse justification -- ~90% of Phase 123 extends shipped code; net-new files are `data/deployment-surfaces.json`, `lib/core/resolve-brain-key.cjs`, `lib/core/cache-prune.cjs`, the per-class fixtures) (Plan 123-06 Task 4).
46
+ - **`@mindrian_os/cli` -> `@mindrian_os/install` doc/test sweep** -- forward-facing references across `docs/install/PACKAGING-PATHS.md`, `tests/manual/95.6-windows-cold-install-acceptance.md`, `tests/test-release-npm-gate.sh`, `docs/INSTALL-LIFECYCLE-HARNESS.md` (lines 91/104/124), plus older `@mindrian/os` mentions in `docs/autopsies/2026-05-09-gary-laben-install-failure.md`, `docs/UI-UX-CONVERGENCE-2026-05-10/04-REVERSE-SALIENT-INSTALL.md`, `docs/testers/gary-laben/FEEDBACK.md`, `docs/testers/outbox/2026-05-07-gary-laben-welcome.md`. Historical CHANGELOG entries stay as the historical record. After the sweep, `grep -rln "@mindrian_os/cli" docs/install/ commands/ tests/test-*.sh scripts/release.sh` returns nothing (Plan 123-05).
47
+
48
+ ### Notes
49
+
50
+ - **Path C re-route status** (2026-05-05): v1.13.0-beta.13 carries Phase 123 (install-lifecycle-harness). Phase 110 (Brain Context Packet Contract) shipped in parallel during the Phase-123 execution waves; its 6 plans + verification completed on `main` between Plan-05 and Plan-07; it rides along here.
51
+ - **Promotion to clean 1.13.0** gated on a real-Windows `mindrian-os doctor --acceptance` run (Lawrence / operator), per Canon Part 5 (Evidence Is Graded By Context) + Part 6 (Product-as-Venture / dog-fooding mandate). A follow-up `bash scripts/release.sh --finalize` -- NOT this release's work -- cuts the clean `1.13.0` after the Windows gate is green.
52
+ - **Concurrent-execution incidents during the Phase 123 + Phase 110 parallel run** (2026-05-12 to 2026-05-13): a Phase-110 `git add -A` swept Plan 123-05's GREEN files into the wrong commit (`4453292`; work correct, attribution muddled); a Phase-110 commit re-introduced `release-beta-smoke.sh` after Plan 123-04 deleted it (`231f5cd`; Plan-04 re-deleted cleanly); the `fix/brain-client-timeout-ask-schema-cache` branch checkout yanked Plan-123 research's HEAD mid-run (cherry-picked back to `main` as `f03195a`). All recovered without data loss. Pattern documented for a future `gsd-executor` worktree-isolation-by-default improvement.
53
+
54
+ ## [1.13.0-beta.12] - 2026-05-12
55
+
56
+ The v1.13.0 CAPSTONE release -- headline content is the **Workflow Layer** (Phase 122: framework <-> command registry + reliable invocation; spec at `.planning/WORKFLOW-LAYER-SPEC.md`, doc at `docs/WORKFLOWS.md`) plus the npm-installer overhaul (`npx @mindrian_os/install` is now a real one-command installer), the `@mindrian_os/cli` -> `@mindrian_os/install` rename, and the install-machinery fixes a Windows live test surfaced (doctor/update path resolution, the statusline pre-release blind spot, and the single plugin-root resolver that retires that whole bug family). Version trail to here: `1.13.0-beta.10` (a token-validation npm publish on 2026-05-12 -- now deprecated), `1.13.0-beta.11` (the real npm installer + the package rename, npm-only -- now deprecated, doctor path bug), `1.13.0-beta.12` (this release: the capstone, tagged `v1.13.0-beta.12`, marketplace `source.ref` pinned, `@mindrian_os/install` published with the `@next` dist-tag).
15
57
 
16
58
  ### Added
17
59
 
60
+ - **The Workflow Layer (Phase 122) -- the framework-to-command registry + reliable invocation.** Larry can now turn "the methodology suggests framework X" into "run `/mos:x`" as a CI-enforced guarantee, not model recall:
61
+ - **`data/command-registry.json`** -- the generated, committed framework-to-command registry (`{ ontology_ref, commands[], framework_index, curated_chains[] }`), built from each `commands/*.md` frontmatter; never hand-edited. Plus `data/framework-names.json` -- the FEEDS_INTO-linked Brain `:Framework` name slice (+ a small curated whitelist), the only Brain-derived artifact in this loop.
62
+ - **`scripts/build-command-registry.cjs`** -- the generator + the `--check` drift tripwire (fails on a stale registry or an unresolvable framework name) + `--refresh-names` (a read-only build-time Brain query that snapshots the allowlist). The `--check` is wired into the pre-commit hook (when any `commands/*.md` / `data/command-registry.json` / `data/framework-names.json` is staged) and the Feynman test runner.
63
+ - **`lib/workflow/command-resolver.cjs`** -- the SOLE deterministic framework-to-command door (`commandsForFramework`, `frameworksForCommand`, `composeWorkflow`, `validateChainAutonomy`); reads only `data/command-registry.json`; zero Brain calls; degrades to empty results / `{ command: null, optional: true }` on a missing registry or a command-less framework (degrade, do not fabricate).
64
+ - **`lib/brain/chain-recommender.cjs`** -- `recommendFrameworkChain({problemType?, currentFramework?, roomState?}) -> [frameworkName]` via the Brain's `FEEDS_INTO` traversal (framework names + problem-type enums only, never a command string, never user content); degrades to `[seed]`.
65
+ - **The five new `/mos:` command frontmatter keys** -- `kind` (`methodology | utility | meta`), `frameworks[]` (the exact Brain `:Framework` name(s)), `produces`, `inputs`, `autonomous_safe` -- retrofitted across 44 commands (the algorithmic cohort first). Contract: `docs/COMMAND-FRONTMATTER.md`.
66
+ - **`/mos:pipeline --from-problem-type <x>` / `--from-framework <x>`** -- Brain-derive the chain, compose commands, print the `/mos:` run order. **`/mos:act --chain`** -- runs the composed workflow but `validateChainAutonomy` first and STOPS at the first non-`autonomous_safe` (or command-less) step with a "needs you here" gate (the Canon Part 3 "human confirms" clause made literal). **`/mos:suggest-next`** -- now returns a step-numbered command sequence, not just a framework list.
67
+ - **The pre-commit registry-drift tripwire** -- `build-command-registry.cjs --check` runs in `.git/hooks/pre-commit`; the Feynman runner runs it too.
68
+ - **`docs/WORKFLOWS.md`** -- the Brain <-> registry <-> Larry join, the five reliability rules, the Canon Part 8 boundary (commands never enter the Brain -- no `Command` node, ever), and the resolver/recommender surface. `docs/THE-BRAIN.md` and `docs/CANON-PHASE-MAP.md` point at it.
69
+ - **`lib/memory/workflow-layer-e2e.test.cjs`** -- walks frontmatter -> `build-command-registry --check` -> `resolver.composeWorkflow(the spec's acceptance example)` -> the command-less degrade case -> the `validateChainAutonomy` stop-point, then runs the Canon Part 8 zero-Brain-mutation grep sweep. Registered in the Feynman runner + `tests/run-all-122.sh`.
18
70
  - **`npx @mindrian_os/install` is a real one-command installer, not a printout.** Previously `npx @mindrian_os/cli install` only echoed the marketplace commands for the user to paste into Claude Code by hand ("no side effects, just guidance"). It now drives Claude Code's own plugin CLI: it checks that `claude` is on PATH (and prints how to install Claude Code if not), runs `claude plugin marketplace add jsagir/mindrian-marketplace`, then `claude plugin install mos@mindrian-marketplace`. Running it with no subcommand -- or with only flags, e.g. `npx @mindrian_os/install --version 1.13.0-beta.9` -- does the install; flags pass through to `claude plugin install`. `doctor` and `update` are still explicit subcommands. The Brain key stays a printed hint -- writing it to the environment is the one side effect left to the user. This unblocks un-gating the npm-quick-install card on the install site (`mindrianos-install-site.vercel.app`). (`bin/cli.js`.)
71
+ - Post-beta.11 follow-up (2026-05-12, after a Windows live test): `mindrian-os doctor` / `update` were resolving the plugin at the legacy `~/.claude/plugins/mindrian-os/` path, which does not exist for a `claude plugin install` -- the plugin is named `mos` and lives at `~/.claude/plugins/cache/<marketplace>/mos/<version>/`. So `npx @mindrian_os/install doctor` was throwing a raw node `MODULE_NOT_FOUND` stack. `bin/cli.js` now resolves the plugin root in order (MINDRIAN_OS_ROOT -> newest marketplace-cache `mos/<version>/` with a `scripts/doctor.cjs` -> legacy clone -> not-found), prints a plain "not installed -- run `npx @mindrian_os/install`" message when truly absent, and `update` uses `claude plugin marketplace update` + `claude plugin update mos@mindrian-marketplace` for a marketplace install (the `git pull` + `install.sh` path is kept only for a dev clone / MINDRIAN_OS_ROOT). The `install` flow also now runs `claude plugin marketplace update` then `claude plugin install` + `claude plugin update` (so an already-installed plugin gets moved to the current ref rather than just reported "already installed", which was the misleading message in the Windows test where the version actually moved 1.12.0 -> 1.13.0-beta.9). Lands in the next `@mindrian_os/install` npm publish.
72
+ - Same Windows test surfaced a pre-release blind spot in `scripts/statusline-mos` (the self-healing statusline resolver): it picked the "latest" cache version with `grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'`, which rejects `-beta.N` suffixes. A box with `1.12.0` + `1.13.0-beta.9` in the marketplace cache picked `1.12.0`, rendered the stale statusline from there, and exported `MINDRIAN_OS_ROOT` pointing at it -- so the version banner / room-context lookup / focus glyph were all computed from the wrong version. Widened the anchor to `^[0-9]+(\.[0-9]+)+(-[A-Za-z0-9.]+)?$` (`sort -V` already orders pre-releases correctly: `1.12.0 < 1.13.0-beta.9 < 1.13.0`). Ships in the next plugin release; the deployed `~/.claude/statusline-mos` (or the `register_statusline` block in `~/.claude/settings.json` that points at `<install-dir>/scripts/statusline-mos`) picks it up when the plugin re-stamps on next install/update. Immediate workaround on an affected box: delete the stale lower-version cache dir under `~/.claude/plugins/cache/mindrian-marketplace/mos/`.
73
+ - Root-cause fix (the three above were band-aids on three independent guessers): **`lib/core/active-plugin-root.cjs`** -- the ONE plugin-root resolver. Precedence: `MINDRIAN_OS_ROOT` env -> `~/.claude/plugins/installed_plugins.json` (Claude Code's own registry of the *active* `mos@mindrian-marketplace` install; temporal truth -- right even when "highest semver" isn't the active version) -> newest pre-release-tolerant `~/.claude/plugins/cache/<marketplace>/mos/<version>/` -> legacy `~/.claude/plugins/mindrian-os/` -> not-found. Usable as a module (`resolveActivePluginRoot()`) and as a CLI (`node active-plugin-root.cjs` prints the path; `--json` for `{root, source}`). `bin/cli.js` (doctor/update) now delegates to it; `scripts/statusline-mos` shells out to its CLI form (with the cache-scan as a fallback for older deployed copies of the wrapper). Reads LOCAL files only (Canon Part 8). Still TODO (separate, lower-risk pass): have `scripts/session-start` re-stamp the `register_statusline` block in `~/.claude/settings.json` from this resolver on every run, so the deployed wrapper / settings pointer can never drift.
19
74
 
20
75
  ### Changed
21
76
 
22
- - **npm package renamed (twice): `@mindrian/os` -> `@mindrian_os/cli` -> `@mindrian_os/install`.** First rename (2026-05-11): the `@mindrian` npm scope never existed (`{"error":"Scope not found"}`), so `@mindrian/os` could never be published; the maintainer created the `@mindrian_os` org and the package moved to `@mindrian_os/cli`; first npm publish was `@mindrian_os/cli@1.13.0-beta.10` on 2026-05-12 (a token-validation build, dist-tag `@next`, no git tag, not on the marketplace) -- now deprecated. Second rename (2026-05-12): `@mindrian_os/cli` implied "a CLI tool" / a guidance printer, which is exactly what it had been; once `install` became a real installer the package name should be the verb, so it moved to `@mindrian_os/install` -- `npx @mindrian_os/install` reads as "install MindrianOS". The `bin` entry stays `mindrian-os` (the post-install command for `doctor`/`update`). `package.json` + `.claude-plugin/plugin.json` are at `1.13.0-beta.11`; once `@mindrian_os/install@1.13.0-beta.11` is published, the v1.13.0 capstone (Phase 122 / Workflow Layer) takes the next number, `1.13.0-beta.12`. Forward-looking references that named `@mindrian_os/cli` (`scripts/release.sh`, `docs/install/PACKAGING-PATHS.md`, `tests/manual/95.6-windows-cold-install-acceptance.md`, `tests/test-release-npm-gate.sh`, the install site's npm-quick-install card) need updating to `@mindrian_os/install`. (The `[1.13.0-beta.9]` entry below is left intact as the historical record of the pre-rename release -- which shipped to GitHub and the marketplace as `v1.13.0-beta.9` but was never published to npm.)
77
+ - **`/mos:suggest-next` returns a command sequence**, not just a framework list; **`framework-chain-composer.proposeNextFramework` routes through `lib/workflow/command-resolver.cjs`** (the only door -- `command:null` degrade for a command-less next framework); **the `pws-methodology` and `brain-connector` skills point at the resolver** (framework routing goes through `command-resolver.commandsForFramework` / `composeWorkflow`, never a `/mos:` named from memory). **The three remaining hand-maintained framework-to-command maps were pruned:** `framework-chain-composer.FRAMEWORK_TO_COMMAND_SLUG` is now an empty back-compat export, `lib/hmi/jtbd-taxonomy.json:methodology_hooks` is marked informational-only (the resolver is authoritative), and `references/methodology/index.md` is now just a pointer to `docs/COMMAND-FRONTMATTER.md` / `data/command-registry.json` / `docs/WORKFLOWS.md` -- it no longer hand-maintains a routing table.
78
+ - **npm package renamed (twice): `@mindrian/os` -> `@mindrian_os/cli` -> `@mindrian_os/install`.** First rename (2026-05-11): the `@mindrian` npm scope never existed (`{"error":"Scope not found"}`), so `@mindrian/os` could never be published; the maintainer created the `@mindrian_os` org and the package moved to `@mindrian_os/cli`; first npm publish was `@mindrian_os/cli@1.13.0-beta.10` on 2026-05-12 (a token-validation build, dist-tag `@next`, no git tag, not on the marketplace) -- now deprecated. Second rename (2026-05-12): `@mindrian_os/cli` implied "a CLI tool" / a guidance printer, which is exactly what it had been; once `install` became a real installer the package name should be the verb, so it moved to `@mindrian_os/install` -- `npx @mindrian_os/install` reads as "install MindrianOS". The `bin` entry stays `mindrian-os` (the post-install command for `doctor`/`update`). `package.json` + `.claude-plugin/plugin.json` ship as `1.13.0-beta.12` (this release); the npm-only intermediate publishes `@mindrian_os/cli@1.13.0-beta.10` and `@mindrian_os/install@1.13.0-beta.11` are deprecated. The install site's npm-quick-install card already names `@mindrian_os/install`; `scripts/release.sh` still says `@mindrian_os/cli` (Step 9.5) and only handles clean `X.Y.Z` bumps (it choked on the pre-release version, so this release was hand-rolled per the CLAUDE.md release process) -- both worth a follow-up. `docs/install/PACKAGING-PATHS.md`, `tests/manual/95.6-windows-cold-install-acceptance.md`, `tests/test-release-npm-gate.sh` still name `@mindrian_os/cli` and need updating to `@mindrian_os/install`. (The `[1.13.0-beta.9]` entry below is left intact as the historical record of the pre-rename release -- which shipped to GitHub and the marketplace as `v1.13.0-beta.9` but was never published to npm.)
79
+
80
+ ### Fixed
81
+
82
+ - **The hallucinated-command failure mode.** Larry could name a non-existent or semantically wrong command -- e.g. `/mos:jtbd` for the JTBD *methodology* when `/mos:analyze-needs` is the framework command (`/mos:jtbd` is the active-JTBD management command, not a methodology runner). With the Workflow Layer, every command Larry surfaces comes back from `lib/workflow/command-resolver.cjs` reading the generated registry -- `composeWorkflow(["Jobs to Be Done (JTBD)"])` returns `/mos:analyze-needs`. A hallucinated command cannot be emitted.
83
+ - **A latent Canon Part 8 breach in prose.** `skills/brain-connector/SKILL.md` carried dead "Brain has Command nodes linked to Frameworks ... `brain_proactive_command` ... `FOLLOWS_FRAMEWORK -> Command`" prose, and `references/brain/command-triggers-schema.md` was a whole dead "commands are first-class Neo4j nodes" schema doc -- both asserted that plugin commands live in the Brain, which the live Brain never implemented (no `Command` label) and which Canon Part 8 forbids. Both were deleted; the `command-triggers-schema.md` path now carries a `REMOVED` tombstone pointing at the Workflow Layer. The `lib/memory/workflow-layer-e2e.test.cjs` grep sweep now fails the build if a `Command`-node assertion ever returns anywhere in `skills/`, `agents/`, or `references/`.
84
+
85
+ ### Maintainer Notes
86
+
87
+ - **Release steps (maintainer-gated -- NOT performed in this phase):** cut the `v1.13.0-beta.11` tag, pin `~/mindrian-marketplace/.claude-plugin/marketplace.json` `source.ref` to the tag, and `npm publish @mindrian_os/install` with the `@next` dist-tag -- per the CLAUDE.md release process and the `feedback_release_lockstep_npm` rule (every plugin release publishes the npm package in lockstep). Phase 122 only finalized this CHANGELOG block and shipped the Workflow Layer code/docs/tests; it did not bump any version, did not `git tag`, did not `npm publish`, and did not edit `marketplace.json`.
23
88
 
24
89
  ### Notes
25
90
 
package/bin/cli.js CHANGED
@@ -10,53 +10,83 @@
10
10
  * flags, e.g. `npx @mindrian_os/install --version 1.13.0-beta.9`) does the
11
11
  * install. `doctor` and `update` are still explicit subcommands.
12
12
  *
13
- * install Path B. Actually install MindrianOS by driving Claude Code's
14
- * own plugin CLI: registers the Mindrian marketplace, then runs
15
- * `claude plugin install mos@mindrian-marketplace`. Requires the
16
- * `claude` CLI on PATH (prints how to get it if missing). Any
17
- * flags after `install` pass through to `claude plugin install`
18
- * (e.g. `mindrian-os install --version 1.13.0-beta.9`). The Brain
19
- * key stays a printed hint -- writing it to the environment is the
20
- * one side effect we leave to the user.
21
- * doctor Path C. Run /mos:doctor's diagnostic logic from OUTSIDE Claude
22
- * Code so users catch install/drift problems before a session.
23
- * Spawns `node <pluginRoot>/scripts/doctor.cjs` with any extra
24
- * args passed through (e.g. `mindrian-os doctor --all --fix`).
25
- * Exits with doctor.cjs's exit code.
26
- * update Mirror /mos:update. `git -C <pluginRoot> pull --ff-only`, then
27
- * re-run `bash <pluginRoot>/install.sh` to re-register agents,
28
- * hooks, settings.json, and the statusLine block.
13
+ * install Install (or bring current) MindrianOS by driving Claude Code's
14
+ * own plugin CLI: registers the Mindrian marketplace, refreshes the
15
+ * catalog, then `claude plugin install` + `claude plugin update` on
16
+ * mos@mindrian-marketplace. Requires the `claude` CLI on PATH (prints
17
+ * how to get it if missing). Flags pass through to `claude plugin
18
+ * install` (e.g. `--version 1.13.0-beta.9`); when a version is pinned
19
+ * the update step is skipped. The Brain key stays a printed hint --
20
+ * writing it to the environment is the one side effect left to you.
21
+ * doctor Run /mos:doctor's diagnostic from OUTSIDE Claude Code so you catch
22
+ * install/drift problems before a session. Resolves the installed
23
+ * plugin (marketplace cache, dev clone, or MINDRIAN_OS_ROOT), then
24
+ * `node <pluginRoot>/scripts/doctor.cjs <args...>`. If the plugin is
25
+ * not installed, says so plainly instead of throwing a node stack.
26
+ * update Bring MindrianOS current. For a marketplace install: `claude plugin
27
+ * marketplace update` + `claude plugin update mos@mindrian-marketplace`.
28
+ * For a dev clone (MINDRIAN_OS_ROOT set): `git -C <root> pull --ff-only`
29
+ * + `bash <root>/install.sh`.
29
30
  *
30
31
  * GSD pattern: pure CJS, node built-ins only, zero npm deps. No CLI framework
31
32
  * (no commander/yargs/meow). process.argv switch-case routing, mirroring
32
33
  * bin/mindrian-tools.cjs and ~/.claude/get-shit-done/bin/gsd-tools.cjs.
33
34
  *
34
- * PLUGIN_ROOT resolution: MINDRIAN_OS_ROOT env var if set (tests, dev boxes),
35
- * else the canonical install cache at ~/.claude/plugins/mindrian-os.
35
+ * Plugin-root resolution is delegated to lib/core/active-plugin-root.cjs (the
36
+ * single source of truth: MINDRIAN_OS_ROOT -> installed_plugins.json -> newest
37
+ * marketplace-cache mos/<version>/ -> legacy clone -> not-found). doctor and
38
+ * update both read from it; scripts/statusline-mos shells out to its CLI form.
36
39
  */
37
40
 
38
41
  const { spawnSync } = require('node:child_process');
39
42
  const path = require('node:path');
40
43
  const os = require('node:os');
44
+ const fs = require('node:fs');
45
+ // The ONE plugin-root resolver: installed_plugins.json (temporal truth) first,
46
+ // then the pre-release-tolerant marketplace-cache scan, then a legacy clone.
47
+ const { resolveActivePluginRoot } = require('../lib/core/active-plugin-root.cjs');
41
48
 
42
- const PLUGIN_ROOT = process.env.MINDRIAN_OS_ROOT
43
- || path.join(os.homedir(), '.claude', 'plugins', 'mindrian-os');
49
+ const MARKETPLACE = 'jsagir/mindrian-marketplace';
50
+ const PLUGIN_SPEC = 'mos@mindrian-marketplace';
44
51
 
45
52
  function run(cmd, args, opts) {
46
53
  return spawnSync(cmd, args, { stdio: 'inherit', ...opts });
47
54
  }
48
55
 
56
+ function ok(result) {
57
+ return result && typeof result.status === 'number' && result.status === 0;
58
+ }
59
+
49
60
  function exitFrom(result) {
50
61
  // spawnSync sets status=null when the process was killed by a signal or
51
62
  // failed to launch; treat that as a generic failure.
52
63
  process.exit(result && typeof result.status === 'number' ? result.status : 1);
53
64
  }
54
65
 
66
+ function hasDoctor(dir) {
67
+ try {
68
+ return !!dir && fs.existsSync(path.join(dir, 'scripts', 'doctor.cjs'));
69
+ } catch {
70
+ return false;
71
+ }
72
+ }
73
+
55
74
  function printUsage() {
56
75
  console.log('mindrian-os <install|doctor|update> (no subcommand = install)');
57
- console.log(' install install MindrianOS via Claude Code (adds the marketplace, installs the mos plugin)');
58
- console.log(' doctor run the MindrianOS install/drift diagnostic (Path C; passes flags through to /mos:doctor)');
59
- console.log(' update pull the latest plugin and re-run install registration');
76
+ console.log(' install install / bring current via Claude Code (marketplace add + plugin install/update)');
77
+ console.log(' doctor run the MindrianOS install/drift diagnostic (passes flags through to /mos:doctor)');
78
+ console.log(' update bring MindrianOS current (marketplace update + plugin update; or git pull for a dev clone)');
79
+ }
80
+
81
+ function requireClaudeCli() {
82
+ const check = spawnSync('claude', ['--version'], { stdio: 'ignore' });
83
+ if (ok(check)) return true;
84
+ console.error('Claude Code is not installed (no `claude` command on your PATH).');
85
+ console.error('Install it first:');
86
+ console.error(' npm install -g @anthropic-ai/claude-code');
87
+ console.error('Then re-run:');
88
+ console.error(' npx @mindrian_os/install');
89
+ return false;
60
90
  }
61
91
 
62
92
  // No subcommand, or flags only (e.g. `npx @mindrian_os/install --version 1.13.0-beta.9`),
@@ -70,68 +100,95 @@ if (!sub || sub.startsWith('-')) {
70
100
 
71
101
  switch (sub) {
72
102
  case 'doctor': {
73
- // Path C: run /mos:doctor's logic from outside Claude Code.
74
- const doctorPath = path.join(PLUGIN_ROOT, 'scripts', 'doctor.cjs');
75
- const r = run(process.execPath, [doctorPath, ...process.argv.slice(3)]);
103
+ const { root } = resolveActivePluginRoot();
104
+ if (!root || !hasDoctor(root)) {
105
+ console.error('MindrianOS does not appear to be installed (could not find scripts/doctor.cjs).');
106
+ console.error('Looked under: ' + path.join(os.homedir(), '.claude', 'plugins') + (process.env.MINDRIAN_OS_ROOT ? ' and $MINDRIAN_OS_ROOT' : ''));
107
+ console.error('Install it first:');
108
+ console.error(' npx @mindrian_os/install');
109
+ process.exit(1);
110
+ }
111
+ const r = run(process.execPath, [path.join(root, 'scripts', 'doctor.cjs'), ...process.argv.slice(argOffset)]);
76
112
  exitFrom(r);
77
113
  break;
78
114
  }
79
115
 
80
116
  case 'update': {
81
- // Mirror /mos:update: fast-forward the plugin clone, then re-run install.sh
82
- // so agents, hooks, settings.json, and the statusLine block get re-stamped.
83
- run('git', ['-C', PLUGIN_ROOT, 'pull', '--ff-only']);
84
- const r = run('bash', [path.join(PLUGIN_ROOT, 'install.sh')]);
85
- exitFrom(r);
117
+ // Dev clone (MINDRIAN_OS_ROOT or a legacy hand-clone): git pull + re-run install.sh.
118
+ const { root } = resolveActivePluginRoot();
119
+ const isDevClone = !!process.env.MINDRIAN_OS_ROOT
120
+ || (root && fs.existsSync(path.join(root, '.git')) && fs.existsSync(path.join(root, 'install.sh')));
121
+ if (isDevClone && root) {
122
+ run('git', ['-C', root, 'pull', '--ff-only']);
123
+ const r = run('bash', [path.join(root, 'install.sh')]);
124
+ exitFrom(r);
125
+ break;
126
+ }
127
+ // Marketplace install: use Claude Code's own update path.
128
+ if (!requireClaudeCli()) process.exit(1);
129
+ console.log('Refreshing the marketplace catalog...');
130
+ run('claude', ['plugin', 'marketplace', 'update']);
131
+ console.log('Updating the MindrianOS plugin...');
132
+ const r = run('claude', ['plugin', 'update', PLUGIN_SPEC]);
133
+ if (!ok(r)) {
134
+ console.error('');
135
+ console.error('`claude plugin update ' + PLUGIN_SPEC + '` did not complete.');
136
+ console.error('Try inside Claude Code: /plugin marketplace update then /plugin update ' + PLUGIN_SPEC);
137
+ exitFrom(r);
138
+ }
139
+ console.log('');
140
+ console.log('MindrianOS is up to date. Run `claude plugin list` to confirm the version.');
141
+ console.log('Verify: mindrian-os doctor (or /mos:doctor inside Claude Code)');
142
+ process.exit(0);
86
143
  break;
87
144
  }
88
145
 
89
146
  case 'install': {
90
- // Path B: actually install MindrianOS by driving Claude Code's plugin CLI.
91
- // Registers the Mindrian marketplace, then `claude plugin install mos@...`.
92
147
  // Flags after `install` (or leading flags when `install` is implied) pass
93
- // through to `claude plugin install` (e.g. `... install --version 1.13.0-beta.9`).
148
+ // through to `claude plugin install` (e.g. `... --version 1.13.0-beta.9`).
94
149
  const passthrough = process.argv.slice(argOffset);
150
+ const pinned = passthrough.some((a) => a === '--version' || a.startsWith('--version='));
95
151
 
96
- // 1. Claude Code must be on PATH -- it does the actual plugin install.
97
- const claudeCheck = spawnSync('claude', ['--version'], { stdio: 'ignore' });
98
- if (!claudeCheck || claudeCheck.status !== 0) {
99
- console.error('Claude Code is not installed (no `claude` command on your PATH).');
100
- console.error('Install it first:');
101
- console.error(' npm install -g @anthropic-ai/claude-code');
102
- console.error('Then re-run:');
103
- console.error(' npx @mindrian_os/install');
104
- process.exit(1);
105
- }
152
+ if (!requireClaudeCli()) process.exit(1);
106
153
 
107
- // 2. Register the Mindrian marketplace. Best-effort: if it is already
108
- // registered Claude Code may exit non-zero with "already added" -- that
109
- // is fine, the install step below still works.
154
+ // Register the Mindrian marketplace (idempotent) and refresh its catalog so
155
+ // we resolve the current ref. Both are best-effort -- "already added" /
156
+ // "already up to date" exit non-zero on some Claude Code versions; fine.
110
157
  console.log('Adding the Mindrian marketplace...');
111
- run('claude', ['plugin', 'marketplace', 'add', 'jsagir/mindrian-marketplace']);
158
+ run('claude', ['plugin', 'marketplace', 'add', MARKETPLACE]);
159
+ console.log('Refreshing the marketplace catalog...');
160
+ run('claude', ['plugin', 'marketplace', 'update']);
112
161
 
113
- // 3. Install (or update) the plugin. This one's exit code matters.
162
+ // Install. On an already-installed plugin Claude Code reports "already
163
+ // installed" and still exits 0 -- the update step below then moves it
164
+ // forward to the current ref (unless the caller pinned a version).
114
165
  console.log('Installing the MindrianOS plugin...');
115
- const inst = run('claude', ['plugin', 'install', 'mos@mindrian-marketplace', ...passthrough]);
116
- if (!inst || inst.status !== 0) {
166
+ const inst = run('claude', ['plugin', 'install', PLUGIN_SPEC, ...passthrough]);
167
+ let updated = false;
168
+ if (!pinned) {
169
+ console.log('Bringing the plugin to the current build...');
170
+ const upd = run('claude', ['plugin', 'update', PLUGIN_SPEC]);
171
+ updated = ok(upd);
172
+ }
173
+
174
+ if (!ok(inst) && !updated) {
117
175
  console.error('');
118
- console.error('`claude plugin install mos@mindrian-marketplace` did not complete.');
176
+ console.error('Installing ' + PLUGIN_SPEC + ' did not complete.');
119
177
  console.error('Finish it by hand inside Claude Code:');
120
- console.error(' /plugin marketplace add jsagir/mindrian-marketplace');
121
- console.error(' /plugin install mos@mindrian-marketplace');
178
+ console.error(' /plugin marketplace add ' + MARKETPLACE);
179
+ console.error(' /plugin install ' + PLUGIN_SPEC);
122
180
  exitFrom(inst);
123
181
  }
124
182
 
125
- // 4. Done. Point at the Brain key + first run.
126
183
  console.log('');
127
- console.log('MindrianOS installed.');
184
+ console.log('MindrianOS is installed and current. Run `claude plugin list` to see the version.');
128
185
  console.log('');
129
186
  console.log('Optional -- connect the Brain for enriched intelligence:');
130
187
  console.log(' inside Claude Code: /mos:setup (choose "Configure Brain", paste your key)');
131
188
  console.log(' or set it directly: export MINDRIAN_BRAIN_KEY="<your-key>" (or add it to ~/.claude/.env)');
132
189
  console.log('');
133
190
  console.log('Verify: mindrian-os doctor (or /mos:doctor inside Claude Code)');
134
- console.log('Start: run `claude`, then /mos:onboard');
191
+ console.log('Start: open a fresh Claude Code session, then /mos:onboard');
135
192
  process.exit(0);
136
193
  break;
137
194
  }
package/commands/act.md CHANGED
@@ -211,9 +211,23 @@ Display the thinking trace (Step 4) and the execution plan following the dry-run
211
211
  Run /mos:act to execute this plan.
212
212
  ```
213
213
 
214
- ### Chain Mode (`/mos:act --chain`)
214
+ ### Chain Mode (`/mos:act --chain`) -- the autonomy gate
215
215
 
216
- 1. Select 3-5 frameworks using the chain selection logic:
216
+ **Before anything else in `--chain` mode, plan + autonomy-gate the chain through the resolver:**
217
+
218
+ ```bash
219
+ node "${CLAUDE_PLUGIN_ROOT}/scripts/act-command.cjs" --chain --room ./room
220
+ ```
221
+
222
+ The helper picks the framework chain for the room state via `lib/brain/chain-recommender.cjs` `recommendFrameworkChain` (a FEEDS_INTO traversal -- framework names + problem-type enums only; Canon Part 8: never a command string, never user content), composes it into `/mos:` commands via `lib/workflow/command-resolver.cjs` `composeWorkflow` (the SOLE framework -> command path, reading only the generated `data/command-registry.json`), calls `validateChainAutonomy(workflow)` FIRST, then walks the steps in order. At the FIRST step whose command is not `autonomous_safe: true` (or whose framework has no `/mos:` command at all), it STOPS and renders a "needs you here" gate (a Shape F.0 / E action report: "[GATE] Chain reached step N: /mos:x for <framework>. This step is not autonomous_safe -- it needs your eyes. [continue] [stop]"). You then:
223
+ - run the `autonomous_safe` prefix steps unattended (dispatch `agents/framework-runner.md` per step, with the checkpoint pause between steps as below),
224
+ - at the gate step, do NOT run it autonomously -- surface the gate to the user and wait. `[continue]` = the user runs that step themselves (or approves running it), then resume the chain from the next step. `[stop]` = halt; what ran above is filed.
225
+
226
+ You NEVER name a `/mos:` command in `--chain` mode from memory and you NEVER decide a step is safe to run unattended from memory -- the command came back from the resolver and the autonomy decision came back from `validateChainAutonomy` / `data/command-registry.json`'s `autonomous_safe` field. `--chain --from-framework <x>` / `--chain --problem-type <x>` seed the chain explicitly.
227
+
228
+ Then, for the steps the helper greenlit:
229
+
230
+ 1. Select 3-5 frameworks using the chain selection logic (the helper already did this via the recommender; this list is the same chain):
217
231
  - First framework: targets weakest section or most pressing gap
218
232
  - Subsequent frameworks: build on previous, guided by Brain `FEEDS_INTO` relationships or natural progression (Exploration -> Analysis -> Synthesis -> Validation)
219
233
  - Never select redundant frameworks
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: "Manually trigger auto-explore on a specific file (Desktop fallback when PostToolUse hook does not fire per RESEARCH 4.8)"
3
3
  argument-hint: "<file_path>"
4
+ serves_jtbd: ["find-problem", "understand-market", "explore"]
4
5
  allowed-tools:
5
6
  - "Bash"
6
7
  - "Read"
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: doctor
3
3
  description: Diagnose and optionally repair MindrianOS install — detects install-cache drift, .room-root sentinel gaps, active-room guard silence, surface-verification gaps, ROOM.md/MINTO.md drift, UI Ruling System compliance, and statusline visibility drift
4
- argument-hint: [--fix] [--cascade-rooms] [--verify-surface] [--room-md] [--ui-compliance] [--statusline-visibility] [--all] [--json]
4
+ argument-hint: "[--fix] [--cascade-rooms] [--verify-surface] [--room-md] [--ui-compliance] [--statusline-visibility] [--install-state] [--all] [--acceptance] [--pre-tag] [--light-npx] [--json]"
5
5
  body_shape: E (Action Report)
6
6
  body_shape_detail: per-class status rows with [before → after] pattern, summary totals, F.1 Next Move selector when drift detected without --fix
7
7
  serves_jtbd: ["audit-room"]
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: operator
3
3
  description: Show or manually set the conversation operator (JUST_TALK / EXPLORE_CAPTURE / BUILD_ROOM / METHODOLOGY / DECISION_GATE) -- the per-room state machine that governs how Larry renders responses
4
- argument-hint: [history] [set <op>] [reset] [--json]
4
+ argument-hint: "[history] [set <op>] [reset] [--json]"
5
5
  body_shape: E (Action Report)
6
6
  body_shape_detail: current state + last 5 history (default), full history (history subcommand), Shape F.1 picker (set subcommand), Shape F.4 confirmation (reset subcommand)
7
7
  serves_jtbd: ["explore"]
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: pipeline
3
3
  description: Chain a multi-step methodology pipeline
4
- argument-hint: [pipeline-name]
4
+ argument-hint: '[pipeline-name] [--from-problem-type <x>] [--from-framework <x>]'
5
5
  serves_jtbd: ["plan-execution"]
6
6
  # --- Phase 122 workflow-layer frontmatter ---
7
7
  kind: meta
@@ -20,6 +20,18 @@ allowed-tools:
20
20
 
21
21
  You are Larry. This command orchestrates multi-step methodology chains -- connected sequences where each framework's output feeds the next as structured input.
22
22
 
23
+ ## Brain-Derived Chains -- `--from-problem-type <x>` / `--from-framework <x>`
24
+
25
+ `/mos:pipeline --from-problem-type ill-defined` (or `--from-framework "Beautiful Question Framework"`) does NOT run a static named pipeline -- it Brain-derives the framework chain and runs the resolver-composed `/mos:` command sequence end to end:
26
+
27
+ ```bash
28
+ node "${CLAUDE_PLUGIN_ROOT}/scripts/pipeline-command.cjs" --from-problem-type ill-defined --room ./room
29
+ ```
30
+
31
+ The helper calls `lib/brain/chain-recommender.cjs` `recommendFrameworkChain` (a FEEDS_INTO traversal -- framework names + problem-type enums only; Canon Part 8: never a command string, never user content), composes that chain into `/mos:` commands via `lib/workflow/command-resolver.cjs` `composeWorkflow` (the SOLE framework -> command path, reading only the generated `data/command-registry.json`), and prints the run order. Then run the printed `/mos:` commands in sequence using the Stage Execution Loop machinery below -- one resolved command per step. For a step whose framework has no `/mos:` command, the helper prints "no /mos: for <framework> -- run it manually; continuing"; skip that step (or run the framework manually) and continue. Every command the helper prints exists in the registry -- the resolver only ever returns registered commands, so you never invoke a `/mos:` that does not exist.
32
+
33
+ `--from-problem-type` accepts the canonical `UDP` / `IDP` / `WDP` tokens and the `undefined` / `ill-defined` / `well-defined` aliases. With neither flag and no named pipeline, the helper falls back to the room's `ProblemType` from `room/STATE.md`.
34
+
23
35
  ## Brain Enhancement (Optional)
24
36
 
25
37
  Try calling Brain: first `mcp__mindrian-brain__brain_schema`, then `mcp__mindrian-brain__get_neo4j_schema` as fallback. If it succeeds, Brain mode is active. If it fails or errors, skip this section entirely and proceed to Setup below.
@@ -45,6 +57,9 @@ Proceed to Setup below with this additional context. Static chains remain the de
45
57
 
46
58
  ### Chain Selection
47
59
 
60
+ **If user passes `--from-problem-type <x>` or `--from-framework <x>`:**
61
+ Run the helper above (`scripts/pipeline-command.cjs`) to Brain-derive the chain and get the resolver-composed `/mos:` run order, then execute those commands in sequence via the Stage Execution Loop. This is the dynamic, graph-derived path -- no `CHAIN.md` file involved.
62
+
48
63
  **If user specifies a pipeline name** (e.g., `/mos:pipeline discovery`):
49
64
  Load `pipelines/{name}/CHAIN.md` and proceed to Stage 1.
50
65
 
package/commands/setup.md CHANGED
@@ -142,7 +142,7 @@ Remove `neo4j-brain` and `pinecone-brain` from `.mcp.json` if present.
142
142
 
143
143
  Ask the user:
144
144
 
145
- > "Do you have a Brain API key? If not, request one at mindrianos-jsagirs-projects.vercel.app/brain-access -- you'll get it within 24 hours."
145
+ > "Do you have a Brain API key? If not, request one at mindrianos.vercel.app/brain-access -- you'll get it within 24 hours."
146
146
 
147
147
  If the user provides a key:
148
148
 
@@ -163,9 +163,13 @@ if [ -f ~/.mindrian.env ] && grep -q "MINDRIAN_BRAIN_KEY" ~/.mindrian.env; then
163
163
  else
164
164
  echo "MINDRIAN_BRAIN_KEY=<their-key>" >> ~/.mindrian.env
165
165
  fi
166
+ # SEC-02 (Phase 123 Plan-07): lock down permissions on POSIX (no-op on Windows).
167
+ # Without this, lib/core/resolve-brain-key.cjs refuses to load the key from a
168
+ # group/world-readable file and session-start shows "Brain: NOT loaded".
169
+ chmod 600 "$HOME/.mindrian.env" 2>/dev/null || true
166
170
  ```
167
171
 
168
- Tell the user: "Key saved to both your project `.env` and `~/.mindrian.env` (global backup). Brain will connect from any directory now."
172
+ Tell the user: "Key saved to both your project `.env` and `~/.mindrian.env` (global backup, chmod 600). Brain will connect from any directory now."
169
173
 
170
174
  ### 4. Test Connection
171
175
 
@@ -206,7 +210,7 @@ curl -s -w "\n%{http_code}" --max-time 15 \
206
210
  > "Brain connected and verified. Larry just got smarter. Your existing commands now have graph intelligence behind them. Try `/mos:suggest-next`."
207
211
 
208
212
  **On health OK but key auth failure (401):**
209
- > "Brain server is up, but your key was rejected. Double-check the key you received, or request a new one at mindrianos-jsagirs-projects.vercel.app/brain-access"
213
+ > "Brain server is up, but your key was rejected. Double-check the key you received, or request a new one at mindrianos.vercel.app/brain-access"
210
214
 
211
215
  **On health OK but key verification timeout:**
212
216
  > "Brain server is up and your key is saved. Verification timed out but that is normal on first connect. Try `/mos:suggest-next` to confirm it works."
@@ -17,9 +17,23 @@ allowed-tools:
17
17
 
18
18
  # /mos:suggest-next
19
19
 
20
- You are Larry. This command uses the Brain graph to recommend what the user should work on next based on their current room state and framework chains.
20
+ You are Larry. This command recommends what the user should work on next as a COMMAND SEQUENCE, not just a list of frameworks: it reads the room's ProblemType (and active JTBD), Brain-derives the framework chain, and composes that chain into the exact `/mos:` commands to run, in order.
21
21
 
22
- **Requires Brain MCP.** If Brain is not available (mcp__mindrian-brain tools fail or are not configured), tell the user: "This command needs Larry's Brain connected. Run `/mos:setup brain` to set it up." Then stop.
22
+ ## The resolver is the only door
23
+
24
+ Run the helper to get the resolver-composed command sequence:
25
+
26
+ ```bash
27
+ node "${CLAUDE_PLUGIN_ROOT}/scripts/suggest-next-command.cjs" --room ./room
28
+ ```
29
+
30
+ It reads `room/STATE.md` for the ProblemType / active JTBD (or pass `--problem-type <x>` / `--from-framework <x>` explicitly), calls `lib/brain/chain-recommender.cjs` `recommendFrameworkChain` (a FEEDS_INTO traversal -- framework names + problem-type enums only; Canon Part 8: never a command string, never user content), composes the chain into `/mos:` commands via `lib/workflow/command-resolver.cjs` `composeWorkflow` (the SOLE framework -> command path, reading only the generated `data/command-registry.json`), and prints BOTH the framework chain AND the step-numbered command sequence. A framework with no `/mos:` yet renders as "(no /mos: for this -- run it manually)" -- degrade, do not fabricate.
31
+
32
+ **Larry NEVER names a `/mos:` command from memory.** Every command you surface came back from the resolver via this helper. If you find yourself about to type a `/mos:` you have not seen the resolver return, stop -- run the helper first. Render in Shape B (Semantic Tree) per `skills/ui-system/SKILL.md`; do not invent a format.
33
+
34
+ When Brain is connected you may additionally weave the co-occurrence narrative below; when it is not, the helper still produces a true command sequence from the registry (framework-only advice degrades gracefully -- still through the resolver).
35
+
36
+ **Note on Brain MCP:** the deeper "similar venture patterns" enrichment below benefits from Brain. If Brain is not available, skip those queries -- the resolver-composed sequence above still stands.
23
37
 
24
38
  ## Setup
25
39
 
@@ -61,7 +75,7 @@ Combine both query results. Present 2-3 next steps ranked by:
61
75
  - Co-occurrence patterns from similar ventures
62
76
 
63
77
  For each recommendation:
64
- - **What to do:** Name the framework and the specific `/mos:` command to run
78
+ - **What to do:** Name the framework AND the specific `/mos:` command -- but take the command from the helper's resolver-composed sequence above (or `lib/workflow/command-resolver.cjs` `commandsForFramework(<framework>)`), never from memory. If a framework has no command, say "run <framework> manually -- there is no /mos: for it" rather than inventing one.
65
79
  - **Why this sequence:** Cite the relationship type from the graph (e.g., "Explore Domains FEEDS_INTO Analyze Needs with 0.85 confidence -- mapping the landscape first sharpens your customer discovery")
66
80
  - **What similar ventures did:** Reference co-occurrence data ("Projects that used Beautiful Question most commonly followed with Explore Domains or Map Unknowns")
67
81