Skip to content

ext_algebra: let the Ext DGA carry a differential and compute cohomology#267

Open
JoeyBF wants to merge 7 commits into
SpectralSequences:masterfrom
JoeyBF:claude/ext-algebra-cohomology
Open

ext_algebra: let the Ext DGA carry a differential and compute cohomology#267
JoeyBF wants to merge 7 commits into
SpectralSequences:masterfrom
JoeyBF:claude/ext-algebra-cohomology

Conversation

@JoeyBF

@JoeyBF JoeyBF commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

A small, generic enhancement to ExtAlgebra, independent of the motivic work (it shares no files with it and can merge on its own). It's one of the foundations of the C-motivic Adams E₂ deformation effort, split out so it can be reviewed on its own terms.

Motivation

ExtAlgebra models Ext as the cochain complex Hom(P•, k) = k^gens. Over a field with a minimal resolution the coboundary is identically zero — dₛ lands in Ā·P_{s−1}, which every φ: P_{s−1} → k kills — so Ext is just the generators and "taking cohomology" is a no-op. But a deformation (a motivic τ-Bockstein δ) or a secondary operation (an Adams d₂) makes the coboundary nonzero, and then the object of interest is its cohomology.

What it adds

  • ExtDifferential — a pluggable DGA differential: a fixed bidegree shift, and at each bidegree the coboundary matrix in the generator bases. For graded coefficients (e.g. F₂[τ], graded by motivic weight) it also exposes graded_dimension / matrix_capped, so the cohomology can be computed one graded slice at a time. The default impls make those ungraded no-ops, so the field/minimal case behaves exactly as before.
  • ExtAlgebra::with_differential / differential — attach and read the differential.
  • cohomology_dimension (+ _capped)dim H = gens − rank δ_out − rank δ_in.

Scope

Nothing here is motivic. The two intended consumers are the motivic lift's δ (a later PR) and the existing secondary (d₂) machinery. Tests exercise it on the classical sphere with a mock differential — confirming the kernel/image bookkeeping, and that a zero differential recovers "cohomology = generators".

cargo test -p ext --lib ext_algebra — 7 passing.

🤖 Generated with Claude Code


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added a differential interface that can be attached to Ext algebra computations.
    • Added secondary coboundary support to model the (d_2) differential and reproduce (E_3)-page behavior.
    • Updated cohomology computations to be differential-aware, including capped dimensions and cohomology subquotients.
  • Bug Fixes
    • Improved correctness and safe fallbacks when differential data is missing or out of range.
  • Refactor
    • Switched (E_3)-page access to a per-bidegree reducer callback for homomorphism computations.
  • Tests
    • Added/updated tests covering both zero-differential behavior and a synthetic nonzero differential reproducing expected (E_3) subquotients/dimensions.

`ExtAlgebra` models Ext as the cochain complex Hom(P•, k) = k^gens. Over a
field with a minimal resolution its coboundary is identically zero, so Ext is
just the generators. But a *deformation* (a motivic τ-Bockstein δ) or a
*secondary* operation (an Adams d₂) makes the coboundary nonzero, and then
the interesting object is its cohomology.

This adds that differential as a pluggable piece:

- `ExtDifferential`: a fixed bidegree `shift` plus, at each bidegree, the
  coboundary `matrix` in the generator bases. For graded coefficients (e.g.
  F₂[τ], graded by motivic weight) it also exposes `graded_dimension` /
  `matrix_capped`, so cohomology can be computed one graded slice at a time;
  the default (ungraded/field) makes those no-ops and recovers the old
  behavior exactly.
- `ExtAlgebra::with_differential` / `differential` to attach and read it.
- `cohomology_dimension` (+ `_capped`): dim H = gens − rank δ_out − rank δ_in.

It's generic — nothing here is motivic. The two consumers are the motivic
lift's δ and the secondary (d₂) machinery; the tests exercise it on the
classical sphere with a mock differential (kernel/image bookkeeping) and
confirm the zero-differential case is just the generators.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ePtYD7Bt4iPeCtmqtqvZE
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 45475a30-f073-4b9c-b14a-41b9198f6a71

📥 Commits

Reviewing files that changed from the base of the PR and between b80d4e9 and e904c9e.

📒 Files selected for processing (1)
  • ext/src/ext_algebra/mod.rs

📝 Walkthrough

Walkthrough

