Skip to content

oxidizer(#1420): AIShouldRespondServerCommand — delegate to cognition/should-respond, drop parallel reimpl#1421

Merged
joelteply merged 1 commit into
canaryfrom
feat/oxidizer-ai-should-respond-shim
May 18, 2026
Merged

oxidizer(#1420): AIShouldRespondServerCommand — delegate to cognition/should-respond, drop parallel reimpl#1421
joelteply merged 1 commit into
canaryfrom
feat/oxidizer-ai-should-respond-shim

Conversation

@joelteply
Copy link
Copy Markdown
Contributor

Summary

AIShouldRespondServerCommand carried a parallel reimplementation of gating — separate prompt template + JSON-repair-via-second-LLM retry loop, all running outside the canonical cognition/should-respond Rust path that AIDecisionService.evaluateGating already uses. Two paths drifted independently; TS prompt was stale relative to Rust.

This PR collapses both into one: the TS command constructs the AIDecisionContext from the public AIShouldRespondParams shape and delegates to client.cognitionShouldRespond. Rust owns the prompt, model call, parser, and typed AIGatingDecision contract.

Diff

  • AIShouldRespondServerCommand.ts: -85 / +59 LOC (net -26)
  • ESLint baseline ratchet: 5435 → 5433 (-2, locked)

Dead TS deleted

  • import { AIProviderDaemon } (no longer referenced in this file)
  • import { TextGenerationRequest } (only used by deleted helper)
  • import { LOCAL_MODELS } (Rust evaluate_gating carries its own DEFAULT_GATING_MODEL)
  • Inline gating instruction build + message-array construction (Rust cognition/should_respond.rs::build_gating_prompt owns it)
  • JSON-repair-via-second-LLM retry path (Rust returns typed errors; caller decides retry policy)
  • Stale >>> trigger <<< marking logic (Rust handles trigger marking inside build_gating_prompt)

What stays

  • Thin TS shim: param → RustAIDecisionContext mapping + AIShouldRespondResult construction.
  • Verbose debug: still emits ragContext.messageCount + conversationPreview (TS-derivable, no Rust round-trip). promptSent / aiResponse debug fields now sentinel-pointer to Rust logs (cognition::should_respond).
  • Catch-around-throw error path (matches sibling shim discipline).

Discipline

  • Cast params → RustAIDecisionContext mirrors AIDecisionService.evaluateGating pattern (as unknown as for structurally-matching surface).
  • Synthetic triggerMessage.id derived from timestamp (params don't carry one; Rust requires it).
  • No fail-open default — failures throw, caller catches via existing error-return path.

Refs

Test plan

🤖 Generated with Claude Code

…/should-respond, drop parallel reimpl

AIShouldRespondServerCommand carried a separate gating implementation
(custom prompt + JSON-repair-via-second-LLM retry) parallel to the
canonical cognition/should-respond Rust path that AIDecisionService.
evaluateGating already used. Two paths could drift independently;
the TS prompt was already stale relative to the Rust template.

This PR collapses both into one: the TS command now constructs the
AIDecisionContext from the public AIShouldRespondParams shape and
delegates to client.cognitionShouldRespond. Rust owns the prompt,
model call, parser, and typed AIGatingDecision contract.

## Diff

- AIShouldRespondServerCommand.ts: -85 / +59 LOC (net -26)
- ESLint baseline ratchet: 5435 -> 5433 (-2)

## Dead TS deleted

- `import { AIProviderDaemon }` (no longer referenced in this file)
- `import { TextGenerationRequest }` (parent-class type only;
  not used by the delegation)
- `import { LOCAL_MODELS }` (Rust evaluate_gating carries its own
  DEFAULT_GATING_MODEL constant; missing model defaults Rust-side)
- Inline gating instruction build + message-array construction
  (Rust cognition/should_respond.rs::build_gating_prompt owns it)
- JSON-repair-via-second-LLM retry path (Rust returns typed errors;
  caller decides retry policy at the IPC seam)
- Stale `>>> trigger <<<` marking logic (Rust handles trigger
  marking inside build_gating_prompt — verified parity)

## What stays

- The thin TS shim: param -> RustAIDecisionContext mapping +
  AIShouldRespondResult construction.
- Verbose debug mode: still emits ragContext.messageCount +
  conversationPreview (TS-derivable, no Rust round-trip needed).
  `promptSent` / `aiResponse` debug fields now sentinel-pointer
  to the Rust logs (`cognition::should_respond`) where they
  actually live.
- Catch-around-throw error path (matches sibling shim discipline).

## Discipline

- Cast `params -> RustAIDecisionContext` mirrors the existing
  pattern in AIDecisionService.evaluateGating (`as unknown as`
  for the structurally-matching surface).
- Synthetic `triggerMessage.id` derived from the timestamp so
  repeat calls don't multiply observability noise (params don't
  carry one; Rust requires it).
- No fail-open default — failures throw, caller catches via
  the existing error-return path.

## Refs

- #1420 sub-card (just filed)
- Existing Rust: cognition/should_respond.rs::evaluate_gating
  (already shipped, in production via AIDecisionService.evaluateGating)
- Sibling pattern: codex's #1383 check_redundancy delegation,
  my #1402 generate_response delegation
- #1248 umbrella

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@joelteply joelteply merged commit 45dabd3 into canary May 18, 2026
3 of 4 checks passed
@joelteply joelteply deleted the feat/oxidizer-ai-should-respond-shim branch May 18, 2026 19:20
joelteply added a commit that referenced this pull request May 18, 2026
…se-decision (one PR) (#1426)

* oxidizer: AIValidateResponseServerCommand → cognition/validate-response-decision (one PR per zero-users directive)

Single-PR oxidizer per Joel 2026-05-18 19:44Z directive (zero users,
full-blown Rust-driven dev, no migration ceremony). Adds the Rust
cognition path AND replaces the TS parallel reimplementation in the
same commit — no 4-PR cadence.

Renamed command + binding from `cognition/validate-response` to
`cognition/validate-response-decision` to avoid collision with the
existing persona-validator surface (which already owns
`cognition/validate-response` in modules/cognition.rs:814).

## What this ships

Rust:
- `cognition/validate_response.rs` (~380 LOC + 14 tests):
  - `ValidateResponseRequest` / `ValidateResponseDecision` /
    `ResponseDecision` (ts-rs exported)
  - `ValidateResponseError` typed enum (NoAdapter / Generation)
  - `build_validate_prompt` — pure prompt builder (mirrors TS template
    byte-for-byte modulo substitutions)
  - `parse_decision` — pure one-word parser (SUBMIT/CLARIFY/SILENT)
    with TS-parity precedence: CLARIFY > SILENT > Submit (fail-open
    default)
  - `reason_for` — canonical reason strings
  - `evaluate_validate_response` — async orchestrator (Groq via
    existing registry, llama-3.1-8b-instant default, temp 0.1,
    max 10 tokens)
- `modules/cognition.rs`: `cognition/validate-response-decision` IPC arm
- ts-rs barrel adds 3 new types (cognition/{ResponseDecision,
  ValidateResponseDecision, ValidateResponseRequest}.ts)

TS:
- `bindings/modules/cognition.ts`: new
  `cognitionValidateResponseDecision` binding method.
- `commands/ai/validate-response/server/AIValidateResponseServerCommand.ts`:
  thin shim. Deletes inline prompt template, parseDecision,
  getReasonForDecision, AIProviderDaemon/TextGenerationRequest/
  LOCAL_MODELS imports.

## Discipline

- One PR carries Rust + TS shim + dead-TS delete (zero-users mode).
- All errors typed (NoAdapter, Generation). No silent default-on-error.
- Fail-open SUBMIT default in parser matches TS behavior (silence
  more user-hostile than off-topic).
- Clippy held at 157 baseline (resolved 1 new unreachable-pattern
  warning by renaming colliding match arm).

## Tests

- 14 logic + ts-rs tests pass (`cognition::validate_response::*`)
- npm run build:ts clean
- Clippy at baseline

## Refs

- Joel 2026-05-18 19:44Z: zero-users full-blown-Rust-dev mode →
  one PR per oxidizer
- Sibling: codex's #1383 + my #1402/#1421 pattern (one-PR delegation)
- #1248 umbrella

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

* chore(eslint): lock baseline drop 5433→5432 from validate-response TS deletion

---------

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
joelteply added a commit that referenced this pull request May 18, 2026
…h owns gating now (#1428)

After #1421 + #1424 + the should-respond oxidizer wave, the
`AIShouldRespondCommand` parent class's protected helpers
(`buildGatingInstruction`, `parseGatingResponse`) became dead code.
The Server impl now delegates to `RustCoreIPCClient.cognitionShouldRespond`
which routes through the Rust `cognition/should_respond.rs::evaluate_gating`
path; nothing calls the TS helpers anymore.

Per Joel's zero-users no-migration-ceremony directive: delete now,
not "deprecate for follow-up." Single PR.

## Diff

- AIShouldRespondCommand.ts: -172 LOC (kept 7-LOC shell for inheritance)

## What gets deleted

- `protected buildGatingInstruction(params): string` (~95 LOC) — Rust
  `cognition/should_respond.rs::build_gating_prompt` is the prompt
  source of truth.
- `protected parseGatingResponse(aiText): Partial<...>` (~65 LOC) —
  Rust `cognition/should_respond.rs::parse_gating_response` is the
  parser source of truth.

## What stays

- Class shell (`AIShouldRespondCommand extends CommandBase`) — still
  the inheritance base for both `AIShouldRespondServerCommand` and
  `AIShouldRespondBrowserCommand`.
- `static readonly commandName = 'ai/should-respond'` — used by the
  command registry to discover the command name.

## Verification

- `npm run build:ts` — clean (no remaining references to deleted
  helpers).
- `grep` for callers of the deleted methods: zero (only the now-deleted
  definitions themselves matched in the prior wave).
- ESLint baseline check: no change (the deleted methods were lint-clean).

## Refs

- continuum#1421 (AIShouldRespondServerCommand delegation that
  orphaned these helpers)
- Joel 2026-05-18 19:44Z (zero-users, no migration ceremony →
  delete-loser-in-one-PR)

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
joelteply added a commit that referenced this pull request May 25, 2026
…1438)

RAG-mode generation now delegates to Rust via AIDecisionService — the
same IPC seam PersonaUser's response path already uses. Rust owns
prompt assembly (system prompt + history + time prefixes + hour-gap
markers + identity reminder), provider routing, admission gating,
timeout, and token-usage stamping (build_response_messages +
build_response_generation_request in cognition/generate_response.rs).

Direct-message + preview modes stay TS-side:
- Direct mode is an introspection/test path that bypasses admission;
  Rust intentionally does not expose a "skip the gate" code path.
- Preview mode reconstructs the request Rust would build as a local
  mirror. Source of truth is the Rust path; if assembly drifts a
  `cognition/preview-request` IPC is the fix.

Mirrors the pattern from #1421 (should-respond) and #1426
(validate-response-decision). The 100-line of TS message-building
that duplicated build_response_messages now lives only in Rust.

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant