Skip to content

Providers phase 3a: open condition snapshot union, policy-driven selectors, ungated resolution - #403

Merged
Juliusolsson05 merged 1 commit into
mainfrom
refactor/providers-phase3-conditions
Jul 6, 2026
Merged

Juliusolsson05 merged 1 commit into
mainfrom
refactor/providers-phase3-conditions

Conversation

@Juliusolsson05

Copy link
Copy Markdown
Owner

Part of #394 (phase 3, slice a). Deliberately avoids the vendored conditions-core slice — no submodule churn.

  1. Open snapshot union: ProviderConditionSnapshot → generic {provider: AgentProviderKind; conditions; ts} (kinds are globally namespaced, so kind-keyed access was always provider-safe); conditionStateByKind<S>() is the sanctioned typed lookup. Per-provider specializations remain for the session event maps. Wire format unchanged.
  2. Policy-driven selectors: new conditionPolicy capability (attention set / action set / ordered label rules / picker kind, in providers/*/renderer/conditions/policy.ts); selectors.ts loses its hardcoded kind lists and provider === 'claude' branches — the exact deferred seam the design doc named. applyConditionSnapshot's fork becomes kind-keyed derivation.
  3. Ungated resolution: sessionManager.resolveCondition drops the claude-only gate; any agent kind routes to its session's resolver, absent resolvers truthfully return no-resolver.

Not in this slice (3b): structured actions, Codex resolver parity (codex-headless submodule work), pending*-mirror deletion.

Verified: tsc both projects, build, vitest 170/170 (incl. selectors.test.ts against the rewrite).

🤖 Generated with Claude Code

…selectors, ungated resolution

The conditions system was the last closed provider surface (#394
phase 3 / §5). Three changes, none touching the vendored
conditions-core slice (no submodule churn):

1. ProviderConditionSnapshot opens from the closed
   ClaudeConditionSnapshot | CodexConditionSnapshot union to the
   generic { provider: AgentProviderKind; conditions:
   Partial<Record<string, ProviderConditionRecord>>; ts } shape —
   mirroring conditions-core's ConditionSnapshot<P>, which was
   already generic. Condition kinds are globally namespaced
   (<provider>.<kind>), so kind-keyed access was always
   provider-safe; the union bought nothing except closure (a third
   provider couldn't TYPE a snapshot without editing the file). The
   per-provider specializations remain as the shapes the provider
   session event maps emit; the new conditionStateByKind<S>() helper
   is the one sanctioned typed lookup. Wire format unchanged.

2. workspace/conditions/selectors.ts becomes generic loops over a new
   conditionPolicy on RendererProviderCapabilities (attention set,
   action set, priority-ordered label rules, composer picker kind) —
   the exact deferred seam docs/design/conditions-system.md called
   out ("the migration is a deletion, not a re-derivation").
   Policies live in providers/<kind>/renderer/conditions/policy.ts.
   WHY data, not derivation from views' attention() fns: the sets and
   views deliberately disagree (AUQ is attention-worthy with NO view;
   compaction has a view but is excluded from the set).
   applyConditionSnapshot's two-provider fork becomes kind-keyed
   derivation for the same reason; the pending* mirrors stay (still
   documented for deletion; pendingCompaction + picker remain the
   only live consumers).

3. sessionManager.resolveCondition drops its claude-only gate. A
   provider that implements AgentSession.resolveCondition previously
   dead-ended in 'no-session' at the manager; now any agent kind
   routes through, and one WITHOUT a resolver (Codex today — its
   approvals answer via raw keystrokes) truthfully returns
   'no-resolver' from the existing capability check.

Also: TileLeaf's AUQ extraction and the debug module's two copies use
conditionStateByKind instead of snapshot-level provider narrowing;
the outlet's Partial→dense-Record erasure is the one sanctioned cast
(same role as eraseRegistry).

NOT in this slice (3b): structured actions replacing raw keystrokes,
Codex-side resolveConditionAction parity (a codex-headless submodule
change), and pending*-mirror deletion.

Verified: tsc clean on both projects, electron-vite build clean,
vitest 170/170 — including selectors.test.ts against the
policy-driven rewrite.

Part of #394.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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