Skip to content

fix: apply the omp audit — card before model, tools only when registered - #270

Merged
omartelo merged 1 commit into
mainfrom
fix/omp-audit
Aug 13, 2026
Merged

omartelo merged 1 commit into
mainfrom
fix/omp-audit

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

A quality pass over #257 and #258 turned up seven findings; this applies all of them. No feature changes — three are promises the code was making and not keeping.

The three that matter

The card is announced before the model is recorded (internal/spawn/spawn.go). Open wrote the model between AddSession and the session-opened event, so a failed write returned with a row and no card — the exact state the comment beside it forbids ("a session only the database knows about is one the user cannot reach to see what went wrong"), and a retry would have left a second row behind. The model is an override read back at spawn, so a failure there now costs the provider's default and nothing else. Pinned by a test that injects the write failure and asserts the card still went out.

HasTools no longer promises tools no install could register (internal/agentplugin/agentplugin.go). Crush and oh-my-pi get their tools from an MCP server written into their config by this binary's path, and both installs deliberately leave that registration out when the path cannot be resolved (crushrcBlock, ompMCPDocument) — while HasTools kept answering yes off the plugin version alone. A relayed message would then name a tool absent from that session's list. Fixed at the root, so Crush is covered too, not only the provider the audit reported. lichBinary moves onto the service for the same reason lookPath is injected: a test has to be able to say "this cannot be resolved".

The oh-my-pi profile branch is tested (internal/agentplugin/files_test.go). OMP_PROFILE beats PI_CODING_AGENT_DIR, and the resolver exists in two packages by the house pattern (the Claude Code pair does the same) — but only the resume copy was pinned. The install proves it now, through a real install into a redirected home, because getting the order backwards writes the extension where omp never scans and every report goes missing in silence.

The rest

  • flagValue replaces the trim-and-refuse-a-leading-dash guard that nameArgs and modelArgs each carried.
  • ompExtensionsDir names the "extensions" literal the install and the version read shared.
  • The CHANGELOG's oh-my-pi entry no longer states flatly that a card renames itself from the conversation title: the wiring is there and the plugin's own suite covers it, but no run has been observed generating one (no model credential on either machine that checked). It now says it takes the title once omp has written one.

Test plan

  • gofmt -l . clean, go vet ./... clean
  • go test ./internal/... green (1352, +8), -race on agentplugin, spawn and terminal
  • Cross-compile loop for linux/darwin/windows: go build + go vet clean on each
  • biome check, tsc --noEmit, vitest run (875) green
  • New coverage: the card survives a failed model write; registersServerAtInstall pinned as a list on both sides; HasTools false for an installed omp with no resolvable binary and unchanged for opencode, whose plugin defines its own tools; the install following OMP_PROFILE over the override

Seven findings from a quality pass over the session-model and oh-my-pi
changes. No behaviour anybody asked for changes; three of these are
promises the code was making and not keeping.

**The card is announced before the model is recorded.** `spawn.Open`
wrote the model between the row and the `session-opened` event, so a
failed write returned with a row nobody could see — exactly the state the
comment beside it forbids, and a retry would have added a second row. The
model is an override read back at spawn, so losing it costs the
provider's default and nothing else.

**`HasTools` no longer promises tools no install could register.** Crush
and oh-my-pi get theirs from an MCP server written into their config by
this binary's path, and both installs leave that registration out when
the path cannot be resolved — while `HasTools` kept answering yes off the
plugin version alone, sending a relayed message to name a tool absent
from that session's list. The condition now matches the install's
(`registersServerAtInstall`), which fixes Crush and oh-my-pi in one
place rather than the reported one. `lichBinary` moves onto the service
so a test can say "this binary cannot be resolved" — the same reason
`lookPath` is injected.

**The oh-my-pi profile branch is tested.** `OMP_PROFILE` beats
`PI_CODING_AGENT_DIR`, and that resolver exists twice by the house
pattern (as the Claude Code pair does); only the resume copy was pinned.
The install now proves it too, through a real install, because getting it
backwards writes the extension where omp never scans and every report
goes missing in silence.

Also: `flagValue` replaces the trim-and-refuse-a-dash guard written twice
in `nameArgs` and `modelArgs`; `ompExtensionsDir` names the directory
literal the install and the version read shared; and the CHANGELOG no
longer claims a card renames itself from the conversation title without
qualification — the wiring is there, but no run has been observed
generating one.
@omartelo
omartelo merged commit 32536f3 into main Aug 13, 2026
4 checks passed
@omartelo
omartelo deleted the fix/omp-audit branch August 13, 2026 15:58
@omartelo omartelo mentioned this pull request Aug 13, 2026
5 tasks done
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