Skip to content

feat(omp): add attended-primary compact adviser adapter - #158

Open
dnth wants to merge 25 commits into
mainfrom
fm/fm-omp-compact-adviser-adapter
Open

dnth wants to merge 25 commits into
mainfrom
fm/fm-omp-compact-adviser-adapter

Conversation

@dnth

@dnth dnth commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Intent

Build the attended-primary hint-only compact-adviser adapter as Firstmate-local extension code (not a separate repo or fork). It advises /compact and never auto-compacts. Inert by default and never active for spawned agents: workers are excluded by design - the entrypoint rejects explicit spawned-worker identity (FM_OMP_HARNESS=omp and the OMP task markers), rejects a linked-worktree or secondmate module root before consulting FM_OVERRIDE, and fm-spawn clears FM_OVERRIDE at ordinary worker launch as defense in depth. Judge contract is a TypeSafe Choice call reusing upstream judge semantics and privacy budgets pinned to compact-adviser commit b2a27b59ce86af4dc8fb5141e169bfbed1e68cee. Consent gates: session gate (attended-primary only, explicit opt-in config/compact-adviser.json) and data gate (TypeSafe payload budget, 64-message cap) - no TypeSafe call without the consent config present, re-checked at each evaluation boundary. Hint surface is person-only via ctx.ui.setWidget/setStatus; sendMessage is FORBIDDEN for hints because every deliverAs variant enters model context. Sensitive tool-call provenance is derived from the whole active branch while transmitted content stays capped at 64 messages. OMP API claims re-verified against the installed 18.2.6 runtime source. Changes confined to the adapter, its tests, and minimal registration/config seams. Firstmate-Validation-Generation: 5be8db0ca8acd83768c0a0f857927ba9

What Changed

  • Added a Firstmate-local OMP compact-adviser extension for attended primaries with explicit opt-in consent, bounded TypeSafe context, and person-only widget/status hints; it never auto-compacts.
  • Added worker, linked-worktree, and secondmate exclusion gates plus launch-time clearing of inherited FM_*_OVERRIDE variables and trusted extension-closure registration.
  • Added focused adapter and secondmate shell tests and documented the runtime API verification, configuration, privacy bounds, and worker-isolation behavior.

Risk Assessment

✅ Low: The adapter and its supporting seams satisfy the stated attended-primary, hint-only, consent, privacy-budget, worker-exclusion, and runtime-verification requirements, with no additional source-verifiable defect found.

Testing

Ran the focused compact-adviser harness covering gates, privacy, consent revocation, message cap, summary preservation, and hint-only side effects; then drove real OMP 18.2.6 no-consent, opt-in-without-key, and spawned-worker-marker sessions. No source or transient worktree artifacts remain. The real qualifying TypeSafe hint scenario could not be exercised without credentials or a supported deterministic judge injection path.

  • Live validation: ⚠️ inconclusive - 3 of 5 scenarios driven live against the product
Scenario Result Live Evidence
Adapter gates, hint-only side effects, consent revocation, privacy budgets, 64-message cap, summary preservation, and pinned judge semantics behave correctly. ⏸️ untested no The focused harness uses a mocked ExtensionAPI and judge; a real OMP session cannot inject the deterministic judge needed to observe the hint path.
Load the extension in real OMP 18.2.6 with no opt-in config and complete a primary turn; the product remains usable without adviser output. ✅ pass live ~/.no-mistakes/evidence/01M38ECKY4711ZAE5R3V6BFQ7K/omp-inert-probe.log
Load real OMP with explicit opt-in but no TypeSafe credential; the turn completes without an adviser hint or compaction side effect. ✅ pass live ~/.no-mistakes/evidence/01M38ECKY4711ZAE5R3V6BFQ7K/omp-optin-no-key.log
Load real OMP with FM_OMP_HARNESS=omp worker identity and opt-in config; the worker turn completes without adviser activation. ✅ pass live ~/.no-mistakes/evidence/01M38ECKY4711ZAE5R3V6BFQ7K/omp-worker-marker.log
With explicit opt-in and a deterministic qualifying judge, a settled turn produces a person-only /compact widget hint without sendMessage or compact(). ⏸️ untested no No supported real-OMP TypeSafe judge stub injection path or credential was available.
Evidence: Real OMP no-consent probe

