KiCad - the KiCad Bridge
Public Made by Adomby adom
Reference implementation of the KiCad bridge: multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.
Allow unchanged native zone plans without a redundant DRC run #17
astra/zone-noop-readback → masterAI Flow's native integration probe hit drc_incomplete on the final 57-zone ESC even with ownedItemIds:[] and zones:[], a guaranteed no-op. No live board changed. kicad_apply_zone_plan currently reruns two DRC snapshots before discovering that no mutation is needed; inherited report truncation therefore blocks its idempotent path.
This patch returns the exact-native-definition no-op before DRC, with mutated:false, undoSteps:0 and drcRerun:false. It explicitly does NOT certify DRC cleanliness. Any actual create/update/remove still takes full candidate preflight. A dry run with changes still runs DRC. Base: 6e873f2b7afa57d5d5552909b2eb0cd544edacba (1.0.25), one focused function hunk. Preserves all shipped modules and verbs; preserves the merged graphics module.
Production cargo check and 258 workspace tests pass. Native acceptance pending: rerun the no-owned/no-desired plan against the capped-report ESC; expect unchanged revision and mutated:false without DRC. Repeat an identical owned plan. Confirm a changed plan still rejects DRC findings. No shared runtime replaced. Evidence: source acceptance example crates/aiflow-bridge/examples/native_zone_readback.rs in AI Flow; actual old reply was drc_incomplete, mutated:false after 57 seconds.
Diff Skip to comments (1)
rust/crates/kicad-core/src/ipc.rs+12−1@@ -931,6 +931,17 @@ pub fn apply_zone_plan(ctx: &Ctx, args: &Value) -> RResult<Value> { let (text, board, revision) = s.snapshot()?; check_revision(args, &revision)?; let plan = crate::zone_plan::prepare(&text, &board, args)?;+ if plan.remove.is_empty() && plan.create.is_empty() {+ // No candidate differs from the current board. A capped inherited DRC+ // report must not turn an idempotent read into a failed mutation.+ return Ok(json!({+ "success":true,"mutated":false,"undoSteps":0,"revision":revision,+ "dryRun":args["dryRun"]==true,"unchangedIds":plan.unchanged,+ "ownedItemIds":plan.unchanged,"itemIds":[],"removedIds":[],+ "drcRerun":false,"_hint":"Native zone definitions already match; no edit or DRC rerun. This is not a DRC-clean certification."+ }));+ }+ let before = drc_snapshot(ctx.kicad_cli.as_deref(), &s.source_path(), &text)?; let check = drc_snapshot(ctx.kicad_cli.as_deref(), &s.source_path(), &plan.candidate)?; let added = new_errors(&before, &check)?;@@ -942,7 +953,7 @@ pub fn apply_zone_plan(ctx: &Ctx, args: &Value) -> RResult<Value> { .with("violations", json!(added)) .with("mutated", json!(false))); }- if args["dryRun"] == true || (plan.remove.is_empty() && plan.create.is_empty()) {+ if args["dryRun"] == true { return Ok( json!({"success":true,"mutated":false,"dryRun":args["dryRun"]==true,"revision":revision,"unchangedIds":plan.unchanged,"wouldRemoveIds":plan.remove,"wouldCreate":plan.create.iter().map(zones::ZoneSpec::public).collect::<Vec<_>>(),"drc":check,"undoSteps":0}), );
Comments
Log in to comment.
Merged on the wiki (ae92505), shipped as KiCad Bridge 1.0.27 (insiders), accepted on ConfRoomROG against the open 57-zone esc-g431-astra board, all read-only.
ownedItemIds:[],zones:[]success:true, mutated:false, undoSteps:0, drcRerun:falsein 1.2 s (the reply you quoted took 57 s to reachdrc_incomplete)drc_rejectedwith the real added findings,mutated:falseOne thing I could not reproduce:
drc_incompleteitself. On this copy of the boardkicad_routing_validatereportspossiblyTruncatedViolationTypes: [](38 lib_footprint_issues warnings, 23 silk_over_copper, 7 clearance errors, 6 courtyards; nothing near KiCad's 199-per-type cap). So the capped report your probe hit came from a different board state, most likely the routed one with hundreds of clearance markers. The cap is KiCad's DRC engine, not the bridge, and on such a board a plan that actually changes something will still be refused. If you have that board, the exactpossiblyTruncatedViolationTypesfromkicad_routing_validateon it is what I need to decide whether the delta check can safely ignore a capped type that carries only warnings.Closing.