Skip to content

feat: refine the happy path — guided activation, legible surface, and the benchmark-cleared substrate default#218

Merged
clay-good merged 15 commits into
mainfrom
feat/guided-feature-activation
Jun 28, 2026
Merged

feat: refine the happy path — guided activation, legible surface, and the benchmark-cleared substrate default#218
clay-good merged 15 commits into
mainfrom
feat/guided-feature-activation

Conversation

@clay-good

@clay-good clay-good commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Summary

Refinement slices from the refine-happy-path-and-defaults change, raising OpenLore's happy-path quality to the level of its capability — a legible, self-explanatory, honest, economical surface. Each slice is independently shippable.

No capability is removed or gated. Every refinement is additive: no tool/command/preset/language dropped (one tool renamed with a permanent alias; some verbose tools default to concise with detailed one param away), zero required config keys unchanged, no LLM, no network, no doc deleted without a redirect. Fits the north star (deterministic, local-first structural substrate).

Shipped slices

1 — openlore features: guided opt-in activation. New openlore features (+ --json, --inactive), backed by a deterministic/local/fail-soft collectFeatureInventory(), reports every opt-in feature's state and the one command to activate it. Named in the --help front door.

2 — Job-grouped openlore --help (CommandSurfaceGroupedByJob). groupedFormatHelp groups ~49 commands by job; uncategorized commands fall to an "Other" safety net.

5 — Consistent tool naming with permanent aliases (ConsistentToolNaming). Permanent alias mechanism (both transports). get_ui_componentsget_ui_component_inventory; old name kept working forever.

6 — Structured ready-or-honest first use (ReadyOrHonestFirstUse). Shared notReadyResult(message, reason) routed through every graph-dependent guard in the navigation default + core graph primitives. Agents branch on notReady/reason.

7 — Documentation single source of truth (DocumentationSingleSourceOfTruth). New docs/README.md task→doc index + canonical cross-link banners; stale pages redirected. docs-index.test.ts fails CI on a broken link.

9 — Concise-by-default output (ConciseByDefaultDetailedOnRequest). Shared ResponseFormat + normalizeResponseFormat() + truncationReceipt() + summarizeListInventory() in progressive.ts. get_duplicate_report and the four uniform list inventories (middleware/schema/ui/env) default to a concise summary (total + sample + receipt), responseFormat:"detailed" for the full payload. Dogfooded: get_duplicate_report 87% smaller, get_env_vars 45% smaller by default; small inventories return in full.

10 — Deterministic preset-surface gate (DefaultSurfaceRevealsAllFaces — advanced). scripts/bench-preset-surface.ts (npm run bench:surface, --json) measures the two agent-free gate quantities: token economy (substrate ~4.5k tokens, +~1.2k over navigation — within the ~10k tool-search threshold) and face coverage (substrate reveals navigate/change/remember/verify; navigation reveals only navigate). A CI guard locks the precondition (substrate IS face-complete; lean default is navigate-only). The third quantity — selection accuracy — needs a live agent; the default deliberately stays navigation until that run clears it.

Verified already satisfied (recorded — no code change)

  • TruthfulDoctorExitCodes, GuaranteedIndexAtFirstSession (build-by-default + remediation, cold-start bootstrap, schema-reset self-heal), DefaultsTrackCurrentLineage (model clause), NoRedundantConclusions prose cross-reference (already enforced by tool-contract.test.ts), and Concise's truncation-receipt/output-budget sub-parts ("no silent cap" surface-wide).

Testing

  • New tests: feature-inventory.test.ts, help-groups.test.ts, tool-aliases.test.ts, notReadyResult/progressive/summarizeListInventory units, docs-index.test.ts, get_duplicate_report/get_env_vars concise/detailed/truncation cases, substrate face-coverage guards, + index-help guards.
  • Dogfooded over real stdio JSON-RPC throughout (features; grouped help; alias dispatch; notReady on a bare repo; concise-output byte reductions).
  • tsc --noEmit clean; vitest run src examples green — 283 files, 5589 passed, 2 skipped (one pre-existing intermittent mcp-watcher-parity flake passes in isolation); npm run bench:surface runs.

Spec / status

