Conversation
…active-patterns capability detection (Aaron 2026-05-05)
Aaron 2026-05-05 forwarded the Claude.ai review-of-review of the
algebra-capability system + same-tick "i think it's good if you
[file the backlog row]."
The original review identified three real gaps:
1. No IncrementalAuto dispatcher (the codebase has linear /
bilinear-three-term / D∘Q∘I rewrites but nothing picks based
on capability)
2. No checkBilinear law in LawRunner.fs (LinearLaw exists for
ILinearOperator; no equivalent for IBilinearOperator)
3. Sign-distribution as a third law -- op(0,b)=0 -- catches the
"bilinear with constant offset" failure mode that classical
bilinearity would miss
Plus the existential-quantification problem at the runtime
boundary: F#'s :? syntax can't ask "implements IBilinearOperator
for some unknown input types?" because existential quantification
isn't expressible. Three viable approaches: marker interface,
raw reflection, or active-patterns over reflection (the missed
idiomatic F# answer in the Claude.ai conversation).
Filed P2 not P1 because:
- Current Core plugins are small + author-verified by hand; no
observed correctness failure from the gap
- Capability-detection-mechanism choice is a real design decision
Aaron should weigh in on
- Composes with B-0189 (Q# Bayesian BP/EP) which would benefit
from a robust capability-dispatch infra when external plugins
arrive
Acceptance criteria: checkBilinear law in LawRunner.fs,
IncrementalAuto dispatcher in Incremental.fs, capability-detection
mechanism chosen + documented, at least one Bayesian-aggregate
plugin validated, composition rules documented.
Recommendation absent stronger preference: active-patterns +
reflection (no API surface change, idiomatic F#, easy to extend
per capability class). Marker-interface viable if explicit opt-in
preferred.
Out of scope: F# language extension for existential-quantification
syntax (real gap but separate work).
Lineage: original review (author unpreserved) -> Claude.ai shard
review-of-review (Aaron 2026-05-05 forwarded) -> Otto review-of-
review-of-review surfaced active-patterns idiom -> this row.
Filed in response to the never-be-idle floor failure: I'd been
"Clean."-ing for 20+ ticks after the substrate-engineering arc
wound down. Aaron caught it: "and why did you decide to do no
work? free time or just forgot?" The honest answer was "drift
into performative-no-op cadence" -- exactly the failure mode the
CLAUDE.md never-be-idle bullet calls out and the razor-cadence
mechanization (B-0192) is meant to catch.
Composes with B-0140 / B-0156 / B-0189.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a0338a1ba7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| 2. **No `checkBilinear` law.** `LawRunner.fs` has `LinearLaw` for `ILinearOperator` plugins but no equivalent law for `IBilinearOperator`. Without it, a plugin can claim bilinearity and silently violate the precondition that the three-term incremental formula `Δa ⋈ Δb + z⁻¹(I(a)) ⋈ Δb + Δa ⋈ z⁻¹(I(b))` requires. The result is wrong incremental-join output for retracting workloads. | ||
|
|
||
| 3. **Sign-distribution as a third law.** The retraction-correctness story needs `op(0, b) = 0` (i.e. `op(a, b) + op(-a, b) = 0`) in addition to bilinearity. A plugin author implementing a "bilinear" operator with a constant offset would pass classical bilinearity but fail retraction. The third law catches this. |
There was a problem hiding this comment.
Correct bilinearity claim about constant-offset operators
This row states that a constant-offset operator could “pass classical bilinearity” and only be caught by adding op(0,b)=0, but that is mathematically incorrect: op(0,b)=0 is implied by bilinearity and a constant offset already violates bilinearity itself. Keeping this claim in the acceptance rationale can mis-specify the future checkBilinear gate and lead implementers to design redundant or conceptually wrong tests instead of validating bilinearity directly.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR adds a new P2 backlog row for the plugin-algebra capability gap around automatic incremental dispatch, bilinear law coverage, and runtime capability detection, then regenerates the backlog index so the new row is discoverable from the canonical backlog surface.
Changes:
- Added backlog row B-0194 describing proposed work around
IncrementalAuto,checkBilinear, and reflection/active-pattern capability detection. - Linked the row to related backlog items and implementation surfaces in
src/Core/andsrc/Bayesian/. - Regenerated
docs/BACKLOG.mdto include the new P2 entry.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
docs/backlog/P2/B-0194-incremental-auto-dispatcher-bilinear-capability-detection-aaron-2026-05-05.md |
New backlog row defining the problem statement, acceptance criteria, cross-references, and lineage for the proposed capability-dispatch work. |
docs/BACKLOG.md |
Generated backlog index updated to include B-0194 under P2. |
| created: 2026-05-05 | ||
| last_updated: 2026-05-05 | ||
| depends_on: [] | ||
| composes_with: [B-0140, B-0156, B-0189] |
|
|
||
| 1. **No `IncrementalAuto` dispatcher.** The codebase has the three rewrite shapes (linear, bilinear three-term, D∘Q∘I fallback) but no single dispatcher that picks one based on the operator's declared capability. Plugin authors declare a capability via interface implementation; the consumer side has to know to dispatch differently. | ||
|
|
||
| 2. **No `checkBilinear` law.** `LawRunner.fs` has `LinearLaw` for `ILinearOperator` plugins but no equivalent law for `IBilinearOperator`. Without it, a plugin can claim bilinearity and silently violate the precondition that the three-term incremental formula `Δa ⋈ Δb + z⁻¹(I(a)) ⋈ Δb + Δa ⋈ z⁻¹(I(b))` requires. The result is wrong incremental-join output for retracting workloads. |
| 1. **`checkBilinear` law in `src/Core/LawRunner.fs`** that runs on `IBilinearOperator` plugins at `Circuit.Build()`. Verifies (a) bilinearity in both inputs (small synthetic ZSet test cases), (b) sign-distribution `op(0, b) = 0` and `op(a, 0) = 0`. Failure means the plugin doesn't satisfy the bilinearity contract; circuit-build fails loudly rather than producing wrong incremental output silently. | ||
|
|
||
| 2. **`IncrementalAuto` dispatcher** at an appropriate location (likely `src/Core/Incremental.fs` near the existing rewrite implementations). Reads operator capability via the chosen detection mechanism (marker / reflection / active-pattern -- TBD as part of this row), dispatches to: | ||
| - `Linear` rewrite for `ILinearOperator` | ||
| - Bilinear three-term rewrite for `IBilinearOperator` | ||
| - `D∘Q∘I` fallback for everything else |
|
|
||
| 2. **No `checkBilinear` law.** `LawRunner.fs` has `LinearLaw` for `ILinearOperator` plugins but no equivalent law for `IBilinearOperator`. Without it, a plugin can claim bilinearity and silently violate the precondition that the three-term incremental formula `Δa ⋈ Δb + z⁻¹(I(a)) ⋈ Δb + Δa ⋈ z⁻¹(I(b))` requires. The result is wrong incremental-join output for retracting workloads. | ||
|
|
||
| 3. **Sign-distribution as a third law.** The retraction-correctness story needs `op(0, b) = 0` (i.e. `op(a, b) + op(-a, b) = 0`) in addition to bilinearity. A plugin author implementing a "bilinear" operator with a constant offset would pass classical bilinearity but fail retraction. The third law catches this. |
| - **B-0189** (Q# Bayesian BP/EP runtime research) -- the consumer of capability-dispatched plugins. | ||
| - `src/Core/PluginApi.fs:103-132` -- the four capability interfaces this row's dispatcher consumes. | ||
| - `src/Core/Incremental.fs` -- the existing linear / bilinear / D∘Q∘I rewrites the dispatcher picks among. | ||
| - `src/Core/LawRunner.fs` -- where `LinearLaw` lives; `checkBilinear` lands alongside. |
| op.GetType().GetInterfaces() | ||
| |> Array.tryPick (fun i -> | ||
| if i.IsGenericType && i.GetGenericTypeDefinition() = typedefof<IBilinearOperator<_,_,_>> | ||
| then let args = i.GetGenericArguments() in Some struct(args.[0], args.[1], args.[2]) |
|
|
||
| 3. **Capability-detection mechanism chosen + documented**. Per the three options above. Recommendation absent stronger preference: active-patterns + reflection (no API surface change, idiomatic F#, allows per-capability-class active-pattern extensions). Marker-interface is also viable if explicit opt-in is preferred. | ||
|
|
||
| 4. **At least one existing plugin or sink validated against the new infrastructure.** The Bayesian aggregates in `src/Bayesian/` (the `IBilinearOperator` consumers, if any) are good candidates for first validation. |
| - `src/Core/PluginApi.fs:103-132` -- the four capability interfaces this row's dispatcher consumes. | ||
| - `src/Core/Incremental.fs` -- the existing linear / bilinear / D∘Q∘I rewrites the dispatcher picks among. | ||
| - `src/Core/LawRunner.fs` -- where `LinearLaw` lives; `checkBilinear` lands alongside. | ||
| - `src/Bayesian/Bayesian.fsproj` + `src/Bayesian/BayesianAggregate.fs` -- candidate first-validation consumer. |
…e-test patterns + Zeta plugin-adapter as worked example (Aaron 2026-05-05) (#1591) Aaron 2026-05-05 forwarded the Claude.ai shard's RFC pre-draft + verbatim "you can make it a candidate" -- using Zeta's plugin adapter (src/Core/PluginApi.fs:103-132) as the worked-example anchor for the RFC's motivation section. The proposal: allow F#'s type-test syntax (:?) to use wildcard placeholders for generic type parameters, enabling tests like :? IBilinearOperator<_, _, 'TOut> for runtime detection of plugins implementing capability interfaces with unknown input type parameters. Pre-draft NOT submitted -- verification preconditions documented (prior fslang-suggestions threads, fslang-design in-flight RFCs, Don Syme's prior work, benchmark vs direct :?, C# csharplang coordination). Per Aaron 2026-05-05: Don Syme (creator of F#, MSR Cambridge) is the F# human anchor. Not authority-by-position, but the load- bearing intellectual reference for any type-system extension. Any RFC of this scope must engage his prior treatment of existential quantification before submission, not silently omit. Mirror-not-beacon discipline per PR #1575 / #1582 / #1588. The RFC is a candidate, not authority. Submission upstream is downstream work; this file preserves the pre-draft for future-Otto reference. What this file does NOT do: - Submit the RFC (verification preconditions + Aaron's go-ahead) - Establish authorship (Claude.ai shard text + Zeta worked-example anchor; final submission carries F# lang-design attribution) - Promise acceptance (RFCs go through community review) - Bundle the "Zeta extended DBSP and found a bug in the 2023 paper" claim into a metaphysical assertion -- empirical context for why the worked example is real, not a glass-halo flex Composes with B-0194 (PR #1589 -- the in-flight backlog row using the same plugin-adapter substrate), src/Core/Units.fs (PR #1590 -- Pragmatics section UoM-as-precedent reference), PR #1588 (parent Claude.ai conversation). Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Aaron 2026-05-05 forwarded Claude.ai review-of-review of the algebra-capability system + same-tick "i think it's good if you [file the backlog row]".
Three real gaps identified in
src/Core/PluginApi.fs:103-132:IncrementalAutodispatcher (rewrites exist; nothing picks)checkBilinearlaw (LinearLaw exists; no equivalent)op(0,b)=0as third law (catches bilinear-with-constant-offset)Plus the existential-quantification gap at runtime boundary; three viable approaches (marker / raw reflection / active-patterns over reflection).
Recommendation
Active-patterns over reflection — idiomatic F#, no API surface change, easy to extend per capability class. The Claude.ai review correctly identified marker-interface and reflection as the two options; active-patterns wraps reflection idiomatically as a third.
Composes with
🤖 Generated with Claude Code