Merge main into copilot/sub-pr-24: integrate fractal algorithmic spine into workspace#27
Merged
tikazyq merged 7 commits intoclaude/decouple-eval-framework-GIOVKfrom Mar 19, 2026
Conversation
…gorithms for structure Replace AI subagent calls with classical algorithms wherever the operation is structurally decidable. Adds TF-IDF cosine similarity (replaces Jaccard), Kahn's topological sort (cycle detection + solve scheduling), git merge-tree reunification, greedy set cover pruning, and complexity scoring. AI is now reserved for semantic operations only: decompose, solve, conflict resolution. New scripts: - solve_scheduler.py: DAG-based critical path scheduling into parallel waves - reunify_merge.py: git 3-way merge + structural conflict detection - prune_gate.py: set cover redundancy analysis Enhanced: - decompose_gate.py: TF-IDF, cycle detection, complexity scoring, budget allocation - SKILL.md: algorithmic spine design principle + updated orchestration protocol Spec: 047-fractal-algorithmic-spine https://claude.ai/code/session_01Gpuehvo6XBmDyQeCQS142c
Replace Python scripts (.harness/scripts/) with native Rust modules (cli/src/fractal/) and a new `synodic fractal` CLI subcommand. Modules: - fractal/decompose.rs: TF-IDF cosine similarity via rust-tfidf crate, combined with Jaccard pre-filter for orthogonality. Kahn's topological sort for cycle detection. Weighted feature scoring for complexity. Proportional budget allocation. - fractal/schedule.rs: DAG-based BFS layer decomposition for solve wave scheduling. Critical path analysis via longest-path DP. - fractal/reunify.rs: git merge-tree 3-way merge for code reunification. Set intersection for boundary/redundancy/gap detection. - fractal/prune.rs: Greedy set cover for minimal covering set. Subset detection and identical output pairing. CLI subcommands: synodic fractal gate — decompose validation synodic fractal schedule — solve wave scheduling synodic fractal reunify — code reunification analysis synodic fractal prune — redundancy detection synodic fractal complexity — standalone complexity scoring 60 tests pass (28 new fractal tests + 32 existing). https://claude.ai/code/session_01Gpuehvo6XBmDyQeCQS142c
Comprehensive docs/FRACTAL.md covering: - Architecture flowchart (ASCII) showing algorithmic spine vs AI calls - AI vs algorithm split diagram with call count comparison - Visual breakdowns for each gate (decompose, solve, reunify, prune) - Complexity scoring weight visualization - Wave scheduling example with dependency graph - Conflict classification table - Node status lifecycle diagram - CLI reference with input/output JSON examples - Algorithm table with complexity classes - Classical algorithm analog mapping - Governance integration checkpoint diagram - Test coverage matrix https://claude.ai/code/session_01Gpuehvo6XBmDyQeCQS142c
Co-authored-by: tikazyq <3393101+tikazyq@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Spec: Decouple eval framework as standalone testing tool
Merge main into copilot/sub-pr-24: integrate fractal algorithmic spine into workspace
Mar 19, 2026
tikazyq
approved these changes
Mar 19, 2026
There was a problem hiding this comment.
Pull request overview
Merges main into a workspace-restructured branch and integrates the Fractal “algorithmic spine” into the synodic CLI crate, replacing the prior Python decompose gate with Rust subcommands and updating associated docs/specs.
Changes:
- Adds
synodic fractalCLI subcommands (gate,schedule,reunify,prune,complexity) and wires them into thesynodicbinary. - Introduces Rust implementations for structural validation/scheduling/reunification/pruning, and adds
rust-tfidfas a dependency. - Updates Fractal documentation/specs to describe the new algorithmic spine and CLI-based protocol; removes the old Python gate script.
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
cli/synodic/src/main.rs |
Adds the Fractal CLI entrypoint and routes it to the new command module. |
cli/synodic/src/cmd/mod.rs |
Exposes the new fractal command module. |
cli/synodic/src/cmd/fractal.rs |
Implements synodic fractal subcommand parsing + stdin/file input handling. |
cli/synodic/src/fractal/mod.rs |
Adds shared types + term/Jaccard utilities used by the algorithmic spine. |
cli/synodic/src/fractal/decompose.rs |
Implements TF-IDF orthogonality, cycle detection, complexity scoring, and budget allocation. |
cli/synodic/src/fractal/schedule.rs |
Implements DAG wave scheduling and critical path analysis for solves. |
cli/synodic/src/fractal/reunify.rs |
Implements structural conflict detection and git merge-tree based reunify analysis. |
cli/synodic/src/fractal/prune.rs |
Implements redundancy detection using subset checks and greedy set cover. |
cli/synodic/Cargo.toml |
Adds rust-tfidf dependency required by the TF-IDF gate. |
cli/Cargo.lock |
Locks rust-tfidf and its dependency entry for synodic. |
skills/fractal/SKILL.md |
Updates the orchestration protocol to use the new Rust CLI subcommands. |
docs/README.md |
Adds an entry for the new Fractal documentation. |
docs/FRACTAL.md |
Adds comprehensive Fractal + algorithmic spine documentation and CLI reference. |
specs/047-fractal-algorithmic-spine/README.md |
Adds the design spec describing the algorithmic spine and intended behaviors. |
.harness/scripts/decompose_gate.py |
Removes the legacy Python decompose gate script (replaced by Rust CLI). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+338
to
+346
| let enumeration_count = lines | ||
| .iter() | ||
| .filter(|l| { | ||
| let trimmed = l.trim(); | ||
| trimmed.starts_with("- ") | ||
| || trimmed.starts_with("* ") | ||
| || regex::Regex::new(r"^\d+\.") | ||
| .unwrap() | ||
| .is_match(trimmed) |
|
|
||
| let end_node = longest | ||
| .iter() | ||
| .max_by_key(|(_, &len)| len) |
Comment on lines
+308
to
+326
| for slug in &merge_order { | ||
| if let Some(child) = children_by_slug.get(slug.as_str()) { | ||
| if let Some(merge_result) = try_merge_tree(&input.base_ref, child) { | ||
| if !merge_result.clean { | ||
| for conflict in merge_result.conflicts { | ||
| if needs_ai_resolution(&conflict) { | ||
| all_conflicts.push(conflict); | ||
| } else { | ||
| auto_resolved.push(AutoResolved { | ||
| description: conflict.description, | ||
| child: slug.clone(), | ||
| resolution: "auto".to_string(), | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
Comment on lines
+617
to
+624
| ``` | ||
| cli/src/ | ||
| ├── fractal/ | ||
| │ ├── mod.rs # shared types, NLP utilities (extract_terms, jaccard) | ||
| │ ├── decompose.rs # TF-IDF gate, cycle detection, complexity, budget | ||
| │ ├── schedule.rs # DAG wave scheduling, critical path | ||
| │ ├── reunify.rs # git merge-tree, structural conflict detection | ||
| │ └── prune.rs # set cover, subset/identity detection |
Comment on lines
+393
to
+406
| All algorithms are implemented in Rust as `synodic fractal` CLI subcommands | ||
| (`cli/src/fractal/`), using the `rust-tfidf` crate for proper TF-IDF computation. | ||
|
|
||
| | Module | CLI Command | Algorithms | | ||
| |--------|-------------|------------| | ||
| | `fractal/decompose.rs` | `synodic fractal gate` | TF-IDF cosine (via `rust-tfidf`), Jaccard pre-filter, Kahn's toposort, complexity scoring, budget allocation | | ||
| | `fractal/schedule.rs` | `synodic fractal schedule` | BFS layer decomposition, critical path DP | | ||
| | `fractal/reunify.rs` | `synodic fractal reunify` | git merge-tree 3-way merge, set intersection conflict detection | | ||
| | `fractal/prune.rs` | `synodic fractal prune` | Greedy set cover, subset detection | | ||
| | `fractal/mod.rs` | (shared) | Term extraction, Jaccard similarity, type definitions | | ||
| | `cmd/fractal.rs` | (CLI dispatch) | stdin/file JSON input, pretty JSON output | | ||
|
|
||
| Tests: 28 fractal-specific tests covering orthogonality detection, cycle detection, | ||
| wave scheduling, diamond dependencies, conflict detection, set cover, and budget allocation. |
|
|
||
| use std::collections::{HashMap, HashSet, VecDeque}; | ||
|
|
||
| use tfidf::{TfIdf, TfIdfDefault}; |
Comment on lines
+124
to
+127
| // Pick node covering most uncovered files | ||
| let best = remaining | ||
| .iter() | ||
| .max_by_key(|(_, files)| files.difference(&covered).count()) |
Comment on lines
+82
to
+119
| /// Detect boundary violations: child modified files outside its scope. | ||
| fn check_scope_violations(children: &[ReunifyChild]) -> Vec<Conflict> { | ||
| let mut conflicts = Vec::new(); | ||
|
|
||
| for child in children { | ||
| let child_files: std::collections::HashSet<&String> = child.files.iter().collect(); | ||
|
|
||
| for sibling in children { | ||
| if sibling.slug == child.slug { | ||
| continue; | ||
| } | ||
| let sibling_files: std::collections::HashSet<&String> = | ||
| sibling.files.iter().collect(); | ||
| let overlap: Vec<String> = child_files | ||
| .intersection(&sibling_files) | ||
| .map(|f| f.to_string()) | ||
| .collect(); | ||
|
|
||
| if !overlap.is_empty() { | ||
| // Only flag once per pair (alphabetical order) | ||
| if child.slug < sibling.slug { | ||
| conflicts.push(Conflict { | ||
| category: "boundary".to_string(), | ||
| children: vec![child.slug.clone(), sibling.slug.clone()], | ||
| description: format!( | ||
| "Children '{}' and '{}' both modified: {}", | ||
| child.slug, | ||
| sibling.slug, | ||
| overlap.join(", "), | ||
| ), | ||
| files: overlap, | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| conflicts | ||
| } |
| > ## Reunification strategy: {reunification} | ||
| > | ||
| > ## Structural analysis (from algorithmic pre-check) | ||
| > {conflicts detected by reunify_merge.py, if any} |
Comment on lines
+373
to
+376
| return children | ||
| .iter() | ||
| .map(|c| (c.slug.clone(), remaining_budget.min(1) / n.max(1))) | ||
| .collect(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branch had diverged from
mainafter PR #23 landed the fractal algorithmic spine. Three conflicts needed manual resolution to reconcile the eval-decoupling workspace restructure with the new fractal module.Conflict resolutions
cli/Cargo.toml— kept workspace format (synodic+synodic-evalmembers); discarded main's single-package definitioncli/synodic/src/main.rs— combinedmod governance;(eval decoupling) withmod fractal;(from main)cli/src/fractal/(old single-package path); moved tocli/synodic/src/fractal/to match workspace structurecli/synodic/Cargo.toml— addedrust-tfidf = "1"required by the fractal module🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.