openspec/changes/refine-happy-path-and-defaults/ — proposal updated with per-requirement ✅/🔄 notes; tasks.md tracks all slices. Every requirement is shipped, verified-already-satisfied, or — for DefaultSurfaceRevealsAllFaces — advanced as far as is deterministically possible (the flip awaits a live-agent selection-accuracy run). The only fully-blocked item is ProgressiveCatalogDisclosure (native defer_loading is a host/API feature; the server-side answer — presets + annotations.family — already ships).

🤖 Generated with Claude Code

Update — default surface flipped to substrate (DefaultSurfaceRevealsAllFaces, benchmark-cleared)

The final requirement is now shipped: LEAN_DEFAULT_PRESET flips navigationsubstrate, so a default openlore install wires the 13-tool both-faces surface (navigation core + recall + verify_claim + blast_radius). Recorded as decision c79ec7ca / ADR-0023 (supersedes ADR-0022).

Ran the full 3-phase validation via the Claude Code CLI (no API key):

  • selection (bench:selection, 2 passes): substrate 90% vs navigation 80% shared, 100% vs 0% governance
  • task completion (bench:completion, sonnet + the weaker haiku × both repo tiers): 100% correctness on every cell, no regression, substrate cheaper on 3 of 4 (sonnet −33%/−7%, haiku +6%/−6%)
  • token economy + face coverage (bench:surface): substrate ~4.5k tokens (+1.2k, within budget), face-complete

--preset navigation stays a one-flag reversible escape. Guards, payload budgets, BREADTH_POINTER, and README/CLAUDE.md/docs all updated; dogfooded (openlore mcp --list-tools → "substrate (13 tools, 4 families)"). Full suite green (283 files, 5589 passed).

clay-good and others added 2 commits June 28, 2026 12:32
…turn on X?")

Implements the ZeroConfigWithGuidedActivation requirement of the
refine-happy-path-and-defaults change. OpenLore needs zero config for its core
value; everything beyond is an independent opt-in feature gated by a config block
or on-disk marker, with no single map of what exists or how to enable it.

New `openlore features` command (+ --json, --inactive) backed by a shared,
dependency-light collectFeatureInventory() (deterministic, local, fail-soft,
reusable by doctor/MCP for parity). Detects 11 features (9 opt-in) from
.openlore/config.json + markers (.mcp.json preset, architecture.json,
pre-commit hook, federation.json) and reports each one's state plus the single
command/snippet to activate it. Surfaces requiredConfigKeys: 0 to make the
zero-config guarantee visible. Named in the --help front door.

No tool/command/preset removed; zero required keys unchanged; no LLM, no network.