ExtAlgebra now supports attached differentials and differential-aware cohomology. SecondaryExtAlgebra uses SecondaryCoboundary to derive E3 pages, while homomorphism reduction APIs receive per-bidegree E3 subquotient callbacks.

Changes

Ext differential integration

Layer / File(s) Summary
Differential API and cohomology computation
ext/src/ext_algebra/mod.rs
Adds ExtDifferential, optional differential attachment, kernel/image-based cohomology, and mock-differential tests.
Secondary d2 implementation
ext/src/ext_algebra/secondary.rs
Adds SecondaryCoboundary, derives matrices from secondary homotopy data, and computes E3 pages through differential-aware subquotients.
Callback-based E3 reduction
ext/src/resolution_homomorphism.rs, ext/examples/secondary_massey.rs
Replaces spectral-sequence arguments with per-bidegree E3 subquotient callbacks for homomorphism reduction and Massey computation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SecondaryExtAlgebra
  participant ExtAlgebra
  participant SecondaryCoboundary
  participant SecondaryResolution
  SecondaryExtAlgebra->>ExtAlgebra: attach SecondaryCoboundary
  ExtAlgebra->>SecondaryCoboundary: request d2 matrix
  SecondaryCoboundary->>SecondaryResolution: read homotopy data
  SecondaryResolution-->>SecondaryCoboundary: provide matrix entries
  SecondaryCoboundary-->>ExtAlgebra: compute E3 subquotient
Loading

Possibly related PRs

Suggested reviewers: hoodmane

Poem

I’m a rabbit with matrices bright,
Hopping through kernels overnight.
The d2 currents flow,
E3 starts to grow.
Binky—cohomology’s right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding a differential to ExtAlgebra and using it to compute cohomology.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Validate that the differential→cohomology abstraction serves a second consumer:
the Adams d₂. Two additions, no behavior change to existing paths.

- `ExtAlgebra::cohomology_subquotient(b)`: the cohomology at `b` as a
  `Subquotient` of the generators — ker(δ out) mod im(δ into), i.e. actual
  representatives of the surviving classes, not just the dimension. The natural
  companion to `cohomology_dimension`; the motivic side wants it (surviving-class
  reps) as much as the secondary side does.
- `SecondaryCoboundary: ExtDifferential`: the Adams d₂ presented as a coboundary
  on the primary ExtAlgebra, shift (n,s) → (n-1,s+2), matrix read from the
  secondary resolution's homotopies. Its `matrix` sizes each end at its own
  bidegree so an `a×0` (empty target: a d₂-cycle) and a `0×b` (off-axis source,
  in-quadrant target: an ambient-`b` image) stay distinct; off the first quadrant
  Ext is a *known* zero, in-quadrant-but-unresolved is unknown (`None`).

Gate test: attaching `SecondaryCoboundary` and computing the E₃ page via the
shared `cohomology_subquotient` reproduces the spectral-sequence bookkeeping's
`page_data` exactly across the sphere in a range (dimension at every bidegree,
including the axes). This is the groundwork for routing the secondary layer's
page/product machinery onto the shared path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ePtYD7Bt4iPeCtmqtqvZE

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ext/src/ext_algebra/mod.rs`:
- Around line 64-79: Document in the trait comments for graded_dimension and
matrix_capped that graded implementations must override both methods together,
ensuring the capped generator count matches the compacted capped matrix
dimensions. Make the invariant explicit near cohomology_dimension_capped so
future implementations do not override only graded_dimension.
- Around line 202-231: Validate the shapes of matrices returned by
ExtDifferential in cohomology_subquotient before using them: require d.matrix(b)
to have dim rows and d.matrix(source) to have dim columns. Return a clear
diagnostic through the method’s existing error/validation mechanism when either
contract is violated, including the bidegree and actual versus expected
dimensions, instead of allowing row or subspace construction to panic; preserve
the missing-matrix zero-image behavior.
- Around line 167-191: Update ExtAlgebra::cohomology_dimension_capped to
validate that rank_out plus rank_in does not exceed gens before performing the
usize subtraction. If the invariant is violated, return None (or the established
invalid-result representation) instead of allowing underflow; preserve the
existing dimension calculation for valid differentials.
- Around line 437-446: Update the mock ExtDifferential implementation’s matrix
method to return a zero matrix with dimensions matching the number of generators
in b, rather than always returning 0x0 outside Bidegree::n_s(0, 2). Preserve the
existing 1x1 matrix for that bidegree and use alg.dimension(b) or the
corresponding dimension source for the zero-matrix shape.

In `@ext/src/ext_algebra/secondary.rs`:
- Around line 41-47: Make SecondaryCoboundary constructible outside its defining
module by adding a public constructor that accepts the required resolution and
prime, or narrow the struct visibility to pub(crate) if it is internal. Also
remove the redundant p field and derive the prime from
res_lift.underlying().prime() wherever needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f887ba1e-4ff7-4aa5-b4ac-a47d6183b1b5

📥 Commits

Reviewing files that changed from the base of the PR and between a3a63cb and d465c71.

📒 Files selected for processing (2)
  • ext/src/ext_algebra/mod.rs
  • ext/src/ext_algebra/secondary.rs

Comment thread ext/src/ext_algebra/mod.rs Outdated
Comment on lines +167 to +191
pub fn cohomology_dimension(&self, b: Bidegree) -> Option<usize> {
self.cohomology_dimension_capped(b, i32::MAX)
}

/// The dimension of the DGA's cohomology at `b` restricted to the coefficient's
/// weight slice `≤ cap` — for a graded coefficient like $\mathbb{F}_2[\tau]$
/// this is a slice of the Ext *module*, and sweeping `cap` exposes the
/// $\tau$-torsion (dimension above the free/`cap = ∞` rank). For an ungraded
/// (field) coefficient the differential reports no grading and this is just
/// [`cohomology_dimension`](Self::cohomology_dimension) for every `cap`.
pub fn cohomology_dimension_capped(&self, b: Bidegree, cap: i32) -> Option<usize> {
let Some(d) = &self.differential else {
return Some(self.dimension(b));
};
let gens = d
.graded_dimension(b, cap)
.unwrap_or_else(|| self.dimension(b));
let shift = d.shift();
let source = Bidegree::n_s(b.n() - shift.n(), b.s() - shift.s());
let rank_out = d.matrix_capped(b, cap)?.row_reduce();
let rank_in = d
.matrix_capped(source, cap)
.map_or(0, |mut m| m.row_reduce());
Some(gens - rank_out - rank_in)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Guard the gens - rank_out - rank_in computation against invariant violations.

This subtraction implicitly assumes rank_out + rank_in <= gens, which only holds if the differential satisfies d ∘ d = 0 at b. That's never checked, so a malformed or buggy ExtDifferential impl would trigger a usize underflow — panicking in debug or silently wrapping to a huge value in release — instead of a clear error.

🛡️ Proposed defensive check
         let rank_out = d.matrix_capped(b, cap)?.row_reduce();
         let rank_in = d
             .matrix_capped(source, cap)
             .map_or(0, |mut m| m.row_reduce());
+        debug_assert!(
+            rank_out + rank_in <= gens,
+            "ExtDifferential violates d∘d=0 at {b:?}: rank_out={rank_out}, rank_in={rank_in}, gens={gens}"
+        );
         Some(gens - rank_out - rank_in)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn cohomology_dimension(&self, b: Bidegree) -> Option<usize> {
self.cohomology_dimension_capped(b, i32::MAX)
}
/// The dimension of the DGA's cohomology at `b` restricted to the coefficient's
/// weight slice `≤ cap` — for a graded coefficient like $\mathbb{F}_2[\tau]$
/// this is a slice of the Ext *module*, and sweeping `cap` exposes the
/// $\tau$-torsion (dimension above the free/`cap = ∞` rank). For an ungraded
/// (field) coefficient the differential reports no grading and this is just
/// [`cohomology_dimension`](Self::cohomology_dimension) for every `cap`.
pub fn cohomology_dimension_capped(&self, b: Bidegree, cap: i32) -> Option<usize> {
let Some(d) = &self.differential else {
return Some(self.dimension(b));
};
let gens = d
.graded_dimension(b, cap)
.unwrap_or_else(|| self.dimension(b));
let shift = d.shift();
let source = Bidegree::n_s(b.n() - shift.n(), b.s() - shift.s());
let rank_out = d.matrix_capped(b, cap)?.row_reduce();
let rank_in = d
.matrix_capped(source, cap)
.map_or(0, |mut m| m.row_reduce());
Some(gens - rank_out - rank_in)
}
pub fn cohomology_dimension(&self, b: Bidegree) -> Option<usize> {
self.cohomology_dimension_capped(b, i32::MAX)
}
/// The dimension of the DGA's cohomology at `b` restricted to the coefficient's
/// weight slice `≤ cap` — for a graded coefficient like $\mathbb{F}_2[\tau]$
/// this is a slice of the Ext *module*, and sweeping `cap` exposes the
/// $\tau$-torsion (dimension above the free/`cap = ∞` rank). For an ungraded
/// (field) coefficient the differential reports no grading and this is just
/// [`cohomology_dimension`](Self::cohomology_dimension) for every `cap`.
pub fn cohomology_dimension_capped(&self, b: Bidegree, cap: i32) -> Option<usize> {
let Some(d) = &self.differential else {
return Some(self.dimension(b));
};
let gens = d
.graded_dimension(b, cap)
.unwrap_or_else(|| self.dimension(b));
let shift = d.shift();
let source = Bidegree::n_s(b.n() - shift.n(), b.s() - shift.s());
let rank_out = d.matrix_capped(b, cap)?.row_reduce();
let rank_in = d
.matrix_capped(source, cap)
.map_or(0, |mut m| m.row_reduce());
debug_assert!(
rank_out + rank_in <= gens,
"ExtDifferential violates d∘d=0 at {b:?}: rank_out={rank_out}, rank_in={rank_in}, gens={gens}"
);
Some(gens - rank_out - rank_in)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ext/src/ext_algebra/mod.rs` around lines 167 - 191, Update
ExtAlgebra::cohomology_dimension_capped to validate that rank_out plus rank_in
does not exceed gens before performing the usize subtraction. If the invariant
is violated, return None (or the established invalid-result representation)
instead of allowing underflow; preserve the existing dimension calculation for
valid differentials.

Comment thread ext/src/ext_algebra/mod.rs
Comment thread ext/src/ext_algebra/mod.rs
Comment thread ext/src/ext_algebra/secondary.rs Outdated
claude added 3 commits July 12, 2026 07:23
…y path

The secondary layer computed its E₃ pages by building a whole Sseq<2, Adams>
per resolution and reading `page_data` off it. Now that the Adams d₂ is an
`ExtDifferential`, `cohomology_subquotient` computes the same E₃ page directly
(ker d₂ / im d₂), so the parallel bookkeeping is redundant.

- `ExtAlgebra::cohomology_subquotient(b)`: the E₃ page (representatives, not
  just the dimension `cohomology_dimension` gives).
- `SecondaryExtAlgebra` holds an Ext-with-d₂ for `M` and for the unit; its
  `page_data`/`unit_page_data` are now `cohomology_subquotient`, and
  `extend_all` no longer builds any Sseq. The `res_sseq`/`unit_sseq` fields,
  their construction, and the `e3_page_data` helper are gone.
- `SecondaryResolutionHomomorphism::hom_k` took a whole `Sseq` only to read one
  page (the λ-part's d₂-image quotient). It now takes the E₃ page as a function
  of bidegree and queries it at its own `lambda_source` — no fragile
  reconstruction of that bidegree by the caller (the first, index-arithmetic
  attempt is what the new product smoke test caught).

Hardening from review:
- assert `ExtDifferential::matrix` shapes in `cohomology_subquotient`
  (gens(b) rows / gens(b) columns), so a nonconformant impl fails loudly;
- debug_assert `rank_out + rank_in ≤ gens` before the cohomology subtraction;
- document that graded impls must override `graded_dimension`/`matrix_capped`
  together;
- the `MockDiff` test fixture now returns correctly-shaped zero matrices (via
  the resolution's generator counts), making it a valid reference for
  `cohomology_subquotient`, not just rank-only `cohomology_dimension`;
- `SecondaryCoboundary` is `pub(crate)` and derives its prime from the
  resolution instead of storing it.

Validated: `secondary-S_2` and `secondary-C2` benchmarks are byte-identical to
golden; new tests cover the E₃-page agreement, the mock subquotient, and that
the secondary product's Ext part is the primary product.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ePtYD7Bt4iPeCtmqtqvZE
… + nightly fmt

The `hom_k`/`hom_k_with` signature change (Sseq → E₃-page function) missed a
caller: `examples/secondary_massey.rs`, which only compiles under default
features (my local runs used --no-default-features, and my grep for callers
searched src/ only). Adapt its call to pass the E₃ page as a closure over the
example's existing `get_page_data`.

Also run nightly `cargo fmt` (the repo's rustfmt.toml enables unstable options —
reorder_impl_items, group_imports, format_strings — that stable rustfmt silently
skips), which the `lint` CI job checks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ePtYD7Bt4iPeCtmqtqvZE
…lved range

`secondary_product`/`secondary_massey` query the E3 page one row past the
resolved filtration, where the outgoing d2 lands at an unresolved bidegree.
The old Sseq path (SecondaryResolution::e3_page) treats an uncomputed outgoing
differential as zero — those classes provisionally survive — so page_data was
always defined there. cohomology_subquotient is stricter: a None outgoing
matrix makes it return None, and unit_page_data's .expect() then panicked
(caught by the C2 v_1 benchmark under `just benchmarks`).

Reproduce the e3_page convention locally in SecondaryCoboundary::matrix by
distinguishing the two ends: an in-quadrant-but-unresolved *source* still means
the page is unknown (None), but an in-quadrant-but-unresolved *target* means
the secondary resolution records no d2 there yet, so give a `rows × 0` matrix
(the whole source is a provisional d2-cycle) instead of None. The generic
cohomology_subquotient contract is unchanged. That `rows × 0` matrix is never
consumed as an incoming differential, since the target bidegree's own
subquotient short-circuits to None at its numerator.

Verified byte-identical against the secondary-*, secondary_product-*, and
secondary_massey-* golden benchmarks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ePtYD7Bt4iPeCtmqtqvZE

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ext/src/ext_algebra/mod.rs (1)

188-196: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate capped matrix dimensions before using their ranks.

An undersized capped matrix can satisfy the rank assertion while silently overstating cohomology. Assert that the outgoing matrix has gens rows and the incoming matrix has gens columns before reduction.

Proposed fix
-        let rank_out = d.matrix_capped(b, cap)?.row_reduce();
-        let rank_in = d
-            .matrix_capped(source, cap)
-            .map_or(0, |mut m| m.row_reduce());
+        let mut out = d.matrix_capped(b, cap)?;
+        assert_eq!(out.rows(), gens);
+        let rank_out = out.row_reduce();
+        let rank_in = match d.matrix_capped(source, cap) {
+            Some(mut incoming) => {
+                assert_eq!(incoming.columns(), gens);
+                incoming.row_reduce()
+            }
+            None => 0,
+        };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ext/src/ext_algebra/mod.rs` around lines 188 - 196, In the rank computation
around graded_dimension, validate matrix dimensions before row reduction: ensure
the outgoing matrix from matrix_capped(b, cap) has gens rows and the incoming
matrix from matrix_capped(source, cap) has gens columns. Preserve the existing
rank defaults and error propagation while asserting these dimensions before
calling row_reduce.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@ext/src/ext_algebra/mod.rs`:
- Around line 188-196: In the rank computation around graded_dimension, validate
matrix dimensions before row reduction: ensure the outgoing matrix from
matrix_capped(b, cap) has gens rows and the incoming matrix from
matrix_capped(source, cap) has gens columns. Preserve the existing rank defaults
and error propagation while asserting these dimensions before calling
row_reduce.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f196e61e-c144-4759-b08b-d2a399f8f695

📥 Commits

Reviewing files that changed from the base of the PR and between d465c71 and 5678bd7.

📒 Files selected for processing (4)
  • ext/examples/secondary_massey.rs
  • ext/src/ext_algebra/mod.rs
  • ext/src/ext_algebra/secondary.rs
  • ext/src/resolution_homomorphism.rs

claude added 2 commits July 12, 2026 11:06
cohomology_dimension_capped mixed a capped generator count (graded_dimension)
with ranks read off matrix_capped without checking the matrices are the right
shape. An undersized capped matrix would understate a rank and silently
overstate the cohomology. Assert the outgoing matrix has `gens` rows and the
incoming matrix has `gens` columns before row-reducing, matching the shape
checks already in cohomology_subquotient.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ePtYD7Bt4iPeCtmqtqvZE
Lead ExtAlgebra and ExtDifferential with the classical story — Ext is the
cohomology of Hom(P•,k); minimal resolution ⇒ generators, non-minimal ⇒ the
canonical dualised differential Hom(d,k) — rather than the deformation story.
The Adams d2 / motivic δ are named only as *also* using the pluggable
coboundary, with the machinery kept in their own modules (the secondary layer);
they no longer headline ExtAlgebra's interface. Generalize graded_dimension's
wording from "motivic weight" to "a deformation base R" (F2[τ] as the example),
since the cap-sweep is the general R-module shape, not motivic-specific.

Docs only — no logic changes. Docs build clean under -D broken_intra_doc_links
-D private_intra_doc_links.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ePtYD7Bt4iPeCtmqtqvZE
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.

2 participants