Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1e32033
WIP: Enforce complexity/linearity lens family whole-corpus (audit-first)
briansrls Jun 29, 2026
6fec541
Link roadmap authority to complexity/linearity family audit plan.
briansrls Jun 29, 2026
639a827
Replace design-doc audit with parse-only whole-corpus harness.
briansrls Jun 29, 2026
d359364
Fix CI: construction_justification on audit lens and rustfmt.
briansrls Jun 29, 2026
037fe55
Fix regen_verify gate: wire audit builtins through stage0 authority.
briansrls Jun 29, 2026
2777bfa
Elevate roster-fiction quantification and eval-interpreter triage in …
briansrls Jun 29, 2026
93f8732
Fix CI OOM: stream decl_facts audit walk and slim witness cache.
briansrls Jun 30, 2026
2f8f2ab
Address #33374 review: triage cleanup, dissolution markers, cache docs.
briansrls Jun 30, 2026
11e9c87
Add SCAFFOLD receipts for complexity/linearity audit hand-Rust bridge.
briansrls Jun 30, 2026
05b2fe5
Address #33390 review: document gate-promotion predicate requirement.
briansrls Jun 30, 2026
bee8ff7
Revert accidental Wave 1 grammar-ladder fold from #5967.
briansrls Jun 30, 2026
2a34474
Add irreducible residue catalogue for operator permanent sign-off.
briansrls Jun 30, 2026
8181724
Fix CI: wire irreducible residue catalogue into ROADMAP reachability.
briansrls Jun 30, 2026
7bef4b7
Complete syntactic audit triage: classify 278 pending sites to zero.
briansrls Jun 30, 2026
d65e9d8
Add real-debt syntactic sample audit for honest N=318 headline.
briansrls Jun 30, 2026
471b70a
Fix CI: wire real-debt syntactic sample audit into ROADMAP.
briansrls Jun 30, 2026
7ec53ef
Fix CI: rustfmt drift in audit and roster partition files.
briansrls Jun 30, 2026
15552f9
Ground syntactic triage on closed-coproduct filter; enroll 6 sites.
briansrls Jun 30, 2026
b2ed506
Remove dead is_open_domain_site after closed-coproduct triage.
briansrls Jun 30, 2026
a18e775
Wave 1 PROPOSE: exhaustive terminal table for grammar-ladder fns. (#5…
gunbai-bot[bot] Jun 30, 2026
3ce812d
Fix CI: remove illegal // comments from .dag lens and witnesses.
briansrls Jun 30, 2026
47ee16f
Reconcile ROADMAP-linked docs with landed closed-coproduct triage.
briansrls Jun 30, 2026
c2c1580
Fix N=29 stale headline in sample-audit doc (now N=24).
briansrls Jun 30, 2026
946513a
Simplify dead branch in coproduct name scanner.
briansrls Jun 30, 2026
c541652
Fix ROADMAP.md generated-artifact drift for erg-nonfold-audit carriers.
briansrls Jun 30, 2026
e25b1ff
Remove dead triage_wildcard substring backstops; document triage_comp…
briansrls Jun 30, 2026
c6c1238
Retrigger CI after runner rustup/sccache infra flake on 20847c7.
briansrls Jun 30, 2026
42ba5ab
Fix rustfmt drift in stage0 audit modules after main rebase.
briansrls Jun 30, 2026
a083400
Fix rebase fallout: dedupe cli_run imports and rustfmt after main merge.
briansrls Jun 30, 2026
a0bcd36
Remove dead corpus_dag_files helpers after module_path_index migration.
briansrls Jun 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Why a tier: **"it compiles but nothing works" traces to non-fold residue** — a
**Audit half — measure the friction + the residue (decidable; wall-able):**

- [ ] **inert-abstraction lens** *(keystone)* — flag any item *defined + self-tested + zero non-test consumers*; generalizes the inert-lens backstop (#5433) from lenses to all carriers. **First RED witness = `Placement` / `Materialization` / `RealizationObjective`** (charter §4: "modeled + witness-passing, no non-test consumer") — a genuinely-inert carrier the lens *fires* on day one, so the lens isn't itself inert (its own §6 guardrail). (`cached_stage` is the *resolved* case — now wired, see Fix half — so it's the worked example, not the witness.)
- [ ] **non-fold-residue audit** — `_ =>` catch-alls over *closed* coproducts · `unwrap_or_default` in inference · hand-rolled recursion where a fold exists. These are the decidable fail-open shapes → §0 wall candidates, not just lenses
- [ ] **non-fold-residue audit** — `_ =>` catch-alls over *closed* coproducts · `unwrap_or_default` in inference · hand-rolled recursion where a fold exists. These are the decidable fail-open shapes → §0 wall candidates, not just lenses [irreducible residue catalogue](docs/plans/non-fold-irreducible-residue-catalogue.md) [real-debt syntactic sample audit](docs/plans/real-debt-syntactic-sample-audit.md)
- [ ] **fold-friction audit** — what makes the fold awkward to reach (the #5512 pre-state: generic fn-params mis-inferred as kernel `Witness`/`Optional`, forcing typed-param workarounds) — the friction predicts where new residue appears

**Fix half — make the fold the path of least resistance:**
Expand Down
182 changes: 182 additions & 0 deletions docs/plans/non-fold-irreducible-residue-catalogue.md

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions docs/plans/real-debt-syntactic-sample-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Syntactic audit triage — headline-number honesty

**Lane:** nimble-ibex-655
**As-of:** 2026-06-30, HEAD `1f5d517f7b`
**Audience:** loyal-bee-794 / operator scope sign-off

## Executive summary (current code)

**The path-heuristic `real-debt` / `open-domain` site classifiers are retired from `triage_wildcard`.** `complexity_linearity_audit_project.rs` no longer uses `is_real_debt_site` or `is_open_domain_site`. Syntactic triage is grounded on **closed-coproduct param resolution** at the AST walk:

**Residual emit-only path buckets:** `triage_complexity` (used only by `syntactic_high_match_fanout` cost findings, not floor gates) still partitions by `starts_with("dsl/extdeps/")` / `dsl/std/` etc. — scaffold residue named in dissolution trigger #2; delete on `#5966` on-carrier swap.

1. Any `match` with a top-level `_ =>` arm is a syntactic finding.
2. `triage_wildcard(site, fn_name, has_closed_coproduct_wildcard)` gates on whether the scrutinee is a **bare fn param** whose declared type head is in the corpus closed-coproduct index (`fn_param_type_heads` + `non_fold_residue_closed_coproduct_type_names()`).
3. If not closed-coproduct → **`open-domain`** (legitimate wildcards over open/primitive domains — permanently out of the elimination wave).
4. If closed-coproduct + on migration roster → **`migration-debt`**; + on irreducible roster → **`kernel-permanent`**; + off roster → **`closed-coproduct-debt`** (must drain or enroll — §5 invariant).

**Resolved-half authority** (floor gate): `non_fold_residue_project::residue_sites` — conservative bare-param + closed-coproduct-type + top-level `_ =>`.

| Metric | Count | Authority |
|--------|------:|-----------|
| Full exception roster slots | **76** | `NON_FOLD_RESIDUE_ROSTER.len()` |
| Migration-debt roster slots | **24** | `NON_FOLD_MIGRATION_DEBT_ROSTER.len()` |
| Irreducible roster slots | **52** | **76 − 24** |
| Live closed-coproduct sites (resolved) | **76/76** rostered | `non_fold_residue_unrostered_count() == 0` |
| Syntactic wildcard findings (whole corpus) | **392** | Parse-only AST walk |
| On-roster syntactic wildcards | **76** | Same set as resolved half |
| Off-roster syntactic wildcards | **316** | All tagged **`open-domain`** |
| **`closed-coproduct-debt` (unrostered)** | **0** | §5 invariant — nothing hidden from floor |

**Operator headline (locked):** **N=24** migration-debt roster slots to drain (closed-coproduct fail-opens on `NON_FOLD_MIGRATION_DEBT_ROSTER`); **316** open-domain stay permanently out. Prior **N=29** count superseded after grammar-ladder Wave 1 (−5 roster) and roster reconciliation on HEAD. **N=318** (`real-debt=294` + path heuristics) is **retired**.

---

## Discriminator comparison (landed)

### A) `open-domain` (316 sites) — closed-coproduct filter

Wildcard `match` where scrutinee is **not** a closed-coproduct fn param (open `Node`/`String`, field access, nested match, extdeps witness parsers, etc.). **Not** elimination-wave scope.

### B) Resolved-half roster (76 sites) — construction-grade

`non_fold_residue` census: bare-param + declared closed-coproduct type + top-level `_ =>`. Partition: **24 migration-debt** (drain) + **52 irreducible** (permanent sign-off catalogue).

### C) Syntactic triage tags (emit-only TSV)

| Tag | Live count (2026-06-30) | Meaning |
|-----|------------------------:|---------|
| `open-domain` | 316 | Not closed-coproduct-param wildcards |
| `migration-debt` | 24 | On `NON_FOLD_MIGRATION_DEBT_ROSTER` |
| `kernel-permanent` | 52 | On irreducible roster |
| `closed-coproduct-debt` | 0 | Unrostered closed-coproduct — must stay at 0 |
| `eval-interpreter-debt` / `grammar-ladder-debt` | 0 | **Removed** — were dead substring backstops after roster partition; roster bucket is authoritative |

### D) Superseded (do not cite)

- `is_real_debt_site` / `is_open_domain_site` path-prefix heuristics — **removed**.
- `real-debt=294` headline — **retired** (pre closed-coproduct filter).
- “Pending closed-coproduct filter” — **landed** in `triage_wildcard` (`complexity_linearity_audit_project.rs:267-304`).

---

## Sample spot-check (closed-coproduct-grounded)

| # | Site | Closed-coproduct? | Roster bucket | Syntactic tag |
|---|------|-------------------|---------------|---------------|
| 1 | `src/v2/lens/testgen.dag::testgen_emit_language_behavior_equivalence_claim` | Yes (`ManualAnchorKey`) | migration-debt | migration-debt |
| 2 | `src/v2/compiler/01_tokenize.dag::lex_try_rules_prefer_longer` | Yes | migration-debt | migration-debt |
| 3 | `dsl/extdeps/cron/schedule_model.dag::render_cron_field` | No | — | open-domain |
| 4 | `src/v2/lens/cost.dag::asymptotic_class_dominates` | Yes | irreducible | kernel-permanent |
| 5 | `dsl/tools/generated_artifact_gate.dag::exit_ok` | Yes | irreducible | kernel-permanent |

Witness: `syntactic_audit_witness_test.dag` executes interpreter builtins over witness roots; site-pinned rows are intentional dissolution ratchets.

---

## Drain lane (unchanged)

Grammar-ladder Wave 1 (-5 roster, exhaustive `ConcreteSyntaxToken` arms) and eval_bind PROPOSE are separate escalate-review PRs. This doc tracks **census honesty** only; roster edits land in the same PR as the fold.
2 changes: 1 addition & 1 deletion dsl/gunbc/roadmap_authority.dag
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ fn section_ergonomics_lane() -> RoadmapSection {
label: "Audit half — measure the friction + the residue (decidable; wall-able)",
nodes: [
authored(id: "erg-inert-lens", done: false, content: "**inert-abstraction lens** *(keystone)* — flag any item *defined + self-tested + zero non-test consumers*; generalizes the inert-lens backstop (#5433) from lenses to all carriers. **First RED witness = `Placement` / `Materialization` / `RealizationObjective`** (charter §4: \"modeled + witness-passing, no non-test consumer\") — a genuinely-inert carrier the lens *fires* on day one, so the lens isn't itself inert (its own §6 guardrail). (`cached_stage` is the *resolved* case — now wired, see Fix half — so it's the worked example, not the witness.)"),
authored(id: "erg-nonfold-audit", done: false, content: "**non-fold-residue audit** — `_ =>` catch-alls over *closed* coproducts · `unwrap_or_default` in inference · hand-rolled recursion where a fold exists. These are the decidable fail-open shapes → §0 wall candidates, not just lenses"),
authored_pp(id: "erg-nonfold-audit", done: false, content: "**non-fold-residue audit** — `_ =>` catch-alls over *closed* coproducts · `unwrap_or_default` in inference · hand-rolled recursion where a fold exists. These are the decidable fail-open shapes → §0 wall candidates, not just lenses", carriers: [ptr(label: "irreducible residue catalogue", path: "docs/plans/non-fold-irreducible-residue-catalogue.md"), ptr(label: "real-debt syntactic sample audit", path: "docs/plans/real-debt-syntactic-sample-audit.md")]),
authored(id: "erg-friction-audit", done: false, content: "**fold-friction audit** — what makes the fold awkward to reach (the #5512 pre-state: generic fn-params mis-inferred as kernel `Witness`/`Optional`, forcing typed-param workarounds) — the friction predicts where new residue appears"),
],
edges: [],
Expand Down
3 changes: 3 additions & 0 deletions src/v1/04_method.dag
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ fn builtin_function_registry() -> Map<String, Node> {
let m = map_insert(m, "non_fold_residue_unrostered_count", int_type)
let m = map_insert(m, "non_fold_residue_stale_roster_count", int_type)
let m = map_insert(m, "non_fold_residue_coproduct_universe_count", int_type)
let m = map_insert(m, "complexity_linearity_syntactic_finding_count", int_type)
let m = map_insert(m, "complexity_linearity_syntactic_wildcard_finding_count", int_type)
let m = map_insert(m, "complexity_linearity_syntactic_site_fired", bool_type)
let m = map_insert(m, "census_corpus_roots_follow_layer_authority", bool_type)
let m = map_insert(m, "transport_script_literal_violation_count_for_path", int_type)
let m = map_insert(m, "layer_import_facts", list_of_type_variable(id: "layer_import_fact_elem"))
Expand Down
2 changes: 1 addition & 1 deletion src/v1/05_emit_rust.dag
Original file line number Diff line number Diff line change
Expand Up @@ -1684,7 +1684,7 @@ fn emit_lib_rs_from_files(all_module_files: List<TextFile>, has_compiler_tests:
)

let hand_maintained_mods = if has_compiler_tests {
"\npub mod v1_interpreter;\npub mod cli_run;\npub mod rest_transport_facts;\npub mod wire_value_serialize;\npub mod coproduct_reflection;\npub mod resolved_graph_cache;\npub mod recorded_fixture;\npub mod doc_reachability_project;\npub mod inert_carrier_project;\npub mod medium_structure_project;\npub mod extdeps_shape_transport_policy_project;\npub mod fact_cardinality_census;\npub mod languages_consumer_census;\npub mod non_fold_residue_project;\npub mod transport_script_position_project;\npub mod v1_compiler_dag_collect;\npub mod v1_compiler_dag_collect_support;"
"\npub mod v1_interpreter;\npub mod cli_run;\npub mod complexity_linearity_audit_project;\npub mod rest_transport_facts;\npub mod wire_value_serialize;\npub mod coproduct_reflection;\npub mod resolved_graph_cache;\npub mod recorded_fixture;\npub mod doc_reachability_project;\npub mod inert_carrier_project;\npub mod medium_structure_project;\npub mod extdeps_shape_transport_policy_project;\npub mod fact_cardinality_census;\npub mod languages_consumer_census;\npub mod non_fold_residue_project;\npub mod transport_script_position_project;\npub mod v1_compiler_dag_collect;\npub mod v1_compiler_dag_collect_support;"
} else {
""
}
Expand Down
10 changes: 10 additions & 0 deletions src/v1/stage0/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ path = "src/bin/v1_src_dag_parse.rs"
name = "wiring_liveness_whole_tree"
path = "src/bin/wiring_liveness_whole_tree.rs"

# SCAFFOLD — emit-only whole-corpus audit for complexity/linearity lens family (SYNTACTIC half).
# ROADMAP §3 `3-gates-whole` ("complexity budget gates the whole codebase"); audit-first bridge
# until `decl_facts(roots)` host builtin (#5966) grounds fn-body reflection. Parse-only walk over
# witness_layer_roots; NOT floor-enrolled — prints findings TSV, exit 0 unless --fail-on-findings.
# DISSOLUTION: swap stub for decl_facts(roots), move triage roster on-carrier, fold into pure .dag
# reader (gunbc#5364), then enroll floor gate.
[[bin]]
name = "complexity_linearity_audit"
path = "src/bin/complexity_linearity_audit.rs"

[[bin]]
name = "measure_whole_tree_resolve"
path = "src/bin/measure_whole_tree_resolve.rs"
Expand Down
133 changes: 133 additions & 0 deletions src/v1/stage0/src/bin/complexity_linearity_audit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#![allow(clippy::disallowed_macros)]

//! SCAFFOLD — emit-only whole-corpus audit for the complexity/linearity lens family (SYNTACTIC half).
//!
//! ROADMAP §3 `3-gates-whole` ("complexity budget gates the whole codebase"); audit-first bridge
//! until `decl_facts(roots)` host builtin (#5966) grounds fn-body reflection. Parse-only walk over
//! `witness_layer_roots` using `decl_facts_parse_only` stub.
//!
//! NOT floor-enrolled. Prints `site`, `lens`, `rule`, `triage` (TSV). Exit 0 unless
//! `--fail-on-findings` (for discriminating tests).
//!
//! DISSOLUTION: swap stub for `decl_facts(roots)`, move triage roster on-carrier, fold SYNTACTIC
//! projections into a pure `.dag` reader (gunbc#5364), then enroll floor gate.

use std::process::ExitCode;

use v1_compiler::complexity_linearity_audit_project::{
audit_corpus_default_roots, audit_corpus_parse_only, roster_fiction_report,
};
use v1_compiler::inert_carrier_project::{inert_carrier_count, inert_carrier_unrostered_count};
use v1_compiler::non_fold_residue_project::{
non_fold_residue_count, non_fold_residue_irreducible_roster_slots,
non_fold_residue_migration_debt_roster_slots, non_fold_residue_unrostered_count,
};

fn require_value(args: &[String], idx: usize, flag: &str) -> Result<String, ExitCode> {
match args.get(idx) {
Some(v) => Ok(v.clone()),
None => {
eprintln!("complexity_linearity_audit: {flag} requires a value");
Err(ExitCode::from(2))
}
}
}

fn run() -> Result<ExitCode, ExitCode> {
let args: Vec<String> = std::env::args().collect();
let mut source_roots: Vec<String> = Vec::new();
let mut fail_on_findings = false;

let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--source-root" => {
i += 1;
source_roots.push(require_value(&args, i, "--source-root")?);
}
"--fail-on-findings" => fail_on_findings = true,
other => {
eprintln!("complexity_linearity_audit: unknown argument: {other}");
return Err(ExitCode::from(2));
}
}
i += 1;
}

if source_roots.is_empty() {
return print_summary(&audit_corpus_default_roots(), fail_on_findings);
}

print_summary(&audit_corpus_parse_only(&source_roots), fail_on_findings)
}

fn print_summary(
summary: &v1_compiler::complexity_linearity_audit_project::AuditSummary,
fail_on_findings: bool,
) -> Result<ExitCode, ExitCode> {
eprintln!(
"complexity_linearity_audit: scanned {} file(s), parsed {}, {} fn(s), {} syntactic finding(s)",
summary.files_scanned,
summary.files_parsed,
summary.fns_scanned,
summary.findings.len()
);
eprintln!(
"complexity_linearity_audit: resolved-half roster proxies (not whole-corpus): \
non_fold_residue total={} unrostered={}, inert_carrier total={} unrostered={}",
non_fold_residue_count(),
non_fold_residue_unrostered_count(),
inert_carrier_count(),
inert_carrier_unrostered_count()
);
let fiction = roster_fiction_report(summary);
eprintln!(
"complexity_linearity_audit: ROSTER-FICTION — (a) MIGRATION-DEBT: {}/{} live on roster \
(floor RED on {} if migration roster fiction dropped); \
(b) IRREDUCIBLE: {}/{} honest permanent residue (operator-signed); \
unrostered today: {}",
fiction.migration_debt_live,
non_fold_residue_migration_debt_roster_slots(),
fiction.floor_red_if_migration_roster_fiction_dropped,
fiction.irreducible_live,
non_fold_residue_irreducible_roster_slots(),
fiction.resolved_unrostered_sites
);
eprintln!(
"complexity_linearity_audit: syntactic wildcard arms — total={} on_roster={} off_roster={} \
| triage: eval-interpreter-debt={} grammar-ladder-debt={} kernel-permanent={} \
migration-debt={} closed-coproduct-debt={} open-domain={} triage-pending={}",
fiction.syntactic_wildcard_total,
fiction.syntactic_wildcard_on_roster,
fiction.syntactic_wildcard_off_roster,
fiction.eval_interpreter_debt,
fiction.grammar_ladder_debt,
fiction.kernel_permanent,
fiction.migration_debt_tagged,
fiction.closed_coproduct_debt,
fiction.open_domain,
fiction.triage_pending
);
let cost_findings = summary.findings.iter().filter(|f| f.lens == "cost").count();
eprintln!(
"complexity_linearity_audit: cost syntactic proxy (Node.body walk) — \
syntactic_high_match_fanout={} site(s) (full cost_lens on DeclFact.node.body pending #5364)",
cost_findings
);
eprintln!("site\tlens\trule\ttriage");
for f in &summary.findings {
println!("{}\t{}\t{}\t{}", f.site, f.lens, f.rule, f.triage);
}

if fail_on_findings && !summary.findings.is_empty() {
return Ok(ExitCode::from(1));
}
Ok(ExitCode::SUCCESS)
}

fn main() -> ExitCode {
match run() {
Ok(code) => code,
Err(code) => code,
}
}
25 changes: 25 additions & 0 deletions src/v1/stage0/src/bin/regen_stage0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ const GENERATED_STAGE0_FILES: &[&str] = &[

const HAND_MAINTAINED_STAGE0_FILES: &[&str] = &[
"cli_run.rs",
"complexity_linearity_audit_project.rs",
"decl_facts_project.rs",
"coproduct_reflection.rs",
"doc_reachability_project.rs",
"inert_carrier_project.rs",
Expand Down Expand Up @@ -349,6 +351,9 @@ fn run() -> Result<(), String> {
time_phase(&mut phases, "patch_languages_consumer_census_mod", || {
patch_languages_consumer_census_mod(&fresh_dir.join("src"))
})?;
time_phase(&mut phases, "patch_complexity_linearity_audit_mod", || {
patch_complexity_linearity_audit_mod(&fresh_dir.join("src"))
})?;
time_phase(&mut phases, "assert_bootstrap_emit_core_support", || {
assert_bootstrap_emit_core_support(&fresh_dir.join("src"))
})?;
Expand Down Expand Up @@ -838,6 +843,26 @@ fn patch_languages_consumer_census_mod(src_dir: &Path) -> Result<(), String> {
Ok(())
}

fn patch_complexity_linearity_audit_mod(src_dir: &Path) -> Result<(), String> {
let lib_path = src_dir.join("lib.rs");
let mut lib_text =
fs::read_to_string(&lib_path).map_err(|e| format!("read {}: {e}", lib_path.display()))?;
if !lib_text.contains("pub mod complexity_linearity_audit_project;") {
lib_text = lib_text.replace(
"pub mod cli_run;\n",
"pub mod cli_run;\npub mod complexity_linearity_audit_project;\n",
);
}
if !lib_text.contains("pub mod decl_facts_project;") {
lib_text = lib_text.replace(
"pub mod complexity_linearity_audit_project;\n",
"pub mod complexity_linearity_audit_project;\npub mod decl_facts_project;\n",
);
}
fs::write(&lib_path, lib_text).map_err(|e| format!("write {}: {e}", lib_path.display()))?;
Ok(())
}

fn assert_bootstrap_emit_core_support(src_dir: &Path) -> Result<(), String> {
let support_path = src_dir.join("v1_compiler_emit_core_support.rs");
let support_text = fs::read_to_string(&support_path)
Expand Down
Loading