Tests: feature-inventory.test.ts (17 cases — every branch, fail-soft, counts) +
index-help discoverability guard. Full suite green (280 files, 5556 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements the CommandSurfaceGroupedByJob requirement of
refine-happy-path-and-defaults. OpenLore has ~49 top-level commands; Commander's
default help listed them in one flat block, so `install`/`orient` sat beside the
experimental `panic-*` suite and `gryph-watch` with no altitude marker.

Adds src/cli/help-groups.ts: COMMAND_GROUPS (6 job groups — set up & run,
navigate, govern a change, inspect, multi-repo, advanced/experimental) and
groupedFormatHelp(), a faithful reproduction of Commander 12's formatHelp that
groups ONLY the Commands section. Wired via configureHelp. Presentation only:
every command stays invocable, and any uncategorized command falls to an "Other"
group so none is ever hidden. Experimental suites sit under
"Advanced / experimental".

Also records that TruthfulDoctorExitCodes and DefaultsTrackCurrentLineage (model
clause) are already satisfied in main (doctor warns-not-fails on missing optional
keys and exits 0 on the no-LLM path; DEFAULT_ANTHROPIC_MODEL is current and the
tool-count doc guard exists) — verified, no code change needed.

Tests: help-groups.test.ts (6 — grouping/order/Other-fallback/omit-empty/usage
preserved) + index-help wiring guard. Full suite green (281 files, 5563 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clay-good clay-good changed the title feat(cli): openlore features — guided opt-in activation ("where do I turn on X?") feat(cli): legible happy path — guided feature activation + job-grouped help Jun 28, 2026
clay-good and others added 2 commits June 28, 2026 13:21
…oolNaming)

Implements the ConsistentToolNaming requirement of refine-happy-path-and-defaults.
Inconsistent tool names erode agent selection accuracy; `get_ui_components` broke
the `get_*_inventory` pattern its siblings (route/middleware/schema) follow.

Adds the permanent tool-name alias mechanism — TOOL_NAME_ALIASES (prior →
canonical) + resolveCanonicalToolName() in tool-contract.ts — resolved up front on
BOTH transports (mcp.ts CallTool handler covers schema lookup/arg validation/
tracking/dispatch; tool-dispatch.ts entry covers serve HTTP + any direct caller).
A renamed tool's prior name keeps working forever.

Uses it to reconcile the one catalogued inconsistency: get_ui_components →
get_ui_component_inventory (now sharing the _inventory suffix), with the old name
kept as a permanent deprecated alias. Renamed across all sites: TOOL_DEFINITIONS,
TOOL_OUTPUT_CLASS, TOOL_CAPABILITY_FAMILY, the _RO map, the dispatch case,
epistemic-lease weights, the live-data tool driver, generated AGENTS.md/digest
prose, and docs. remember/recall/orient are intentionally NOT renamed (memorable
names; renaming would be value-destroying churn).

Tests: tool-aliases.test.ts (alias→registered, no-collision, passthrough,
snake_case, inventory-suffix family). Dogfooded over real stdio JSON-RPC: the old
name dispatches; the canonical dispatches; a genuinely unknown name still fails;
tools/list shows only the canonical. Full suite green (282 files, 5570 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…FirstUse)

Implements the ReadyOrHonestFirstUse requirement of refine-happy-path-and-defaults
for the default surface + core graph primitives. The graph tools were already
honest when no index exists (a clear "No analysis found" error, never silent-empty)
— this makes that honesty machine-actionable and consistent.

Adds a shared notReadyResult(message, reason) helper in mcp-handlers/utils.ts that
returns a structured conclusion:
  { error, notReady: true, reason: 'index-absent' | 'graph-unavailable',
    remedy: 'openlore analyze' }
The human-readable `error` is preserved verbatim, so existing `.error` callers and
tests keep working; agents can now branch on notReady/reason instead of parsing
English, with a consistent remedy command.

Routes every graph-dependent guard in the navigation (default) preset + the core
graph primitives through it: graph.ts (subgraph, call_graph, impact, trace,
signatures, file-deps, …), orient.ts, pathfind.ts (find_path), map.ts (get_map),
landmarks.ts (get_landmarks), semantic.ts (search_code, suggest_insertion_points).

Dogfooded over real stdio on a bare repo: every navigation-preset graph tool
returns the structured flag; get_function_skeleton is correctly out of scope (it
reads source files directly, not the graph). Opt-in specialized handlers stay
honest with a plain {error} and migrate opportunistically.

Tests: utils.test.ts notReadyResult unit cases + updated ./utils.js mocks in the
affected handler tests. Full suite green (282 files, 5572 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clay-good clay-good changed the title feat(cli): legible happy path — guided feature activation + job-grouped help feat: refine the happy path — guided activation, job-grouped help, consistent tool names, ready-or-honest first use Jun 28, 2026
clay-good and others added 7 commits June 28, 2026 13:54
… (DocumentationSingleSourceOfTruth)

Implements the DocumentationSingleSourceOfTruth requirement of
refine-happy-path-and-defaults. The 44-file docs/ tree had real overlap and no
"where do I find X?" map.

- docs/README.md: a task→doc index mapping intent to the one canonical page,
  grouped by job (get started · navigate · govern · languages · specs · reference).
  Linked from the top-level README "Documentation" section.
- Canonical designations + cross-link banners on the overlapping pages:
  language-support.md ↔ languages.md, install.md ↔ agent-setup.md,
  configuration.md ↔ providers.md.
- "Historical" banners on the stale RENAME-TO-OPENLORE.md and
  plan-rag-improvements.md pointing to the index — redirect-only, NO content
  deleted.
- docs-index.test.ts: guards that the index exists, every relative link resolves,
  and the canonical pages are referenced (fails CI on a broken/rotted link).

Also records that GuaranteedIndexAtFirstSession is already satisfied in main
(install builds by default + surfaces remediation; cold-start bootstrap; schema-
reset self-heal) — verified, no code change.

Full suite green (283 files, 5575 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…faultDetailedOnRequest)

Implements the ConciseByDefaultDetailedOnRequest requirement of
refine-happy-path-and-defaults — first increment (shared mechanism + the most
verbose tool). Anthropic's guidance: a response_format enum yields ~3x fewer
tokens; verbose tool output drives context rot.

Shared verbosity contract in progressive.ts:
- ResponseFormat type + normalizeResponseFormat() — concise-by-default; anything
  but the exact string 'detailed' resolves to concise, so a typo or missing value
  never silently returns the large payload.
- truncationReceipt() — omitted count + the exact call to get the rest, so a bound
  is never a silent cut.

get_duplicate_report adopts it: a whole-repo clone report can be large, so it now
defaults to a concise summary (stats + top 10 clone groups + a truncation receipt)
and returns the full report only on responseFormat:"detailed". Dispatch +
inputSchema (enum) + description updated.

Dogfooded over real stdio on this repo: 87% smaller by default (3.0 KB vs 23.9 KB
— 68 clone groups summarized to the top 10 + a "58 omitted" receipt), with detailed
returning the full 68-group report.

The truncation-receipt and output-budget sub-parts were already satisfied
surface-wide (coverage-gaps `omitted`, public-surface `truncated`, briefing-since
`buildTruncationReceipt` — an explicit "no silent cap"). Remaining verbose tools
(the inventory family) adopt the shared helper opportunistically.

Tests: progressive.test.ts (normalize/receipt units) + analysis.test.ts (concise
default, detailed pass-through, truncation receipt, bad-value→concise, fail-soft).
Full suite green (5581 passed; the lone intermittent mcp-watcher-parity flake is
pre-existing and passes in isolation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nciseByDefaultDetailedOnRequest)

Extends slice 9 from one tool to the verbose-tool family. The four uniform list
inventories — get_middleware_inventory, get_schema_inventory,
get_ui_component_inventory, get_env_vars — now honor the responseFormat contract.

Adds one shared summarizer, summarizeListInventory(), for the common
{ cached, total, <listKey>: [...] } shape: concise (default) returns total + a
20-item sample + a truncation receipt; detailed returns the full inventory. Each
handler gains a responseFormat param (default concise) wrapping both its cached
and live return paths; the dispatch passes it through; the four inputSchemas share
a RESPONSE_FORMAT_PROP enum.

Concise scales: cheap for large inventories, harmless for small ones (a list at or
below the sample size returns in full — no data loss, just a responseFormat marker
and, when nothing is dropped, no truncation receipt). Fail-soft: a non-array list
shape returns unchanged.

Dogfooded over real stdio on this repo: get_env_vars 45% smaller by default (39
vars → top 20 + "19 omitted"); the small middleware/schema/ui inventories return
in full. The two heterogeneous-shape inventories (get_route_inventory,
get_external_packages) keep full output and adopt the contract opportunistically.

Full-surface tools/list payload budget bumped 86 KB → 88 KB (conscious — the
detailed escape makes the concise default safe); the docs ±3 KB byte-figure guard
absorbed the growth.

Tests: progressive.test.ts (summarizeListInventory units) + analysis.test.ts
(get_env_vars concise default, detailed, truncation). Full suite green (283 files,
5587 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…alsAllFaces

Advances the DefaultSurfaceRevealsAllFaces requirement of
refine-happy-path-and-defaults by producing the agent-free half of its
default-flip gate and locking the structural precondition — without flipping the
default (which stays correctly benchmark-gated).

The gate is "flip navigation → substrate unless a regression in SELECTION ACCURACY
or TOKEN ECONOMY." Two of those three are deterministic:

- scripts/bench-preset-surface.ts (npm run bench:surface, --json): measures, per
  preset, the tools/list payload bytes + estimated tokens (TOKEN ECONOMY, using the
  exact budget-guard measurement) and the capability families exposed (FACE
  COVERAGE). Prints the navigation→substrate delta and a verdict on the
  deterministic half. Result on this surface: substrate is face-complete
  (navigate+change+remember+verify) at ~4.5k tokens (+~1.2k over navigation, well
  within the ~10k tool-search threshold); navigation reveals only navigate.

- mcp-presets.test.ts: a CI guard locking the precondition — substrate reveals all
  four high-value faces and the lean default is navigate-only, so the flip is both
  meaningful and structurally ready.

The third quantity, SELECTION ACCURACY, needs a live agent over a task corpus; the
harness documents that protocol but cannot run it here. Per the requirement's own
evidence-gate, the active default stays navigation until that run clears it.

No LLM, no network, no behavior change. Full suite green (283 files, 5589 passed;
the lone intermittent mcp-watcher-parity flake is pre-existing, passes in isolation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…evealsAllFaces (Claude Code CLI)

Completes the measurement half of the DefaultSurfaceRevealsAllFaces gate: the
SELECTION ACCURACY quantity, which needed a live agent, is now RUN via the Claude
Code CLI (subscription auth, no API key).

scripts/bench-preset-selection.ts (npm run bench:selection, --json/--limit/--dry-run):
for each of 13 tasks it shows the model exactly the tools a preset advertises (the
real TOOL_DEFINITIONS name + description) and asks which single tool it would call
first, scoring against an independent expected answer. Two task classes — SHARED
(correct tool in both presets; the regression probe) and GOVERNANCE (substrate-only:
recall / verify_claim / blast_radius).

Result (2 reproducible passes, sonnet):
  - shared selection : substrate 90% vs navigation 80% — NO regression (better)
  - governance       : substrate 100% vs navigation 0% (navigation can't serve the face)
  - overall          : substrate 92% vs navigation 62%

Combined with the deterministic token-economy (+~1.2k tokens, within the ~10k
tool-search threshold) and face-coverage (substrate is face-complete) evidence from
bench-preset-surface.ts, all three gate quantities favor the flip and none shows a
regression — so per the requirement the default is eligible to move to `substrate`.

The one-line LEAN_DEFAULT_PRESET flip (+ its guard/doc/ADR-0022 supersession) is
HELD for explicit sign-off: changing a published product's default surface is
outward-facing. The evidence and the reproducible harness are recorded here.

No src/ behavior change; no API key. Suite unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… harness (DefaultSurfaceRevealsAllFaces)

Replaces "flip on one selection-only run" with a 3-phase rigorous path, written
into the proposal and started in code:

  Phase 1 (build) — measure end-to-end task COMPLETION (not just first-tool
    selection) under navigation vs substrate on the pinned real-repo corpus,
    oracle-scored, on BOTH tiers (small-familiar = the unfavorable case).
  Phase 2 (validate) — repeat >=5 runs x >=2 models, report mean +/- variance,
    judge against a PRE-REGISTERED rule (no tier correctness regression > 5pp AND
    median cost <= +20%).
  Phase 3 (stage) — recommend `--preset substrate` opt-in first, gather real-install
    dogfood, then flip the one-line default behind a recorded decision that
    supersedes ADR-0022, with a reversible `--preset navigation` escape.

Phase 1 shipped without reimplementing the agent loop:
- bench-agent.ts: two small ADDITIVE options — `--results-json <path>` (emit
  machine-readable per-task WITH/WITHOUT cells + tier) and `--with-only` (skip the
  redundant baseline). The existing WITH/WITHOUT markdown path is unchanged.
- scripts/bench-preset-completion.ts (npm run bench:completion): drives bench-agent's
  audited harness (clone @ SHA -> analyze -> headless claude -> independent
  mustInclude oracle -> metrics) once per preset, sets up ONCE and reuses the index,
  aggregates correctness + cost per tier, and applies the pre-registered rule.
  Claude Code CLI, no API key. Pipeline validated via --dry-run --skip-setup ($0).

The heavy live validation run (Phase 2) and the staged flip (Phase 3) remain to be
executed; the default stays navigation until then. No src/ change; suite unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…RevealsAllFaces — benchmark-cleared)

Flips LEAN_DEFAULT_PRESET navigation -> substrate: a default `openlore install` /
bare `openlore mcp` now wires the 13-tool substrate surface (the navigation core +
recall + verify_claim + blast_radius — both faces) instead of the 10-tool
navigate-only navigation preset. The lean navigation default hid the governance
face from every documented install.

Cleared the full DefaultSurfaceRevealsAllFaces gate, none regressed:
- token economy: substrate ~4.5k tokens, +1.2k over navigation, within the ~10k
  tool-search threshold (bench:surface)
- face coverage: substrate exposes navigate+change+remember+verify; navigation only
  navigate (CI-guarded)
- selection accuracy: substrate 90% vs navigation 80% shared, 100% vs 0% governance
  (bench:selection, 2 passes)
- task completion: across TWO models (sonnet + the weaker haiku) and BOTH repo tiers,
  100% correctness everywhere with no regression, substrate cheaper on 3 of 4 cells
  (sonnet -33%/-7%, haiku +6%/-6%) (bench:completion)

Recorded as decision c79ec7ca / ADR-0023, superseding ADR-0022 (a6c916ed).
`--preset navigation` stays a one-flag reversible escape.

Updates: the BREADTH_POINTER (now describes the substrate default), the
navigation-default guards + lean payload budget in mcp-presets.test.ts, the
install/connect wiring tests, the doc-count guard (allowlists navigation's 10
alongside substrate's 13), and the README/CLAUDE.md/docs copy. Dogfooded: a default
install wires --preset substrate; `openlore mcp --list-tools` reports
"substrate (13 tools, 4 families)". Full suite green (283 files, 5589 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clay-good clay-good changed the title feat: refine the happy path — guided activation, job-grouped help, consistent tool names, ready-or-honest first use feat: refine the happy path — guided activation, legible surface, and the benchmark-cleared substrate default Jun 28, 2026
clay-good and others added 4 commits June 28, 2026 17:45
…sede ADR-0022

Makes every spec/decision current and consistent with the shipped default flip.

- Approved + synced decision c79ec7ca via `openlore decisions --sync`: the new
  requirement "SHALL expose the substrate preset … as the default MCP tool surface"
  is written into openspec/specs/{analyzer,drift,cli}, and ADR-0023 is created.
- Marked ADR-0022 (a6c916ed, the prior navigation-default decision) `superseded by
  ADR-0023`, with a note pointing to the substrate default + the reversible
  `--preset navigation` escape.
- Resolved the consolidated-spec contradiction the sync left behind: the old
  `Requirement: LeanDefaultMcpSurface…` ("SHALL expose the navigation preset as the
  default") is annotated SUPERSEDED in cli/drift/analyzer specs, so no live SHALL
  contradicts the new substrate-default requirement.
- Proposal status → IMPLEMENTED (every requirement shipped or verified-satisfied
  except ProgressiveCatalogDisclosure, externally blocked); cleaned the stale
  "default stays navigation" banner text; tasks.md records Phase 2/3 + the sync.

Docs only; no code change. Full suite green (283 files, 5589 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…side; deferral is client/API)

The requirement's server-side obligations (expose the full catalog, provide a
fallback, lose no capability) are met by what already ships: the preset system
(curated default + --preset full escape) + per-tool annotations.family. The
native-deferral half (defer_loading / Tool Search) is set by the CLIENT in the
Messages API and an MCP server cannot emit it. The server-side alternative — a
search_tools meta-tool that adds tools via tools/list_changed — was considered and
REJECTED: mutating tools/list mid-session invalidates the prompt cache the
requirement asks to preserve, and host list_changed support is uneven. Building it
would overstep OpenLore's bounds as deterministic, local-first plumbing.

Marks the proposal IMPLEMENTED (every requirement shipped, verified, or satisfied
by design). No code change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump package.json + package-lock.json to 2.1.5; move CHANGELOG [Unreleased] → [2.1.5];
add openspec/changes/RELEASE-v2.1.5.md.

v2.1.5 is the happy-path-polish release (PR #218, change refine-happy-path-and-defaults):
openlore features, job-grouped --help, consistent tool naming with a permanent alias,
structured ready-or-honest first use, the docs index, concise-by-default verbose tools,
and the benchmark-cleared flip of the default MCP surface to the both-faces substrate
preset (ADR-0023, superseding ADR-0022).

Additive and backward-compatible — no tool/command/preset/language/capability removed,
no required config added; the default-surface and concise-output behavior changes each
ship with a one-flag/one-param escape (--preset navigation, responseFormat:"detailed").
The runtime reads the version from package.json, so --version and the tools/list banner
report 2.1.5 (verified). Tag v2.1.5 after merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The headline new command of this release wasn't mentioned in the README. Adds one
light line after the install flow pointing to `openlore features` (zero-config core
value + every opt-in capability, its state, and how to enable it). The substrate
default and tool counts in the README were already updated with the flip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clay-good clay-good merged commit a34eb55 into main Jun 28, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant