Release Observatory

The last two months, curated.

Everything notable that shipped in spruce-grove over the past 60 days, with plain-language breakdowns of what it is, what it does, and why it matters — plus a complete index of the smaller work.

275
commits
12
features
22
bug fixes
61
tools
7
agents
71
plugins

Upstream Connector living link

Spruce Grove is grown from Code Puppy (MIT, Michael Pfaffenberger and contributors) — not away from it. This connector is the standing agreement to keep watching the upstream line: see what they ship, judge whether it helps this grove, port what does, and log what differs. Of the updates on this page, the live tally in the strip below the header is computed from commit authorship on every page load — every entry above carries its badge, and the counts can never drift from the evidence.

The line, verbatim

from PROVENANCE.md
  • Upstream: github.com/mpfaffenberger/code_puppy — the living source we learn from
  • Working fork: github.com/t-granlund/code_puppy — where the grove's own commits live
  • Sync point: merge d819ae4e — 0 upstream commits behind at import
  • Import: pristine copy became commit #1; rebrand applied in audited passes after

The contracts that keep it safe

compatibility, kept on purpose
  • code_puppy.* imports resolve to spruce_grove.* via the meta-path shim — upstream patterns keep working
  • Entry-point group code_puppy.plugins retained — upstream plugin bundles load unrenamed
  • code-puppy-core-plugins stays a pinned dependency — upstream's official bundle ships to us directly
  • Rename map is audited, not improvised — every port lands rebrand-clean

The Leather Apron Gate

counsel · nothing passes unjudged
What it is
The standing review that every signal from the upstream line must face before it touches this grove — and that our own work must face before it ships. The Junto's question, made mechanical: is it tried, true, and honest — or manic, insecure, or risky?
What it does
Every live-feed row arrives wearing ⧗ awaiting counsel. A human counsel member judges it against five criteria: tried & true (battle-tested, no surprise dependencies), secure (no new exfiltration surface, secrets stay in the grove, supply chain clean), honest (docs match behavior, no vanity numbers), grove-fit (passes the rename map and compatibility contracts), and counsel sign-off (an apron-wearer says yes). Only then does the badge flip.
Why it matters
Staying connected to upstream is free leverage; accepting upstream blindly is how a supply chain becomes an attack chain. The connector is read-only public metadata — no tokens, no code, no identity ever crosses it. The gate is the only door.

Live upstream feed

api.github.com · checked on every page load · no cache

Listening for the upstream pulse…

The Living Log voice-led

This is the live stream of how the harness evolves — the primary engine, not a side channel. The loop: speak (dictate while building) → capture (entries land in LIVING-UPDATES.md as they happen) → gate (every signal — ours and upstream's — faces the Leather Apron criteria below) → ship (the self-healing release train carries it) → observe (this page, live) → learn (port what helps, log what differs). The founding story and the rules of the grove live in MANIFESTO.md. Entries age from idea through in flight to shipped, and the shipped ones graduate into

21 entries · newest first

2026-09-23 — The boot mark learns to wiggle, and Wiggledom becomes the fourth pillar

shipped · build session (Jacob Collier's "The Wiggly Wonder of Music") · grove-grown
What happened
The boot wordmark was pyfiglet's ansi_shadow — chunky solid blocks that read as 8-bit. It is now drawn in braille: dots, not slabs, with the curved, organic letterforms the grove deserves. banner_art.py and splash.py both carry the new bake; the splash taught itself a braille tier map (cells with an interior dot are the neon core, the rest glow). Same contract, unchanged: six rows, SPRUCE GROVE exactly 96 columns.
The idea behind the art became the idea behind the tool. Wiggledom is now the fourth pillar in ETHOS.md (README too): melody is the through-line, rhythm is space and pace, harmony is the relationship between the parts. Straight lines are brittle; the wiggle is water. The boot tagline now closes with there are no straight lines in nature.
The Collier transcript moved into docs/ (kebab-cased), beside the other talk transcripts, as the reference for the new pillar.
The cli.banner.grove_closer key was missing from es and fr-CA catalogs — a pre-existing i18n gap, closed while here.
Made durable. The art lives in two places by necessity (splash.py cannot import spruce_grove and keeps its own copy), so the baker is now scripts/bake_braille_banner.py with a --check drift guard: it re-derives the art and fails if either copy has wandered. Pillow was already a runtime dependency, so nothing new was pulled in. tests/test_banner_durability.py (21 tests) locks the contract cross-platform — 6 rows, 96 columns, braille-only, both copies byte-identical — and, wherever a usable font exists, asserts a fresh bake reproduces the committed art exactly.

2026-09-22 — Fifteen private agents cross into the grove, and the last code_puppy tie gets a name

shipped · build session ("port over all the agents I had so they stand completely on their own") · grove-grown
What happened
the steward's code_puppy agents turned out to be 15 JSON definitions in ~/.code_puppy/agents/ - not the Python framework under code_puppy/agents/, which grove already carried. All 15 now live in ~/.spruce_grove/agents/: the roster went 8 -> 22.
Porting was a migration, not a copy: agent references (code-puppy -> spruce-grove, web-puppy -> web-retriever), config paths (~/.code_puppy -> ~/.spruce_grove), and trailing-space display_names. Agents keep their own names, including web-puppy, which coexists with grove's built-in web-retriever.
They stay private. These files carry real business context and the repo is public; a public route is a later, deliberate decision.
Tooling landed in scripts/: port_code_puppy_agents.py (dry-run migration), dial_user_agents.py (audit: load, tool resolution, model pins; non-zero exit gates a pass), check_uc_tools.py.

2026-09-22 — The harness seam learns its own word for tool context: RunContext -> ToolContext

shipped · build session (harness exit, bead SPRUCE-GROVE-OS-tdy) · grove-grown
What happened
pydantic-ai detects the injected tool context by type identity, not by name, so the grove vocabulary could not be a fresh look-alike class -- it has to bind to the exact class the harness injects. That binding lives in the adapter and nowhere else.
New spruce_grove/harness/tool_context.py binds ToolContext = get_harness().tool_context_type() once at import; the protocol gains a pure tool_context_type() method and harness/__init__ exposes ToolContext lazily. protocol.py stays free of pydantic imports (structural test still green).
28 modules migrated off pydantic_ai.RunContext: all 21 tool modules, then the agent/model/MCP layers (gemini_model, round_robin_model, mcp_/managed_server, agents/_compaction, _model_message_transform, both stream handlers). Only the adapter files keep the direct pydantic-ai reference -- that's the point of a seam.

2026-09-22 — Model routing: the smart-routing config was silently dead — every agent rode the cheapest model

shipped · build session ("we're supposed to be smart about the right models for the right thing") · grove-grown
What happened
The steward's observation was exactly right: everything ran GLM-5.3-Flash. Three compounding causes, all verified: (1) the global default pointed at the pinned GLM-5.3-Flash entry instead of the syn:large:text driving seat; (2) all seven per-agent pins sat under an [agents] config section that NO code has ever read (the reader only scans [grove]) — dead config wearing a tie; (3) five of the seven pin names targeted legacy agent names (code_puppy, husky, web_puppy, junto…) that no longer exist — real names verified at runtime: spruce-grove, helios, planning-agent, model-judge, qa-kitten, web-retriever, agent-creator, mail-researcher (+ plugin agents backoffice, creative-scaffold).
THEN the fourth bug surfaced — the umbrella over everything: the rebrand renamed the config file puppy.cfg → grove.cfg in code but never migrated the file, so the steward's entire curated config sat in puppy.cfg while every supported version read a grove.cfg that did not exist. Identity, theme, routing: silently ignored since the rename. Shipped a one-time migration in ensure_config_exists (copy verbatim when grove.cfg is absent, legacy file kept as a backup, never overwritten, no dual-read), filed as COMPAT-EXIT contract #9, and ran it live: grove.cfg now exists with the full routing table.
Live routing table (verified by the new routing doctor — every pin targets a real agent AND a live catalog model, problems: NONE): driving seat → syn:large:text; reasoning agents (spruce-grove, helios, planning-agent, model-judge, qa-kitten) → syn:large:text; fan-out (web-retriever, agent-creator) → syn:small:text; compaction summarizer → hf:zai-org/GLM-5.3-Flash (cheapest class at full 524288 context; rotated pin degrades to the sliding-window fallback). The doctor itself caught two over-pins (backoffice/creative-scaffold are plugin commands, not agents) — removed.

2026-09-22 — The settings surface crosses the seam (harness exit 3 of 61)

shipped · build session ("review the transition state; finish the core things") · grove-grown
What happened
Census recomputed first, honestly: 61 files / 114 statements still import pydantic-ai; the old "2 of ~58" was true on 9/15 and had drifted since.
Three call-site files now route model resolution AND settings through the seam: agents/_builder.py — the agent construction path — no longer imports model_factory at all; tools/subagent_invocation.py and private_inference.py speak only grove vocabulary for resolution/settings (their remaining pydantic-ai imports are the agent loop, the next surface).
Six test files migrated to seam-level stubs (PydanticHarness methods or the canonical model_factory paths); the adapter's call-time delegation keeps the inherited patch seams alive. One honest behavior note captured in tests: the adapter forwards every parameter explicitly, so max_tokens=None now appears in call shapes (the inherited default either way).

2026-09-16 — Brand polish: every surface on the canonical kit, desktop included

shipped · build session ("logos not fully polished and applied everywhere") · grove-grown
What happened
Visual audit of all 14 live pages (rendered evidence, not vibes): the persona pages' wordmark chips still carried the pre-rebrand solid tile (tan rounded square, solid dark trees); the field-guide's primary logo was the legacy flat mark with a 404 favicon; retired dog-era SVGs still shipped in two asset dirs.
The desktop app (spruce-grove-desktop) rebuilt its entire Tauri icon set from the Core Disc: 15 pngs + multi-res ico + icns via iconutil; ui favicon swapped to the Disc data URI; README lockup added; the repo is now a sync-brand-assets.sh consumer (its grove-mark.svg was a stale generation - the sync loop caught it).

2026-09-16 — Rails continued + five dependency exits with receipts

shipped · build session ("rails: continue; complete any dependency exits needed") · grove-grown
What happened
Rails (AUTO): the weekly insurance snapshot ran and sealed (backups/20260915-235647.tar.gz + sha256, 28 repos mirror-cloned with issues/releases metadata); the D2 pip-audit re-run found 53 known vulnerabilities across 8 packages - every one bumped to its fix version, re-audit clean.

2026-09-16 — The validation ladder: desktop onboarding, traceability, the living directory

in flight · dictation session (the "biggest validations" question) · grove-grown
What happened
Three validations now name the next phase, captured in docs/VALIDATION-LADDER.md: (1) the desktop OS onboarding — persona-driven first runs that tune token economy and context utilization from minute one and make the synthetic-subscription path seamless; (2) the traceability program — generated matrices mapping every button, command, and feature to the test and the build-log receipt that proves it; (3) the living directory — opening a folder loads it as an organism with pulses, hooks, telemetry, and an audit trail, all voice-driven through mockingbird.
The small-business portfolio wedge opened with two Benton-Drones-style studies (private lab, local-only): one business books jobs by mailto: with no online booking at all; the other runs a commercial gym portal with no public schedule — both are exactly the gap the grove's small-business kit exists to fill.
The family-lab wedge (voice-first computing for the smallest builders) is captured privately and locally by design — the public repo never carries the people, only the product ideas.

2026-09-15 — The dashboard lands: release rail + dependency census go public

shipped · build session (the "level-set everything we borrow" question) · grove-grown
What happened
The stale solid-mark favicon pair left the repo root; the site serves the Disc, hash-verified against logos/.
docs/DEPENDENCY-EXIT.md: the full census of everything borrowed — six tiers, verdicts computed by import scans of grove source and the plugin package. npm/axios: zero in-repo. typer: computed unused, removal queued. CI action pinning and site-font self-hosting queued. httpx2 documented (codex/claude transports), requests dedupe queued, pyfiglet replacement queued.
/dashboard.html live on the public site: every release on the rail with what landed in it, and the dependency-exit ladder rendered from the in-repo board. Wired into pages.yml + the parity harness.
GitHub releases with real notes now exist for the rail (the tag was the only receipt since v1.0.1 — now the notes travel with it).
AGENTS.md back under the 10k cap so the agent rules load whole.

2026-09-15 — The execution board: the sovereignty work becomes runnable

in flight · build session (the "what can be automated" question) · grove-grown
What happened
The infrastructure runbook became a task board (docs/SOVEREIGNTY-EXECUTION.md) with one owner per task: the human for identity, payment, ceremony, and approval; scripts for everything that can be verified.
Automation kit landed in scripts/sovereignty/: the wall (arm_the_wall.sh), the insurance snapshot (backup_github.sh), the site-parity harness (build_site_parity.sh — byte-identical artifact proof for the rails migration), the clean-history export (fresh_history_export.sh), and the Forgejo/Woodpecker/Caddy stack templates.
First supply-chain audit ran against the actual ship set: one finding (a file-upload parser with a known advisory), fixed and re-audited to zero. The audit command is now part of the board.

2026-09-15 — The Council & The Wall: governance made public

in flight · council session (governance design) · grove-grown

2026-09-15 — The harness seam lands: the grove starts owning its own engine

in flight · birthday dictation + build session (the sovereignty push) · grove-grown
What happened
First two call sites migrated with behavior parity proven by tests (same raises, same fallbacks, same handle types). 56 remain; each lands one at a time, tests green, no big-bang rewrite — the Gate applies to our own work too.
Roadmap adopted into SOVEREIGNTY.md: inventory (done) → seam (landed) → grove implementation behind the seam → flip per model → prune. The north star beyond: a core so lean and standard it could wake on real hardware, agnostic and self-owned — the destination, not the next step.

Extensibility & Plugins 3 headliners 1 grove-grown · 2 upstream-synced

The platform keeps growing by composition, not by core bloat. These three changes formalized how plugins and external packages load, and hardened the boundary between core and userland.

Entry-point plugin discovery

7f5ba17 · 2026-08-14 · featupstream
What it is
Plugins can now register themselves through Python package entry points, not just by living in a directory. The loader discovers installed distributions advertising the spruce_grove.plugins group at import time.
What it does
Lets plugin authors ship their work as a normal pip-installable package; the moment the package lands in the environment, it appears in spruce-grove alongside user-dir plugins without any config editing.
Why it matters
It turns a fork-and-pray ecosystem into a real distribution model. Upstream used this to extract the built-in plugin suite into code-puppy-core-plugins on PyPI — and it means any team can ship an internal plugin bundle the same way.

Installed core-plugin version surfaced at startup

0dd7f79 · 2026-08-15 · featupstream
What it is
The CLI now prints the version of the installed code-puppy-core-plugins package on startup, alongside the app version.
What it does
Shows two independent numbers in the startup banner: the app version and the version of the companion plugins package, since they rev separately after the plugin-extraction refactor.
Why it matters
Eliminates the whole class of "why does that plugin behave differently for you" confusion. When the core repo and the plugin package drift, the drift is now visible in the first line of output instead of manifesting as a phantom bug.

Project-tier plugin trust gate hardened

beeab61 · 2026-08-10 · fixgrove
What it is
When spruce-grove is launched from a directory containing its own .spruce_grove/plugins, those plugins now load only after explicit trust approval — and running from ~ no longer accidentally treats your personal plugins as untrusted project code.
What it does
Adds a guard that returns None from get_project_plugins_directory() when the resolved path equals the user plugins dir, so the trust-gate applies only to actual repo-bundled code, never to your own home-profile plugins.
Why it matters
Closes a security hole where checking out an arbitrary repo and running spruce-grove in it would auto-load that repo's plugins without consent. Malicious repos can't inject behavior just by containing a plugins directory.

Reliability & Durability 4 headliners 1 grove-grown · 3 upstream-synced

Long-running agentic jobs used to face the entire Unix gauntlet: crashes, suspend/resume, network blips. This cycle made persistence a first-class concern instead of an afterthought.

Pickle replaced with versioned JSON envelopes

30edbc8 · 2026-08-15 · featupstream
What it is
Session and state persistence moved off pickle (Python-specific, version-fragile, unsafe to deserialize) and onto a versioned JSON envelope format with explicit schema migration.
What it does
Every persisted record now carries its own format_version and deserializes through a whole-tree migrator that validates on read and can roll forward old formats without breaking.
Why it matters
Pickles from an old spruce-grove version routinely crashed new versions in place. Versioned JSON survives upgrades, is human-inspectable, can be diffed, and removes an entire class of RCE risk from tampered state files.

Self-healing session-format sweep

1659081 · 2026-08-16 · fixupstream
What it is
A migration pass that scans all saved sessions at startup and upgrades any in an old format, instead of failing on the first stale file.
What it does
Runs a quiet sweep at boot; when it finds a legacy session it rewrites it to the current envelope format in place and continues, with per-file errors logged to a transient channel instead of spamming the console.
Why it matters
Previously a single ancient session file could brick startup until someone deleted it by hand. Now the system absorbs its own history, and the failure-degenerate case (corrupted format) is contained to one log line.

Goal resume by stable UUID

90fde59 · 2026-07-22 · featupstream
What it is
Interrupted long-running goals can now be resumed by a durable UUID instead of whatever ephemeral session handle they happened to have.
What it does
Every goal gets a stable identifier written into the durable store on creation; killing the process mid-goal and restarting lets you reference that UUID and pick up where the DAG left off, toolcalls-as-checkpoints.
Why it matters
Before this, a laptop sleep or a core dump meant restarting a multi-hour orchestration from scratch. UUID-resume turns goal execution into something closer to workflow engines like Temporal — while staying in-process.

Self-healing auto-updates

721ce25 · 2026-09-15 · featgrove
What it is
The end of the update button. On every startup the CLI compares itself against PyPI and, when a newer release exists, upgrades its on-disk install in place — no human, no nag, no maintenance window.
What it does
A startup daemon thread fetches the latest version (never blocking the session), reports what it found, and runs uv tool upgrade when behind. The running session keeps its warm, consistent code; the next launch boots the new release and one log line narrates the handoff.
Why it matters
Tools that wait for a keeper to update them on someone else's schedule go stale and take their owners with them. The grove verifies against the world, acts, reports in plain words — and can always be told to wait (NO_AUTO_UPDATE). Living and breathing beats installed and monitored.

Agents & Orchestration 3 headliners 3 upstream-synced

The core promise of spruce-grove is that delegation is cheap and safe. These changes made the recursion bounded, the failures recoverable, and the prompts identity-stable.

Bounded sub-agent recursion depth

350c5c66 · 2026-07-21 · featupstream
What it is
A hard cap on how deeply sub-agents can delegate to other sub-agents, enforced at invocation time.
What it does
Tracks agent invocation depth per session and refuses to start another nested level once the cap is reached, emitting a clear error instead of spinning into infinite recursion.
Why it matters
Nested delegation is powerful but has a catastrophic failure mode: an agent hallucinating its own name as a delegate target and invoking itself forever, burning tokens until rate-limit. The cap makes the failure immediate and legible.

Dead-model fallback on pinned sub-agents

12c5c3c · 2026-08-11 · fixupstream
What it is
If an invoked sub-agent has a specific model pinned and that model is currently dead or unavailable, the invocation now falls back to a working model instead of hard-failing.
What it does
Catches model-resolution errors in the delegation path, logs a scoped warning (deduplicated per conversation, not per process), and retries with the next available provider for that agent's tier.
Why it matters
Model catalogs go stale. A marketing-model name gets deprecated and suddenly a whole orchestration tree dies because a leaf agent can't spawn. Fallback keeps the workflow alive with degraded capability rather than dead.

Sub-agent identity/depth prompt injection

b519df9 · 2026-07-23 · featupstream
What it is
Every sub-agent invocation now prepends an explicit system-context block describing the agent's own name and how deep in the delegation stack it is.
What it does
Frames the delegation-chain position for the model: you are QA-Kitten, 2 levels deep, spawned by Pack Leader. Models answer differently and more conservatively when they know their own place in the tree.
Why it matters
Anonymously-nested models exhibit hallucinated authority: a deep-nested agent starts emitting "let me delegate that further" because it can't tell it isn't the orchestrator. Identity prompts measurably reduce unnecessary fan-out.

Models & Providers 3 headliners 3 upstream-synced

New frontier models keep shipping with weird knobs. This cycle handled three of them: per-tool guardrails for the sharpest new model, a generalized request-param surface, and OAuth for baselines that needed it.

Per-tool guardrails for GPT-5.6 family

5ce5975 · 2026-07-21 · featupstream
What it is
Models in the GPT-5.6 family can now be gated per-tool: some tools allowed, some blocked, based on a per-model safety profile.
What it does
Reads a model-family capability map at agent setup; a GPT-5.6-backed agent gets its available tool list filtered so, for example, file-writing tools may be disabled while read-only tools remain.
Why it matters
The newest models are the least predictable. Shipping them with a full toolbox means inheriting every regression immediately. Per-tool gating lets you adopt frontier models for read-heavy agents first, and only widen the tool scope as trust grows.

User-defined custom request params per model

d08b6c9 · 2026-08-01 · featupstream
What it is
A pass-through config surface letting you attach arbitrary key/value params to any model's request payload without forking the provider.
What it does
Reads extra params from the model config (e.g. "request_params": {"reasoning_effort": "high"}) and merges them into the HTTP payload that provider actually receives.
Why it matters
Every new model ships with some bespoke API knob that the codebase doesn't know about yet — new thinking modes, new safety tiers, whatever. This is the escape hatch that means you never have to wait for a code release to enable one.

Meta Muse OAuth provider

c0e26247 · 2026-08-05 · featupstream
What it is
Full OAuth support for Meta's Muse model family, with token lifecycle handled the same way as the existing Claude and Codex OAuth paths.
What it does
Implements the Muse auth flow (browser-redirect + token refresh + encrypted storage) and exposes Muse models in the model factory under the muse: prefix once authenticated.
Why it matters
Muse is a meaningfully different price/latency profile from the incumbent providers; without this, using it required manual bearer-token wrangling. Now it's a one-time login flow, like everything else.

Observability & Telemetry 3 headliners 3 upstream-synced (4 commits)

An agent that can't report its own token usage is a black box. This cycle made the reporting granular, lossless across providers, and end-to-end timestamped.

Per-run token usage and latency

ccc81e7 · 2026-07-24 · featupstream
What it is
Every agent run now reports granular token consumption and wall-clock latency at turn-end.
What it does
The turn-completion telemetry includes prompt/completion token counts (broken out by cache-read vs cache-write where the provider exposes it) and the millisecond duration from first request to final stream close.
Why it matters
Cost debugging used to require correlating provider dashboards to session logs. Now the ground-truth economics are in the same place as the conversation, making "why did that four-step task cost 90k tokens" immediately answerable.

Sub-agent usage reporting & cache-metric reliability

d00ac86 + 827f8a1 · 2026-08-15/16 · fixupstream
What it is
Sub-agent invocations now reliably surface their own token-usage back into the parent session's telemetry, and the triad of cache-write-cost hallucinations, provider-reported drift, and reporting regressions were closed in a single sweep.
What it does
Plumbs sub-agent token counters through the delegation finish protocol so the parent's usage pane reflects the leaf work, and normalizes providers' differing cost-reporting semantics so the display never invents numbers.
Why it matters
Before this, a Pack Leader spawning four sub-agents would report only its own (small) token cost, hiding the real total. The observability was silently lying, and any cost-allocation decision made from it was wrong.

timestamp_heartbeat plugin

5ae287b · 2026-07-23 · featupstream
What it is
A plugin that stamps a __SYS_TIMESTAMP__ field into tool results every N calls, so every result in a session has a coarse but consistent clock.
What it does
Hooks the tool-callback chain; on every k-th invocation it appends a timestamp block to the result payload, giving downstream log parsers and the model itself a time anchor.
Why it matters
Long sessions drift. Models lose track of wall-clock time in extended context, leading to subtly-wrong time-sensitive reasoning ("is that before or after my context window started"). A heartbeat counter is cheap and durable.

New Since Last Curation auto-detected 11 grove-grown · 0 upstream-synced

Feature commits detected by the pipeline that haven't been curated into deep-dives yet. These render straight from the changelog so the page never goes stale between curation passes.

self-host the field guide's fonts; refresh the release observatory

938116f · 2026-09-25 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit 938116f in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

an About page, and fix the nav's dead repo link

232d32c · 2026-09-25 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit 232d32c in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

grove-owned braille spinner, seated as the default

c4a2f7f · 2026-09-23 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit c4a2f7f in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

/console panel to see and tend live sessions

f6fb2a9 · 2026-09-23 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit f6fb2a9 in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

live-session scanner + `--console` headless read

76233b6 · 2026-09-23 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit 76233b6 in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

braille boot mark, and Wiggledom as the fourth ethos pillar

dd8035e · 2026-09-23 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit dd8035e in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

route default vision to syn:large:text (cheapest multimodal)

67bb580 · 2026-09-21 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit 67bb580 in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

refresh lineup for 2026-09 subscription model changes

0292fdf · 2026-09-21 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit 0292fdf in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

Mockingbird /rec plugin -- mic -> whisper -> review -> send-as-prompt (build-log 27)

9dabbc2 · 2026-09-10 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit 9dabbc2 in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

merge-discipline + privacy pre-commit guard (sg-5al.1)

e459cc3 · 2026-09-10 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit e459cc3 in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

grove bootloader polish + phases dashboard + memo guardrails

22586b3 · 2026-09-10 · featgrove
What it is
A feature that landed since the last curation pass.
What it does
See commit 22586b3 in the repo for the implementation diff.
Why it matters
Auto-detected — a curated narrative will be added on the next observatory curation pass.

Minor Updates & Bug Fixes everything else

The steady hum of fixing things. Grouped by topic for scanability — a selection of the more notable small changes, not all 300.

Minor Enhancements

feat + refactor + docs + chore highlights
  • 0733e8d· 09-24 · one build, one source of truth — and stop tracking the outputgrove
  • 26f8b76· 09-24 · the Apache-2.0 rationale, publicly, and two more transcripts untrackedgrove
  • 0b299d3· 09-24 · sync Leather Apron Club slide count (47 -> 51)grove
  • 2ac1013· 09-23 · step 2 of the harness exit is complete, and say whygrove
  • a5e2bb0· 09-23 · decision layer plan (System One-style bounded decisions, local-first)grove
  • fb6dbe1· 09-23 · those session dumps are iTerm2 AutoLog, not grove outputgrove
  • f34397b· 09-22 · record the ToolContext vocabulary landing + recompute the censusgrove
  • c3e7a05· 09-22 · session handoff addendum — synthetic.new lineup refresh (2026-09-21)grove
  • 28da0c2· 09-15 · session handoff — the launch document for the next sessiongrove
  • d40fec8· 09-15 · root every asset into the self-healing loop — per-persona updatesgrove
  • c1ca905· 09-15 · license analysis — Apache-2.0 vs MIT for the grove (bad-actor playbook, the law behind attribution, NOTICE strategy, standing-your-ground runbook); ground truth: MIT lineage, no NOTICE files, club site unlicensedgrove
  • 6399409· 09-14 · mark the archived leather-apron-club deck copy stale — canonical deck lives in the code_puppy checkout (40 slides, Sept 18 council)grove
  • 566c6af· 09-11 · DOMAIN-LAUNCH executed -- DNS, verification, root flip done; cert pendinggrove
  • de09604· 09-11 · progress board synced to build-log 32 -- L5 95%, 16/19 beads, launch queue reorderedgrove
  • 54cdf13· 09-10 · reroute 4 grandfathered legacy-namespace imports to spruce_grovegrove
  • 28ed62b· 09-10 · verified live domain pricing -- sprucegrove.io $28.12 first year at Porkbun, .ai $82.70grove
  • 8a6274e· 09-10 · progress.html -- Then/Now/Next roadmap board (spec vs shipped vs live queue) + index cardgrove
  • 5277c1a· 09-10 · build-log 29 -- voice loop dogfooded live, desktop dictation path (4 beads), PyPI claim runbookgrove

Bug Fixes

fix bucket highlights
  • ae21280· 09-25 · repair the /releases layout and every page that clipped on narrow screensgrove
  • 10472d3· 09-25 · CI regeneration must not publish a zeroed inventorygrove
  • 11c512d· 09-25 · hub footer labels named repos that don't existgrove
  • e7ca009· 09-25 · make every hub-linked page mobile-clean and brand-consistentgrove
  • 7d469f6· 09-24 · put the site's nav mark under the sync script toogrove
  • 60be611· 09-24 · sweep the published surfaces to zero, and guard themgrove
  • de36660· 09-24 · redeploy when the build script changesgrove
  • c426fe6· 09-24 · normalize the build output path before guarding itgrove
  • 4953a46· 09-24 · the master icon was the stale one; sync it and de-name the public copygrove
  • 7478ac0· 09-24 · /rec rejected real speech with pauses, and hid its own keysgrove
  • 234de8c· 09-24 · the generators were still publishing namesgrove
  • 5cebf11· 09-24 · stop the "thank you, thank you, thank you" dictation buggrove
  • 64b630c· 09-24 · finish the pivot on the surfaces it never reachedgrove
  • d84a0dc· 09-23 · give every published page an apple-touch-icon, correctly rootedgrove
  • 4533b2d· 09-23 · never raise when hashing rich tool payloadsgrove
  • 918c18b· 09-23 · name the stale-install cause at the lazy tool seamgrove
  • fd98a28· 09-23 · defer self-update actuation to exit so it can't break a sessiongrove
  • 8d74d2d· 09-23 · one broken tool must never kill an agent rungrove