archive: conditional X3 SPLINE acceptance preserving rmorgans prerequisites (unrun)

This commit is contained in:
selune
2026-10-31 03:20:37 +01:00
parent dfb0b3e113
commit 3559964792
7 changed files with 7082 additions and 0 deletions
@@ -0,0 +1,33 @@
# Conditional X3 SPLINE acceptance
Source-only proposal for SolidCraft; one existing product path, `crates/io/src/dxf.rs`. The added adapter lives exclusively inside its existing `#[cfg(test)]` module. There is no new production helper, import routing or test registration outside that module.
## Provenance and application
The receiver is #8515 at `d8e7a8690a30e44a58255e5dd345881ef092a93a`. The supplied **before** source composes that receiver with **four exact, unedited dxf.rs hunks by rmorgans from #9356** at `2edca81fef00da8e8cd43fbc77ad1dfebff350ee`, based on `f9146cdd5887af90b0999c8dbd8f4fb8ae0f7f18`. Those owner hunks cover the legacy SPLINE arm, Nurbs affine handling, the writer match arm and the owner's original test. They are prerequisites, not changes authored by this proposal.
The candidate adds only our conditional adapter, fixture builder and seven acceptance tests to that composed source. The 84 prior inline test bodies and the entire composed production prefix are preserved. TEXT/INSERT and rmorgans' legacy SPLINE fallback are unchanged.
Apply `own-conditional-appendix.patch` only to source identical to `before/crates/io/src/dxf.rs`; its output is `candidate/crates/io/src/dxf.rs`. All three are literal RAW bytes. No full alternative patch is included: the complete before source plus the owned patch already reconstructs the candidate without duplicating owner changes. Reconcile the exact prerequisites before applying to another receiver.
## Preserve, defer and reject
- **Preserve:** admitted degree/control coordinates, nonuniform clamped knots and unequal rational weights pass to the real `Geom2::bspline`. Units become millimetres once in the typed reader; positive uniform copy transforms only control positions. The owner's even-knot/equal-weight editable-spline canonicalization remains, without promising authored representation bits survive it.
- **Defer:** production projection/routing, TEXT/MTEXT anchor/raw spelling semantics, INSERT/block semantics, original flag provenance and whole-import/expansion budgets. The current typed reader admits only its supported clamped SPLINE subset; it rejects closed/periodic/linear/fit flags and unclamped inputs. `DxfShape` alone cannot prove the original flags.
- **Reject:** factory `Option::None` becomes an explicit `IoError`; other shapes explicitly refuse. No clamping, fitting, resampling, extra unit factor, guessed flags, silent drop or legacy fallback is introduced.
Seven original **UNRUN** tests cover nonuniform quadratic spans with independent analytic points; the owner's even/equal-weight editable path; a weighted quarter circle with inch-to-mm import and scale/translation; unsupported source flags/fit data; malformed/unclamped controls and counts; ten invalid typed inputs producing explicit constructor errors; and non-SPLINE refusal. Real reader, model-copy, factory and public evaluator APIs are used.
## Integration conditions
#9356 was open/draft/unmerged at the pinned metadata capture. Besides its four dxf.rs hunks, five other owner paths remain integration dependencies and are not supplied or edited here:
- `crates/io/src/sketch2d.rs`: factory and Nurbs representation.
- `crates/sketch/src/lib.rs`: sketch representation/public exports.
- `crates/sketch/src/curves.rs`: evaluator.
- `crates/engine/src/cmd/sketch_import.rs`: engine conversion.
- `crates/io/src/svg.rs`: exhaustive geometry handling.
This isolated geometry acceptance proposal does not complete X3 or integrate #9356. Source preservation and byte reconstruction establish no compiler, test, runtime or mergeability result. No formatting, compilation or tests were run for this proposal. Owner-stack reconciliation, independent integration review and compiler/test qualification remain required.
`source-bindings.json` records exact pinned source references and RAW identities. `publication-manifest.json` lists only the files intended for publication.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,209 @@
diff --git a/crates/io/src/dxf.rs b/crates/io/src/dxf.rs
--- a/crates/io/src/dxf.rs
+++ b/crates/io/src/dxf.rs
@@ -3229,4 +3229,205 @@
"budget precedes allocation and producer admission"
);
}
+ // Conditional seam acceptance, not the production read_dxf projection.
+ // This stays inside the existing cfg(test) module: actual9356 supplies
+ // Geom2::bspline/Nurbs and the public evaluator when the source is composed.
+ // Raw flags/provenance are admitted by read_dxf_file before these positive
+ // fixtures reach this geometry-only adapter; a DxfShape alone proves none.
+ fn project_layered_spline_for_legacy(shape: DxfShape) -> Result<Geom2> {
+ let DxfShape::Spline { degree, knots, ctrl, weights } = shape else {
+ return Err(IoError::Invalid("not supported yet: partial legacy projection accepts only SPLINE".into()));
+ };
+ // Move the arrays into the delivered constructor. No clamping, fitting,
+ // resampling, extra unit factor or fallback to an even control spline.
+ Geom2::bspline(degree, ctrl, knots, weights)
+ .ok_or_else(|| IoError::Invalid("layered SPLINE refused by the delivered legacy B-spline constructor".into()))
+ }
+
+ fn spline_projection_fixture(units: i32, flags: i32, degree: u8, ctrl: &[(f64, f64)], knots: &[f64], weights: &[f64]) -> String {
+ let mut text = format!(
+ "0\nSECTION\n2\nHEADER\n9\n$INSUNITS\n70\n{units}\n0\nENDSEC\n0\nSECTION\n2\nENTITIES\n\
+ 0\nSPLINE\n70\n{flags}\n71\n{degree}\n72\n{}\n73\n{}\n74\n0\n",
+ knots.len(), ctrl.len(),
+ );
+ for k in knots {
+ text.push_str(&format!("40\n{k}\n"));
+ }
+ for w in weights {
+ text.push_str(&format!("41\n{w}\n"));
+ }
+ for (x, y) in ctrl {
+ text.push_str(&format!("10\n{x}\n20\n{y}\n"));
+ }
+ text.push_str("0\nENDSEC\n0\nEOF\n");
+ text
+ }
+
+ #[test]
+ fn layered_spline_projection_nonuniform_knots_keep_two_analytic_quadratic_spans() {
+ let text = spline_projection_fixture(
+ 4, 8, 2,
+ &[(0.0, 0.0), (2.0, 3.0), (5.0, -1.0), (7.0, 2.0)],
+ &[0.0, 0.0, 0.0, 1.0, 3.0, 3.0, 3.0], &[],
+ );
+ let file = read_dxf_file(&text).unwrap();
+ assert_eq!(file.entities().len(), 1);
+ let projected = project_layered_spline_for_legacy(file.entities()[0].geometry().clone()).unwrap();
+ let Geom2::Nurbs { degree, ref knots, ref ctrl, ref weights } = projected else {
+ panic!("uneven knots must not become the sketch's even-knot control spline")
+ };
+ assert_eq!(degree, 2);
+ assert_eq!(knots.as_slice(), &[0.0, 0.0, 0.0, 1.0, 3.0, 3.0, 3.0]);
+ assert_eq!(ctrl.as_slice(), &[Vec2::new(0.0, 0.0), Vec2::new(2.0, 3.0), Vec2::new(5.0, -1.0), Vec2::new(7.0, 2.0)]);
+ assert!(weights.is_none());
+ let pieces = solidcraft_doc::sketch::nurbs_beziers(ctrl, weights.as_deref(), knots, usize::from(degree)).unwrap();
+ assert_eq!(pieces.len(), 2);
+ // Analytic quadratic spans: [P0,P1,(2P1+P2)/3] and
+ // [(2P1+P2)/3,P2,P3]. The literals below are independent
+ // points on those two polynomials, not recorded exporter output.
+ for (index, t, expected) in [
+ (0, 0.0, Vec2::new(0.0, 0.0)),
+ (0, 0.5, Vec2::new(7.0 / 4.0, 23.0 / 12.0)),
+ (0, 1.0, Vec2::new(3.0, 5.0 / 3.0)),
+ (1, 0.0, Vec2::new(3.0, 5.0 / 3.0)),
+ (1, 0.5, Vec2::new(5.0, 5.0 / 12.0)),
+ (1, 1.0, Vec2::new(7.0, 2.0)),
+ ] {
+ let actual = pieces[index].point(t);
+ assert!(actual.dist(expected) < 1e-11, "piece={index}, t={t}: {actual:?} != {expected:?}");
+ }
+ }
+
+ #[test]
+ fn layered_spline_projection_even_knots_keep_editable_control_spline() {
+ for (flags, weights) in [(8, vec![]), (12, vec![2.0; 4])] {
+ let text = spline_projection_fixture(
+ 4, flags, 2,
+ &[(0.0, 0.0), (2.0, 3.0), (5.0, -1.0), (7.0, 2.0)],
+ &[0.0, 0.0, 0.0, 1.5, 3.0, 3.0, 3.0], &weights,
+ );
+ let file = read_dxf_file(&text).unwrap();
+ let projected = project_layered_spline_for_legacy(file.entities()[0].geometry().clone()).unwrap();
+ let Geom2::Spline { pts, control, degree } = projected else {
+ panic!("the delivered factory's even/equal-weight path must remain editable")
+ };
+ assert!(control);
+ assert_eq!(degree, 2);
+ assert_eq!(pts, vec![Vec2::new(0.0, 0.0), Vec2::new(2.0, 3.0), Vec2::new(5.0, -1.0), Vec2::new(7.0, 2.0)]);
+ }
+ }
+
+ #[test]
+ fn layered_spline_projection_rational_quarter_circle_scales_once_and_keeps_weights() {
+ let w = std::f64::consts::FRAC_1_SQRT_2;
+ let text = spline_projection_fixture(
+ 1, 12, 2, &[(1.0, 0.0), (1.0, 1.0), (0.0, 1.0)],
+ &[0.0, 0.0, 0.0, 1.0, 1.0, 1.0], &[1.0, w, 1.0],
+ );
+ let file = read_dxf_file(&text).unwrap();
+ let DxfShape::Spline { knots: original_knots, ctrl: original_ctrl, weights: original_weights, .. } = file.entities()[0].geometry() else {
+ panic!("the actual layered reader must produce a SPLINE")
+ };
+ assert_eq!(original_ctrl.as_slice(), &[Vec2::new(25.4, 0.0), Vec2::new(25.4, 25.4), Vec2::new(0.0, 25.4)]);
+ assert_eq!(original_knots.as_slice(), &[0.0, 0.0, 0.0, 1.0, 1.0, 1.0]);
+ assert_eq!(original_weights.as_deref(), Some(&[1.0, w, 1.0][..]));
+ let center = Vec2::new(10.0, -7.0);
+ let copied = file.translated_scaled(center, 2.0).unwrap();
+ let projected = project_layered_spline_for_legacy(copied.entities()[0].geometry().clone()).unwrap();
+ let Geom2::Nurbs { degree, ref knots, ref ctrl, ref weights } = projected else {
+ panic!("the rational quarter circle must keep its weights")
+ };
+ assert_eq!(degree, 2);
+ assert_eq!(knots, original_knots);
+ assert_eq!(weights, original_weights);
+ let pieces = solidcraft_doc::sketch::nurbs_beziers(ctrl, weights.as_deref(), knots, usize::from(degree)).unwrap();
+ assert_eq!(pieces.len(), 1);
+ for t in [0.0, 0.125, 0.5, 0.875, 1.0] {
+ assert!(((pieces[0].point(t) - center).len() - 50.8).abs() < 1e-10, "t={t}");
+ }
+ for (t, expected) in [
+ (0.0, center + Vec2::new(50.8, 0.0)),
+ (0.5, center + Vec2::new(50.8 * w, 50.8 * w)),
+ (1.0, center + Vec2::new(0.0, 50.8)),
+ ] {
+ assert!(pieces[0].point(t).dist(expected) < 1e-10, "t={t}: {expected:?}");
+ }
+ // Model copying/projecting leaves original source records untouched.
+ assert_eq!(file.entities()[0].geometry(), &DxfShape::Spline {
+ degree: 2, knots: vec![0.0, 0.0, 0.0, 1.0, 1.0, 1.0],
+ ctrl: vec![Vec2::new(25.4, 0.0), Vec2::new(25.4, 25.4), Vec2::new(0.0, 25.4)],
+ weights: Some(vec![1.0, w, 1.0]),
+ });
+ }
+
+ #[test]
+ fn layered_spline_projection_closed_periodic_and_fit_flags_refuse_before_projection() {
+ let ctrl = [(1.0, 0.0), (1.0, 1.0), (0.0, 1.0)];
+ let knots = [0.0, 0.0, 0.0, 1.0, 1.0, 1.0];
+ for flags in [1, 2, 3, 9, 10, 16, 24] {
+ let text = spline_projection_fixture(4, flags, 2, &ctrl, &knots, &[]);
+ assert!(read_dxf_file(&text).is_err(), "unsupported flags={flags} must refuse before conversion");
+ }
+ let text = spline_projection_fixture(4, 8, 2, &ctrl, &knots, &[]);
+ assert!(text.contains("74\n0\n"));
+ assert!(read_dxf_file(&text.replace("74\n0\n", "74\n1\n")).is_err());
+ for flags in [0, 8] {
+ let file = read_dxf_file(&spline_projection_fixture(4, flags, 2, &ctrl, &knots, &[])).unwrap();
+ assert!(matches!(project_layered_spline_for_legacy(file.entities()[0].geometry().clone()).unwrap(), Geom2::Spline { control: true, degree: 2, .. }));
+ }
+ let w = std::f64::consts::FRAC_1_SQRT_2;
+ for flags in [4, 12] {
+ let file = read_dxf_file(&spline_projection_fixture(4, flags, 2, &ctrl, &knots, &[1.0, w, 1.0])).unwrap();
+ assert!(matches!(project_layered_spline_for_legacy(file.entities()[0].geometry().clone()).unwrap(), Geom2::Nurbs { degree: 2, .. }));
+ }
+ }
+
+ #[test]
+ fn layered_spline_projection_unclamped_or_invalid_controls_do_not_fall_back() {
+ let ctrl = [(0.0, 0.0), (2.0, 3.0), (5.0, -1.0), (7.0, 2.0)];
+ let knots = [0.0, 0.0, 0.0, 1.0, 3.0, 3.0, 3.0];
+ let text = spline_projection_fixture(4, 8, 2, &ctrl, &knots, &[]);
+ assert!(text.contains("73\n4\n"));
+ let malformed = [
+ spline_projection_fixture(4, 8, 2, &ctrl, &[-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0], &[]),
+ spline_projection_fixture(4, 8, 2, &[(0.0, 0.0), (f64::NAN, 3.0), (5.0, -1.0), (7.0, 2.0)], &knots, &[]),
+ text.replace("73\n4\n", "73\n3\n"),
+ ];
+ for input in malformed {
+ assert!(read_dxf_file(&input).is_err(), "typed admission must not fall back to the permissive legacy reader");
+ }
+ }
+
+ #[test]
+ fn layered_spline_projection_constructor_none_is_explicit_for_invalid_typed_data() {
+ for case in 0..10 {
+ let mut shape = DxfShape::Spline {
+ degree: 2, knots: vec![0.0, 0.0, 0.0, 1.0, 1.0, 1.0],
+ ctrl: vec![Vec2::new(1.0, 0.0), Vec2::new(1.0, 1.0), Vec2::new(0.0, 1.0)], weights: None,
+ };
+ if let DxfShape::Spline { degree, knots, ctrl, weights } = &mut shape {
+ match case {
+ 0 => *degree = 0,
+ 1 => *degree = 10,
+ 2 => { ctrl.pop(); }
+ 3 => ctrl[1].x = f64::NAN,
+ 4 => { knots.pop(); }
+ 5 => knots[3] = -1.0,
+ 6 => knots.fill(0.0),
+ 7 => *weights = Some(vec![1.0, 0.0, 1.0]),
+ 8 => *weights = Some(vec![1.0, -1.0, 1.0]),
+ _ => *weights = Some(vec![1.0, 1.0]),
+ }
+ }
+ let error = project_layered_spline_for_legacy(shape).unwrap_err().to_string();
+ assert!(error.contains("refused by the delivered legacy B-spline constructor"), "case={case}: {error}");
+ }
+ }
+
+ #[test]
+ fn layered_spline_projection_non_spline_is_an_explicit_unsupported_case() {
+ let error = project_layered_spline_for_legacy(DxfShape::Line(Vec2::ZERO, Vec2::X)).unwrap_err().to_string();
+ assert!(error.contains("only SPLINE"), "{error}");
+ }
+
}
@@ -0,0 +1,61 @@
{
"status": "ALLOWLISTED_SOURCE_ONLY_PUBLICATION_PACKET",
"suggested_destination": "proposals/drawings/2026-10-31/x3-spline-projection/",
"publication_by": "ROOT",
"allowlist": [
"README.md",
"source-bindings.json",
"before/crates/io/src/dxf.rs",
"candidate/crates/io/src/dxf.rs",
"own-conditional-appendix.patch"
],
"member_count": 5,
"members": [
{
"path": "before/crates/io/src/dxf.rs",
"bytes": 165014,
"sha256": "409bb336acc4594314a566f40196f66294c45e5afaa546ba96a377de804b8d72"
},
{
"path": "candidate/crates/io/src/dxf.rs",
"bytes": 175531,
"sha256": "e89ab2b1a4a4717ab806da8bddf228a315591be41d780b439002686e99394cd7"
},
{
"path": "own-conditional-appendix.patch",
"bytes": 10940,
"sha256": "337eb943d7d49b279555cfca73d532568fc0d8aa5df1c74aeac1352af7a140d0"
},
{
"path": "README.md",
"bytes": 3952,
"sha256": "d4c3d74c5bc64f6549d2824f354a4a6683d548910afe86d27f92131b2cb1726b"
},
{
"path": "source-bindings.json",
"bytes": 4727,
"sha256": "785e41031435eb63890e6fa1dc46534aa9e7adcfbb95edae9cffbf11611dcccd"
}
],
"privacy_checks": {
"exact_allowlist": true,
"private_local_paths_absent": true,
"private_chat_ids_absent": true,
"credential_shaped_markers_absent": true,
"scripts_logs_receipts_toolstate_source_captures_absent": true
},
"raw_identity_checks": {
"before_unchanged": true,
"candidate_unchanged": true,
"owned_patch_unchanged": true,
"forward_reconstruction": true,
"owner_hunks_unedited": 4,
"original_tests_preserved": 84,
"new_tests_unrun": 7
},
"full_alternative_omitted": "Redundant: complete before RAW plus owned RAW delta reconstructs candidate.",
"compiled": false,
"tests_run": false,
"runtime_qualified": false,
"owner_integration_complete": false
}
@@ -0,0 +1,110 @@
{
"status": "PINNED_SOURCE_IDENTITIES_NOT_EXECUTION_RESULTS",
"receiver_PR": 8515,
"receiver_head": "d8e7a8690a30e44a58255e5dd345881ef092a93a",
"owner_PR": 9356,
"owner_author": "rmorgans",
"owner_head": "2edca81fef00da8e8cd43fbc77ad1dfebff350ee",
"owner_base": "f9146cdd5887af90b0999c8dbd8f4fb8ae0f7f18",
"owner_state_at_capture": "open draft unmerged",
"owner_exact_unedited_dxf_hunks": 4,
"before_sha256": "409bb336acc4594314a566f40196f66294c45e5afaa546ba96a377de804b8d72",
"candidate_sha256": "e89ab2b1a4a4717ab806da8bddf228a315591be41d780b439002686e99394cd7",
"owned_patch_sha256": "337eb943d7d49b279555cfca73d532568fc0d8aa5df1c74aeac1352af7a140d0",
"source_refs": [
{
"repository": "0xlillith/solidcraft",
"ref": "d8e7a8690a30e44a58255e5dd345881ef092a93a",
"path": "crates/io/src/dxf.rs",
"github_blob": "278581d5dd5feb514fb13e9aa9f925fc9525be93",
"raw_sha256": "0b614a91d0e8e18698238f727cf3a7f193c3813ce89641f503ac3e6f63022d9c",
"raw_bytes": 160844
},
{
"repository": "0xlillith/solidcraft",
"ref": "d8e7a8690a30e44a58255e5dd345881ef092a93a",
"path": "crates/io/src/dxf_out.rs",
"github_blob": "4994bb769af39f3514cc6779b640e6e8c64c6540",
"raw_sha256": "e451ebb48561349b870886e72d5a9ee50073ed69798619f03217654dc8928304",
"raw_bytes": 120393
},
{
"repository": "0xlillith/solidcraft",
"ref": "d8e7a8690a30e44a58255e5dd345881ef092a93a",
"path": "crates/io/src/dxf_out/file_model.rs",
"github_blob": "3804e73b342a5116251698dd9ab326d7875ea22a",
"raw_sha256": "b6b44a90168b9f36e9f3086198a53edd30f0d7f81d10f256d639c0f7f784bd55",
"raw_bytes": 44667
},
{
"repository": "0xlillith/solidcraft",
"ref": "d8e7a8690a30e44a58255e5dd345881ef092a93a",
"path": "crates/io/src/dxf_out/file_model/geometry.rs",
"github_blob": "a99465aeac84d978f1aaed8777c5dbcf018542e9",
"raw_sha256": "e0caa2f7e94c260cfe51fcb67b4473422c9e000cde019e34c0eb11e604138f3c",
"raw_bytes": 65706
},
{
"repository": "0xlillith/solidcraft",
"ref": "d8e7a8690a30e44a58255e5dd345881ef092a93a",
"path": "crates/io/src/sketch2d.rs",
"github_blob": "df0e587174ee9d320d27448d5821460056e99dfe",
"raw_sha256": "12a4849c596a9c7fdf2cc61f54d814ecb517344eefc00782604b6d81e0d5ab79",
"raw_bytes": 2118
},
{
"repository": "grumpydevorg/solidcraft",
"ref": "f9146cdd5887af90b0999c8dbd8f4fb8ae0f7f18",
"path": "crates/io/src/dxf.rs",
"github_blob": "7defb594c9a0243e9f512c0657e39bdc698a4679",
"raw_sha256": "b5262f6d8834dd228d6914c045d5ba8a4382646027b1c790e79dc70d25c6f90c",
"raw_bytes": 30913
},
{
"repository": "grumpydevorg/solidcraft",
"ref": "2edca81fef00da8e8cd43fbc77ad1dfebff350ee",
"path": "crates/io/src/dxf.rs",
"github_blob": "e83d1c871cf5ce26bedc521dfbefadd352d253b8",
"raw_sha256": "2657aeef153d79d6df5ce9b02211cf116c1334eb2f05aca1b7ba6acbe3d8dfa1",
"raw_bytes": 35083
},
{
"repository": "grumpydevorg/solidcraft",
"ref": "2edca81fef00da8e8cd43fbc77ad1dfebff350ee",
"path": "crates/io/src/sketch2d.rs",
"github_blob": "57d6fa770a0c70e1c7363b33bf4e9eb716886c51",
"raw_sha256": "52bbac5fa0986e6f0edbddaff25e34c7ed0345f1e16c7dac872bf986aa5bd57b",
"raw_bytes": 4689
},
{
"repository": "grumpydevorg/solidcraft",
"ref": "2edca81fef00da8e8cd43fbc77ad1dfebff350ee",
"path": "crates/sketch/src/lib.rs",
"github_blob": "f7d084f3d691c27bec87faae09963d650aab452c",
"raw_sha256": "0c1359616ff78ea4bc2dcb5ece717425aa98e58335376b8da6a636cedfabf636",
"raw_bytes": 4461
},
{
"repository": "grumpydevorg/solidcraft",
"ref": "2edca81fef00da8e8cd43fbc77ad1dfebff350ee",
"path": "crates/sketch/src/curves.rs",
"github_blob": "62038844cf4b0745df74d4ea094145c93b3b3d35",
"raw_sha256": "96f5a74716d9f9a9d65c676b7c7b9552b0e7a653b7510ab5073be79e5a75c614",
"raw_bytes": 30654
},
{
"repository": "grumpydevorg/solidcraft",
"ref": "2edca81fef00da8e8cd43fbc77ad1dfebff350ee",
"path": "crates/doc/src/lib.rs",
"github_blob": "0a750d01bc7384c7bd27ec98cc944c77f2cb19e6",
"raw_sha256": "fe314ef5b1e32691b6f4c4cd2e2cb31423decb14342192b52a5c2cdab40c37c3",
"raw_bytes": 4027
}
],
"product_path": "crates/io/src/dxf.rs",
"adapter_scope": "existing inline cfg(test) only",
"prior_test_bodies_preserved": 84,
"new_test_cases_unrun": 7,
"compiled": false,
"tests_run": false
}
+4
View File
@@ -63,3 +63,7 @@ real emitted-content coverage, PDF readers and actual validation remain pending.
## 2026-10-31: combined X1 source reconciliation
[Eleven-path X1 alternative](2026-10-31/x1-combined-source-reconciliation/README.md) combines nine original prerequisite candidates with the exact already archived two-file parent, preserving foreign source, generic contracts, 53 pins and 117+25 source test declarations. Apply its sole combined delta once to frozen main, never sequentially after the parent. Two absent paths are explicit /dev/null additions. Source-only/uncompiled/unrun; lock resolution and whole-workspace API validation remain pending. No readiness or result transfer.
## Conditional X3 SPLINE acceptance — source only, 31 October
[Exact before/candidate, owned appendix and integration conditions](2026-10-31/x3-spline-projection/README.md). A test-only adapter consumes the real layered SPLINE fields through rmorgans' pending #9356 factory, with explicit Option::None refusal. Four exact owner hunks remain attributed and untouched; the other five owner paths are prerequisites, not co-ported. Seven original analytical tests are UNRUN; all 84 existing inline bodies and production routing/TEXT/INSERT are preserved. This does not complete X3, integrate #9356 or establish compiler/test readiness.