Working... READY, captain.

Working...
READY, captain.
Evidence: Real OMP opt-in and worker-marker probes

Working... READY, captain

Working...
READY, captain
Evidence: Real OMP worker-marker probe

Working... READY, captain

Working...
READY, captain
- Outcome: ⚠️ 1 warning across 1 run (3m31s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ .omp/extensions/lib/compact-adviser/config.ts:46 - parseSavedApiKey() is introduced but has no callers anywhere in the adapter or its command/config paths. It adds an unused validation API and duplicate key-validation surface without satisfying any stated requirement; remove this component unless future saved-key configuration is explicitly intended.

🔧 Fix applied.
✅ Re-checked - no issues remain.

⚠️ **Test** - 1 warning
  • ⚠️ live validation verdict: inconclusive (3 of 5 scenarios were driven live against the product); untested: Adapter gates, hint-only side effects, consent revocation, privacy budgets, 64-message cap, summary preservation, and pinned judge semantics behave correctly., With explicit opt-in and a deterministic qualifying judge, a settled turn produces a person-only /compact widget hint without sendMessage or compact().
  • Live validation: ⚠️ inconclusive - 3 of 5 scenarios driven live against the product
Scenario Result Live Evidence
Adapter gates, hint-only side effects, consent revocation, privacy budgets, 64-message cap, summary preservation, and pinned judge semantics behave correctly. ⏸️ untested no The focused harness uses a mocked ExtensionAPI and judge; a real OMP session cannot inject the deterministic judge needed to observe the hint path.
Load the extension in real OMP 18.2.6 with no opt-in config and complete a primary turn; the product remains usable without adviser output. ✅ pass live ~/.no-mistakes/evidence/01M38ECKY4711ZAE5R3V6BFQ7K/omp-inert-probe.log
Load real OMP with explicit opt-in but no TypeSafe credential; the turn completes without an adviser hint or compaction side effect. ✅ pass live ~/.no-mistakes/evidence/01M38ECKY4711ZAE5R3V6BFQ7K/omp-optin-no-key.log
Load real OMP with FM_OMP_HARNESS=omp worker identity and opt-in config; the worker turn completes without adviser activation. ✅ pass live ~/.no-mistakes/evidence/01M38ECKY4711ZAE5R3V6BFQ7K/omp-worker-marker.log
With explicit opt-in and a deterministic qualifying judge, a settled turn produces a person-only /compact widget hint without sendMessage or compact(). ⏸️ untested no No supported real-OMP TypeSafe judge stub injection path or credential was available.
  • bash tests/fm-omp-compact-adviser.test.sh
  • omp --no-session --no-tools --no-skills --no-rules --no-extensions -e .omp/extensions/fm-compact-adviser-omp.ts -p 'respond with READY'
  • Real OMP opt-in probe with temporary consent config and no TypeSafe credential
  • Real OMP worker-marker probe with FM_OMP_HARNESS=omp
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

dnth added 17 commits September 23, 2026 21:24
Ports the upstream compact-adviser judge contract (pinned commit
b2a27b59ce86af4dc8fb5141e169bfbed1e68cee) to OMP as a Firstmate-local
extension. Hint-only: advises /compact via ctx.ui.setWidget, never
auto-compacts, never injects into model context.

Gate chain: COMPACT_ADVISER_DISABLE, Firstmate primary scope (spawned
workers excluded by design since ambient discovery loads project
extensions everywhere), and an explicit opt-in record at
config/compact-adviser.json.

OMP API claims re-verified against @oh-my-pi/pi-coding-agent 18.2.6
source (runtime moved from the report's 18.1.21); verification recorded
in the eval report addendum.
… falling back to durable inbox delivery when the endpoint is missing/unverifiable, preserving normal steering safety. `bash -n` and `git diff --check` pass
…directly into the remote durable inbox before endpoint probing, and added an idempotent direct transport retry from the reconciler for markerless routes. `bash -n` and `git diff --check` pass; the focused lifecycle test still reproduces the existing `dead markerless reconciliation notify failed` case, so further investigation is required
…durable remote inbox before endpoint-based delivery, preserving recovery when the endpoint is gone. `bash -n` and `git diff --check` pass; the focused lifecycle test still reproduces the dead markerless failure, so the CI issue is not fully resolved
…770ab, a36b760, 7c95b42) from bin/fm-remote-secondmate-control.sh and bin/fm-secondmate-reconcile.sh. Compact-adviser changes remain untouched; git diff --cached --check passes. The outer executor must commit/re-push and retry CI
…ches

The remote OMP secondmate launch preflight refuses any tracked top-level
.omp/extensions/*.ts file not in the trusted closure. The compact-adviser
adapter's fm-compact-adviser-omp.ts entrypoint and its lib/compact-adviser
import closure were missing from that allowlist, so every remote OMP
secondmate launch on a branch carrying the adapter was refused.

Add the entrypoint and its exact eight-file local import closure to
omp_secondmate_extension_matches_trusted_closure, keeping the existing
byte-identity requirement against the primary's copies. A regression test
in fm-omp-secondmate.test.sh proves the closure launches when identical
and refuses when a file is modified or missing.
@dnth
dnth force-pushed the fm/fm-omp-compact-adviser-adapter branch from f5032aa to 8603589 Compare September 23, 2026 14:09
@dnth dnth changed the title feat(omp): add attended-primary compact adviser feat(omp): add attended-primary compact-adviser adapter Sep 23, 2026
@dnth dnth changed the title feat(omp): add attended-primary compact-adviser adapter feat(omp): add hint-only compact-adviser adapter for attended primary Sep 23, 2026
…t gaps

Astra review of 09c1f2c (PR #158):

- F1: reject spawned-worker identity (FM_OMP_HARNESS=omp and the OMP task
  markers) at the entrypoint, and reject a linked-worktree or secondmate
  module root before FM_*_OVERRIDE is consulted, so inherited primary
  overrides can no longer activate a worker's adviser. fm-spawn now also
  clears FM_*_OVERRIDE at ordinary worker launch as defense in depth.
- F3: scope fixtures install the real fm-gate-refuse-lib.sh and
  fm-primary-scope-lib.sh plus a real extension copy; the suite proves
  opted-in primary activation through the entrypoint first, then worker,
  secondmate, gate-agent, and inherited-override rejection through it.
- F4: tool-call provenance is derived from the whole active branch while
  transmitted content stays capped at 64 messages, so an in-window
  sensitive tool result whose call fell outside the window is still
  excluded; regression test covers the out-of-window call + in-window
  .env result.

F2 is not a defect per the accepted design (separate 8,000-byte user and
14,000-byte recent budgets under the 32,000-byte request cap).
@dnth dnth changed the title feat(omp): add hint-only compact-adviser adapter for attended primary feat(omp): add attended-primary compact adviser adapter Sep 24, 2026
…pdating the spawn profile test’s expected worker launch command to include the required cleared FM_*_OVERRIDE variables. The adapter-focused test passes and the change is whitespace-clean. The remaining pure-contract failure has no failure detail in the supplied CI log and appears unrelated to the adapter change
… and Kimi harness launch expectations to include the cleared FM_*_OVERRIDE environment assignments emitted by fm-spawn. Bash syntax and diff checks pass; Kimi runtime test is unavailable locally because Python 3.10 lacks tomllib
…de the FM_*_OVERRIDE clearing prefix introduced by this PR. `tests/fm-spawn-dispatch-profile.test.sh` now passes fully; `git diff --check` is clean
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