phase29ao(p31): ssot shadow adopt routing in composer
This commit is contained in:
@ -18,9 +18,13 @@ Scope: Repo root の旧リンク互換。現行の入口は `docs/development/cu
|
||||
**CorePlan migration 道筋 SSOT**
|
||||
`docs/development/current/main/design/coreplan-migration-roadmap-ssot.md` が移行タスクの Done 判定の入口。
|
||||
|
||||
**Next implementation (Phase 29ao P31)**
|
||||
- 目的: shadow adopt の判定/Fail-Fast/タグを composer に集約し、router を “呼ぶだけ” に縮退(挙動不変)
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P31-REFactor-SHADOW-ADOPT-ROUTER-TO-COMPOSER-SSOT-INSTRUCTIONS.md`
|
||||
**Next implementation (Phase 29ao P32)**
|
||||
- 目的: Pattern2 real-world strict/dev shadow adopt
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P32-STRICT-ADOPT-PATTERN2-REALWORLD-FROM-FACTS-INSTRUCTIONS.md`
|
||||
- After P32: TBD
|
||||
|
||||
**2025-12-30: Phase 29ao P31 COMPLETE (shadow adopt routing SSOT)**
|
||||
shadow adopt の判定/Fail-Fast/タグを composer 側に集約し、router を薄くした(仕様不変)。
|
||||
|
||||
**2025-12-30: Phase 29ao P30 COMPLETE (Shadow adopt composer SSOT)**
|
||||
Facts→CorePlan の入口を `plan/composer` に集約し、Normalizer の責務を DomainPlan→CorePlan に縮退した(挙動不変)。
|
||||
|
||||
@ -2,12 +2,17 @@
|
||||
|
||||
## Current Focus: Phase 29ao(CorePlan composition)
|
||||
|
||||
Next: Phase 29ao P31(shadow adopt routing SSOT)
|
||||
指示書: `docs/development/current/main/phases/phase-29ao/P31-REFactor-SHADOW-ADOPT-ROUTER-TO-COMPOSER-SSOT-INSTRUCTIONS.md`
|
||||
Next: Phase 29ao P32(Pattern2 real-world strict/dev shadow adopt)
|
||||
指示書: `docs/development/current/main/phases/phase-29ao/P32-STRICT-ADOPT-PATTERN2-REALWORLD-FROM-FACTS-INSTRUCTIONS.md`
|
||||
運用ルール: integration filter で phase143_* は回さない(JoinIR 回帰は phase29ae pack のみ)
|
||||
運用ルール: phase286_pattern9_* は legacy pack (SKIP) を使う
|
||||
移行道筋 SSOT: `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md`
|
||||
|
||||
**2025-12-30: Phase 29ao P31 完了** ✅
|
||||
- 目的: shadow adopt の判定/Fail-Fast/タグを composer 側に集約し、router を薄くする(仕様不変)
|
||||
- 変更: `src/mir/builder/control_flow/plan/composer/shadow_adopt.rs` / `src/mir/builder/control_flow/plan/composer/mod.rs` / `src/mir/builder/control_flow/joinir/patterns/router.rs` / `docs/development/current/main/phases/phase-29ao/README.md` / `docs/development/current/main/10-Now.md` / `docs/development/current/main/30-Backlog.md` / `CURRENT_TASK.md` / `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md`
|
||||
- 検証: `cargo build --release` / `./tools/smokes/v2/run.sh --profile quick` / `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh`
|
||||
|
||||
**2025-12-30: Phase 29ao P30 完了** ✅
|
||||
- 目的: Facts→CorePlan の入口を `plan/composer` に集約し、Normalizer の責務を DomainPlan→CorePlan に縮退(挙動不変)
|
||||
- 変更: `src/mir/builder/control_flow/plan/composer/shadow_adopt.rs` / `src/mir/builder/control_flow/plan/composer/mod.rs` / `src/mir/builder/control_flow/joinir/patterns/router.rs` / `src/mir/builder/control_flow/plan/normalizer/pattern2_break.rs` / `src/mir/builder/control_flow/plan/normalizer/pattern3_if_phi.rs` / `src/mir/builder/control_flow/plan/normalizer/pattern5_infinite_early_exit.rs` / `src/mir/builder/control_flow/plan/normalizer/pattern_scan_with_init.rs` / `src/mir/builder/control_flow/plan/normalizer/pattern_split_scan.rs` / `docs/development/current/main/phases/phase-29ao/README.md` / `docs/development/current/main/10-Now.md` / `docs/development/current/main/30-Backlog.md` / `CURRENT_TASK.md` / `docs/development/current/main/design/coreplan-migration-roadmap-ssot.md`
|
||||
|
||||
@ -15,8 +15,8 @@ Related:
|
||||
|
||||
- **Phase 29ao(active): CorePlan composition from Skeleton/Feature**
|
||||
- 入口: `docs/development/current/main/phases/phase-29ao/README.md`
|
||||
- 状況: P0–P30 ✅ 完了 / Next: P31(shadow adopt routing SSOT)
|
||||
- Next 指示書: `docs/development/current/main/phases/phase-29ao/P31-REFactor-SHADOW-ADOPT-ROUTER-TO-COMPOSER-SSOT-INSTRUCTIONS.md`
|
||||
- 状況: P0–P31 ✅ 完了 / Next: P32(Pattern2 real-world strict/dev shadow adopt)
|
||||
- Next 指示書: `docs/development/current/main/phases/phase-29ao/P32-STRICT-ADOPT-PATTERN2-REALWORLD-FROM-FACTS-INSTRUCTIONS.md`
|
||||
|
||||
- **Phase 29af(✅ COMPLETE): Boundary hygiene / regression entrypoint / carrier layout SSOT**
|
||||
- 入口: `docs/development/current/main/phases/phase-29af/README.md`
|
||||
|
||||
@ -34,7 +34,8 @@ Related:
|
||||
## 1.1 Current (active)
|
||||
|
||||
- Active phase: `docs/development/current/main/phases/phase-29ao/README.md`
|
||||
- Next step: `docs/development/current/main/phases/phase-29ao/P31-REFactor-SHADOW-ADOPT-ROUTER-TO-COMPOSER-SSOT-INSTRUCTIONS.md`
|
||||
- Next step: `docs/development/current/main/phases/phase-29ao/P32-STRICT-ADOPT-PATTERN2-REALWORLD-FROM-FACTS-INSTRUCTIONS.md`
|
||||
- After P31: `docs/development/current/main/phases/phase-29ao/P32-STRICT-ADOPT-PATTERN2-REALWORLD-FROM-FACTS-INSTRUCTIONS.md`
|
||||
|
||||
## 2. すでに固めた SSOT(再発防止の土台)
|
||||
|
||||
|
||||
@ -177,13 +177,17 @@ Gate(SSOT):
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P30-MOVE-SHADOW-ADOPT-COMPOSER-SSOT-INSTRUCTIONS.md`
|
||||
- ねらい: Facts→CorePlan の入口を `plan/composer` に集約し、Normalizer の責務を DomainPlan→CorePlan に縮退(挙動不変)
|
||||
|
||||
## P31: shadow adopt routing SSOT(router を薄くする)
|
||||
## P31: shadow adopt routing SSOT(router を薄くする)✅
|
||||
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P31-REFactor-SHADOW-ADOPT-ROUTER-TO-COMPOSER-SSOT-INSTRUCTIONS.md`
|
||||
|
||||
## P32: Pattern2 real-world strict/dev shadow adopt(phase263 をタグ必須で固定)
|
||||
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P32-STRICT-ADOPT-PATTERN2-REALWORLD-FROM-FACTS-INSTRUCTIONS.md`
|
||||
- ねらい: shadow adopt の判定/Fail-Fast/タグを composer に集約し、router を “呼ぶだけ” に縮退(挙動不変)
|
||||
|
||||
## Next(planned)
|
||||
|
||||
- Next: P31(実装)
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P31-REFactor-SHADOW-ADOPT-ROUTER-TO-COMPOSER-SSOT-INSTRUCTIONS.md`
|
||||
- After P31: P32(TBD)
|
||||
- Next: P32(Pattern2 real-world strict/dev shadow adopt)
|
||||
- 指示書: `docs/development/current/main/phases/phase-29ao/P32-STRICT-ADOPT-PATTERN2-REALWORLD-FROM-FACTS-INSTRUCTIONS.md`
|
||||
- After P32: TBD
|
||||
|
||||
@ -336,140 +336,16 @@ pub(crate) fn route_loop_pattern(
|
||||
let strict_or_dev = crate::config::env::joinir_dev::strict_enabled()
|
||||
|| crate::config::env::joinir_dev_enabled();
|
||||
|
||||
if strict_or_dev
|
||||
&& matches!(
|
||||
domain_plan,
|
||||
crate::mir::builder::control_flow::plan::DomainPlan::Pattern1SimpleWhile(_)
|
||||
)
|
||||
{
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern1 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern1_simplewhile.is_none() {
|
||||
return Err("pattern1 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan =
|
||||
composer::compose_coreplan_for_pattern1_simplewhile(builder, facts, ctx)?
|
||||
.ok_or_else(|| {
|
||||
"pattern1 strict/dev adopt failed: skeleton compose rejected".to_string()
|
||||
})?;
|
||||
if let Some(adopt) = composer::try_shadow_adopt_core_plan(
|
||||
builder,
|
||||
ctx,
|
||||
strict_or_dev,
|
||||
&domain_plan,
|
||||
&outcome,
|
||||
)? {
|
||||
let composer::ShadowAdoptOutcome { core_plan, tag } = adopt;
|
||||
PlanVerifier::verify(&core_plan)?;
|
||||
eprintln!("[coreplan/shadow_adopt:pattern1_simplewhile]");
|
||||
return PlanLowerer::lower(builder, core_plan, ctx);
|
||||
}
|
||||
|
||||
if strict_or_dev
|
||||
&& matches!(
|
||||
domain_plan,
|
||||
crate::mir::builder::control_flow::plan::DomainPlan::Pattern3IfPhi(_)
|
||||
)
|
||||
{
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern3 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern3_ifphi.is_none() {
|
||||
return Err("pattern3 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan =
|
||||
composer::compose_coreplan_for_pattern3_ifphi(builder, facts, ctx)?
|
||||
.ok_or_else(|| {
|
||||
"pattern3 strict/dev adopt failed: compose rejected".to_string()
|
||||
})?;
|
||||
PlanVerifier::verify(&core_plan)?;
|
||||
eprintln!("[coreplan/shadow_adopt:pattern3_ifphi]");
|
||||
return PlanLowerer::lower(builder, core_plan, ctx);
|
||||
}
|
||||
|
||||
if strict_or_dev
|
||||
&& matches!(
|
||||
domain_plan,
|
||||
crate::mir::builder::control_flow::plan::DomainPlan::ScanWithInit(_)
|
||||
)
|
||||
&& matches!(
|
||||
outcome.plan.as_ref(),
|
||||
Some(crate::mir::builder::control_flow::plan::DomainPlan::ScanWithInit(_))
|
||||
)
|
||||
{
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern6 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.scan_with_init.is_none() {
|
||||
return Err("pattern6 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = composer::compose_coreplan_for_pattern6_scan_with_init(builder, facts, ctx)?
|
||||
.ok_or_else(|| "pattern6 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
PlanVerifier::verify(&core_plan)?;
|
||||
eprintln!("[coreplan/shadow_adopt:pattern6_scan_with_init]");
|
||||
return PlanLowerer::lower(builder, core_plan, ctx);
|
||||
}
|
||||
|
||||
if strict_or_dev
|
||||
&& matches!(
|
||||
domain_plan,
|
||||
crate::mir::builder::control_flow::plan::DomainPlan::SplitScan(_)
|
||||
)
|
||||
{
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern7 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.split_scan.is_none() {
|
||||
return Err("pattern7 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = composer::compose_coreplan_for_pattern7_split_scan(builder, facts, ctx)?
|
||||
.ok_or_else(|| "pattern7 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
PlanVerifier::verify(&core_plan)?;
|
||||
eprintln!("[coreplan/shadow_adopt:pattern7_split_scan]");
|
||||
return PlanLowerer::lower(builder, core_plan, ctx);
|
||||
}
|
||||
|
||||
if strict_or_dev
|
||||
&& matches!(
|
||||
domain_plan,
|
||||
crate::mir::builder::control_flow::plan::DomainPlan::Pattern5InfiniteEarlyExit(_)
|
||||
)
|
||||
{
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern5 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern5_infinite_early_exit.is_none() {
|
||||
return Err("pattern5 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan =
|
||||
composer::compose_coreplan_for_pattern5_infinite_early_exit(builder, facts, ctx)?
|
||||
.ok_or_else(|| {
|
||||
"pattern5 strict/dev adopt failed: compose rejected".to_string()
|
||||
})?;
|
||||
PlanVerifier::verify(&core_plan)?;
|
||||
eprintln!("[coreplan/shadow_adopt:pattern5_infinite_early_exit]");
|
||||
return PlanLowerer::lower(builder, core_plan, ctx);
|
||||
}
|
||||
|
||||
if strict_or_dev
|
||||
&& matches!(
|
||||
domain_plan,
|
||||
crate::mir::builder::control_flow::plan::DomainPlan::Pattern2Break(_)
|
||||
)
|
||||
&& matches!(
|
||||
outcome.plan.as_ref(),
|
||||
Some(crate::mir::builder::control_flow::plan::DomainPlan::Pattern2Break(_))
|
||||
)
|
||||
{
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern2 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern2_break.is_none() {
|
||||
return Err("pattern2 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = composer::compose_coreplan_for_pattern2_break_subset(builder, facts, ctx)?
|
||||
.ok_or_else(|| "pattern2 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
PlanVerifier::verify(&core_plan)?;
|
||||
eprintln!("[coreplan/shadow_adopt:pattern2_break_subset]");
|
||||
eprintln!("{}", tag);
|
||||
return PlanLowerer::lower(builder, core_plan, ctx);
|
||||
}
|
||||
|
||||
|
||||
@ -9,14 +9,7 @@ use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts;
|
||||
use crate::mir::builder::control_flow::plan::planner::Freeze;
|
||||
use crate::mir::builder::MirBuilder;
|
||||
|
||||
pub(in crate::mir::builder) use shadow_adopt::{
|
||||
compose_coreplan_for_pattern1_simplewhile,
|
||||
compose_coreplan_for_pattern2_break_subset,
|
||||
compose_coreplan_for_pattern3_ifphi,
|
||||
compose_coreplan_for_pattern5_infinite_early_exit,
|
||||
compose_coreplan_for_pattern6_scan_with_init,
|
||||
compose_coreplan_for_pattern7_split_scan,
|
||||
};
|
||||
pub(in crate::mir::builder) use shadow_adopt::{try_shadow_adopt_core_plan, ShadowAdoptOutcome};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(in crate::mir::builder) fn try_compose_domain_plan_from_canonical_facts(
|
||||
|
||||
@ -4,6 +4,7 @@ use super::PlanNormalizer;
|
||||
use crate::ast::{ASTNode, Span};
|
||||
use crate::mir::builder::control_flow::joinir::patterns::router::LoopPatternContext;
|
||||
use crate::mir::builder::control_flow::plan::normalize::CanonicalLoopFacts;
|
||||
use crate::mir::builder::control_flow::plan::planner::PlanBuildOutcome;
|
||||
use crate::mir::builder::control_flow::plan::{
|
||||
CorePlan, DomainPlan, Pattern2BreakPlan, Pattern2PromotionHint,
|
||||
Pattern3IfPhiPlan, Pattern5InfiniteEarlyExitPlan, ScanDirection, ScanWithInitPlan,
|
||||
@ -11,6 +12,11 @@ use crate::mir::builder::control_flow::plan::{
|
||||
};
|
||||
use crate::mir::builder::MirBuilder;
|
||||
|
||||
pub(in crate::mir::builder) struct ShadowAdoptOutcome {
|
||||
pub core_plan: CorePlan,
|
||||
pub tag: &'static str,
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn compose_coreplan_for_pattern1_simplewhile(
|
||||
builder: &mut MirBuilder,
|
||||
facts: &CanonicalLoopFacts,
|
||||
@ -131,3 +137,122 @@ pub(in crate::mir::builder) fn compose_coreplan_for_pattern7_split_scan(
|
||||
let core = PlanNormalizer::normalize(builder, plan, ctx)?;
|
||||
Ok(Some(core))
|
||||
}
|
||||
|
||||
pub(in crate::mir::builder) fn try_shadow_adopt_core_plan(
|
||||
builder: &mut MirBuilder,
|
||||
ctx: &LoopPatternContext,
|
||||
strict_or_dev: bool,
|
||||
domain_plan: &DomainPlan,
|
||||
outcome: &PlanBuildOutcome,
|
||||
) -> Result<Option<ShadowAdoptOutcome>, String> {
|
||||
if !strict_or_dev {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
match domain_plan {
|
||||
DomainPlan::Pattern1SimpleWhile(_) => {
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern1 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern1_simplewhile.is_none() {
|
||||
return Err("pattern1 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan =
|
||||
compose_coreplan_for_pattern1_simplewhile(builder, facts, ctx)?
|
||||
.ok_or_else(|| {
|
||||
"pattern1 strict/dev adopt failed: skeleton compose rejected"
|
||||
.to_string()
|
||||
})?;
|
||||
Ok(Some(ShadowAdoptOutcome {
|
||||
core_plan,
|
||||
tag: "[coreplan/shadow_adopt:pattern1_simplewhile]",
|
||||
}))
|
||||
}
|
||||
DomainPlan::Pattern3IfPhi(_) => {
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern3 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern3_ifphi.is_none() {
|
||||
return Err("pattern3 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = compose_coreplan_for_pattern3_ifphi(builder, facts, ctx)?
|
||||
.ok_or_else(|| "pattern3 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
Ok(Some(ShadowAdoptOutcome {
|
||||
core_plan,
|
||||
tag: "[coreplan/shadow_adopt:pattern3_ifphi]",
|
||||
}))
|
||||
}
|
||||
DomainPlan::ScanWithInit(_) => {
|
||||
if !matches!(outcome.plan.as_ref(), Some(DomainPlan::ScanWithInit(_))) {
|
||||
return Ok(None);
|
||||
}
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern6 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.scan_with_init.is_none() {
|
||||
return Err("pattern6 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = compose_coreplan_for_pattern6_scan_with_init(builder, facts, ctx)?
|
||||
.ok_or_else(|| "pattern6 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
Ok(Some(ShadowAdoptOutcome {
|
||||
core_plan,
|
||||
tag: "[coreplan/shadow_adopt:pattern6_scan_with_init]",
|
||||
}))
|
||||
}
|
||||
DomainPlan::SplitScan(_) => {
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern7 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.split_scan.is_none() {
|
||||
return Err("pattern7 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = compose_coreplan_for_pattern7_split_scan(builder, facts, ctx)?
|
||||
.ok_or_else(|| "pattern7 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
Ok(Some(ShadowAdoptOutcome {
|
||||
core_plan,
|
||||
tag: "[coreplan/shadow_adopt:pattern7_split_scan]",
|
||||
}))
|
||||
}
|
||||
DomainPlan::Pattern5InfiniteEarlyExit(_) => {
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern5 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern5_infinite_early_exit.is_none() {
|
||||
return Err("pattern5 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan =
|
||||
compose_coreplan_for_pattern5_infinite_early_exit(builder, facts, ctx)?
|
||||
.ok_or_else(|| {
|
||||
"pattern5 strict/dev adopt failed: compose rejected".to_string()
|
||||
})?;
|
||||
Ok(Some(ShadowAdoptOutcome {
|
||||
core_plan,
|
||||
tag: "[coreplan/shadow_adopt:pattern5_infinite_early_exit]",
|
||||
}))
|
||||
}
|
||||
DomainPlan::Pattern2Break(_) => {
|
||||
if !matches!(outcome.plan.as_ref(), Some(DomainPlan::Pattern2Break(_))) {
|
||||
return Ok(None);
|
||||
}
|
||||
let facts = outcome
|
||||
.facts
|
||||
.as_ref()
|
||||
.ok_or_else(|| "pattern2 strict/dev adopt failed: facts missing".to_string())?;
|
||||
if facts.facts.pattern2_break.is_none() {
|
||||
return Err("pattern2 strict/dev adopt failed: facts mismatch".to_string());
|
||||
}
|
||||
let core_plan = compose_coreplan_for_pattern2_break_subset(builder, facts, ctx)?
|
||||
.ok_or_else(|| "pattern2 strict/dev adopt failed: compose rejected".to_string())?;
|
||||
Ok(Some(ShadowAdoptOutcome {
|
||||
core_plan,
|
||||
tag: "[coreplan/shadow_adopt:pattern2_break_subset]",
|
||||
}))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user