| name | visiomaster |
| description | Windows-first Visio diagram reconstruction workflow for flowcharts, architecture diagrams, and paper-style module figures. Reuses ppt-master style analysis and composition discipline on the front half, but outputs editable Visio .vsdx plus exported .svg and .png through a scene.json to Visio pipeline. Use when the user wants a diagram recreated as editable Visio shapes instead of a pasted screenshot or PPT-only result. |
Visiomaster
Overview
visiomaster is a standalone skill for rebuilding diagram images into editable Visio deliverables.
It is optimized for:
- flowcharts
- product or system architecture diagrams
- paper-style module/framework figures
- box-arrow process diagrams that should remain editable
It is not the right tool for:
- posters
- UI screenshots
- decorative layouts
- image-heavy slides where the main value is visual styling rather than structured diagram semantics
Core Positioning
Use ppt-master ideas on the front half:
- source collection
- style extraction
- layout discipline
- image understanding
- visual polishing standards
Do not reuse ppt-master's raw SVG -> PPTX output path for Visio.
For Visio, the stable path is:
image -> scene.json -> validate -> Visio COM render -> .vsdx/.svg/.png
The key rule is simple:
- main structure should be redrawn as editable nodes, labels, and connectors
- small thumbnails or texture snippets may remain raster only when redrawing them is not worth the loss in speed
- never solve a reconstruction request by pasting the whole original image unless the user explicitly asks for贴图
Environment
This skill is Windows-first and expects:
- local Microsoft Visio desktop installed
- Python with
pywin32
Use the active thread default Python interpreter. If the user or project provides a specific Python path, use that; otherwise use:
python
Workflow
1. Confirm scope
First classify the source request:
- editable flowchart recreation
- architecture/module diagram recreation
- paper figure cleanup/redraw
- image-assisted redraw with a few raster sub-assets allowed
If the diagram is mostly boxes, arrows, labels, and containers, stay in visiomaster.
For image-based exact replicas, always secure a local source image file before claiming strict review readiness:
- If the user provides a filesystem path, use that path as
metadata.source_image and all review --original inputs.
- If the user uploads or attaches an image without a local path, save/stage that image into the reconstruction workspace as
source/original.<ext> before rendering the final deliverable. Do not treat a chat attachment alone as an acceptable strict-review source.
- If the current client does not expose an attached image as readable bytes and the image cannot be staged locally, clearly mark the work as a draft/manual preview and ask for a source file path before strict review or final exact delivery.
- Every exact replica must keep the staged/local source path stable across review rounds. Do not use screenshots of the replica, pair images, OCR output, or memory of the attachment as a substitute for the original source image.
When you have a source file path, stage it with the helper script so review manifests can use one stable canonical image:
python ${SKILL_DIR}\scripts\stage_source_image.py `
--input <source.png> `
--workspace <reconstruction_workspace> `
--id <figure_id>
This writes source/original.<ext> and source/source_manifest.json with SHA-256 hashes. Use the staged image path as metadata.source_image and as make_review_assets.py --original.
For wide or dense figures, do not start by authoring the whole page in one pass. If the source has many modules, many arrows, tiny labels, or a very wide canvas, first create a region plan:
- visible regions become
group_container
- invisible logical work areas become
audit_region
- every meaningful node gets
container_id
- each region should usually stay under 12-18 visible nodes before whole-page assembly
- shared typography and arrow styles must be fixed before region scenes are merged
For exact replicas, do not write scene.json until you have a source-faithful visual inventory for that specific image. This inventory is produced by visual LLM inspection of the source image, not by OCR, filename clues, warning logs, prior scenes, or a batch scene generator. It must preserve visible source language and notation exactly; do not translate Chinese labels to English, normalize formulas, invent unreadable text, or replace source modules with generic neural-network blocks unless the source visibly shows them.
Record the inventory in metadata.source_visual_inventory before the first render. At minimum it should include:
analysis_basis: a short note such as visual_llm_source_image.
language_profile and do_not_translate.
unknown_text_policy: use mark_unreadable_do_not_invent for unclear tiny text.
- per-region
source_bbox_px, required visible labels/formulas, component motifs, edge motifs, port/boundary/dashed-frame notes, uncertainty notes, and text layout facts.
Before authoring the first edges array for an exact replica, run a separate arrow-inventory pass from the source image. The goal is to lock topology before any Visio PNG exists. For arrow-dense local structures, this pass is not optional bookkeeping; it is the scene driver:
- record every source-visible arrow in
metadata.arrow_plan
- each visible arrow or visible line segment gets its own independent
arrow_plan_id; do not describe a whole local subgraph or multi-hop chain with one plan entry
- each entry needs
id, from_visual_object, from_anchor_description, to_visual_object, to_anchor_description, route_shape, line_style, arrowhead, semantic_intent, source_bbox_px, must_not_cross, relative_position_facts, direction, endpoint/boundary facts, and certainty
- use
semantic_intent: "data_flow" for normal flow, "feedback"/"loss_backprop" for dashed return paths, "boundary_handoff"/"frame_output" for frame-edge arrows, "merge"/"fan_in" for many-to-one joins, "fork"/"fan_out" for one-to-many branches, and "loop_update" for outer cycles
- use route shapes such as
straight_horizontal, straight_vertical, orthogonal, rounded_orthogonal, smooth_curve, or loop; do not leave major arrows as vague auto
- after authoring edges, bind every source-visible edge with
arrow_plan_id
- one
arrow_plan_id may bind to only one scene edge by default. If one source arrow truly needs multiple scene segments, every segment edge must declare same_source_arrow: true, segment_index, and segment_count
- when a source arrow is unreadable, mark
certainty: "uncertain" and do not invent its destination
Treat metadata.arrow_plan as the source-truth checklist for later visual review: the reviewer should be able to say whether A001, A002, etc. match the original, rather than writing broad comments like "arrows are wrong".
For attention-like motifs, decompose the visual grammar before drawing scene edges. A source crop that looks like K/Q -> multiply -> score matrix -> value multiply -> value matrix -> Concat is not one edge. Record the local motif, then inventory each visible connector separately, for example:
A101: K_w right edge -> qk_mul left edge, horizontal, no arrowhead
A102: Q_a right/top edge -> qk_mul lower-left edge, short diagonal/curved, no arrowhead
A103: qk_mul right edge -> score matrix left edge, horizontal, arrowhead end
A104: V_w right edge -> value multiply left edge, horizontal, no arrowhead
A105: score matrix upper-right corner -> value multiply lower-left edge, diagonal, no arrowhead
A106: value multiply right edge -> value matrix left edge, horizontal, arrowhead end
A107: value matrix top edge -> Concat bottom edge, vertical, arrowhead end
When a local diagram matches a known motif such as attention_score_motif, value_weighting_motif, residual_add_norm_motif, or concat_merge_motif, generate the local scene from that motif grammar first. For attention_score_motif, Q/K feed the left-side multiply, Softmax is a floating label rather than an edge endpoint, the multiply output enters the score matrix, the score matrix connects diagonally to value multiplication, value multiplication enters the value matrix, and the value matrix outputs vertically to Concat.
For paper-style exact replicas, source_visual_inventory should record precise layout facts, not only module names:
- text alignment: left / center / right and baseline relation
- intended line breaks and no-wrap expectations
- whether a label is plain text, math-like, caption, annotation, or mixed CJK+math
- whether subscripts/superscripts are visible and must be preserved
- serif / sans / CJK / math font intent and visible source font if known
- whether visible shadow / glow / emphasis exists on the source text or bars
- caption prefix/body split such as bold
Fig. 6. plus regular body
- crop obligations for that region, such as
caption, small_text, or arrow_dense
- box/line/shadow/density facts for that region: padding, corner radius, dash rhythm, line weight, soft-shadow character, and whether the crop is visually tight or loose
For strict replica work, also mark:
metadata.replica_review_mode: "strict_replica"
metadata.replica_stage: "layout_topology" before the first render
metadata.replica_stage: "detail_polish" only after layout/topology is already visually correct
Fresh capability evaluation means a fresh scene from the source inventory. Do not validate a skill change by patching an old scene and checking whether that old scene looks better. Old scenes and old reviews may explain failure modes, but after changing skill workflow, schema, renderer, or components, rebuild each test scene from the source image inventory. Batch exporting finished scenes is fine; batch-generating several scenes from one Python script is not valid proof that the skill works for normal users.
2. Build or refine scene.json
scene.json is the contract between the visual analysis step and Visio rendering.
When authoring or editing it:
- read
references/scene-schema.md
- use
templates/visio_components.json as the supported component vocabulary
- use
templates/style_profiles.json to select paper_white or clean_white
- read
references/visio-component-map.md if you need mapping guidance
- for exact replicas, author coordinates in source pixels when possible and let the renderer scale them to inches
Starter generation:
python ${SKILL_DIR}\scripts\image_to_scene.py --image <source.png> --output <scene.json>
This script does not infer the real diagram structure from pixels. It only writes a blank or template starter scene. The actual first-pass scene.json for exact work must still be authored by the LLM from the source image.
For exact large-figure reconstruction, start in source pixels and record the region strategy:
python ${SKILL_DIR}\scripts\image_to_scene.py --image <source.png> --pixel-page --region-strategy region_first --output <scene.json>
If the layout is close to a standard process flow, you can seed from the built-in example:
python ${SKILL_DIR}\scripts\image_to_scene.py --image <source.png> --template basic-flow --output <scene.json>
Treat this as draft/bootstrap authoring only. It is not valid strict-replica proof.
For GAN/TFR training-cycle figures, AI-generated paper diagrams, or images with Real/Generated TFR panels, you may seed a draft/bootstrap pass from the canonical module template:
python ${SKILL_DIR}\scripts\image_to_scene.py --image <source.png> --template gan-tfr --output <scene.json>
Do not use template-seeded scenes as final evidence for strict capability evaluation. For strict replica work, rebuild the scene from a blank source-driven authoring pass before judging the skill.
Before the first Visio render of a draft/bootstrap or legacy GAN/TFR scene, you may run the deterministic recipe pass explicitly:
python ${SKILL_DIR}\scripts\scene_autofix.py <scene.json> --recipe gan-tfr --output <fixed.scene.json>
This recipe upgrades fragile local grammar before visual tuning: split Real/Generated boxes become tfr_panel, empty dashed loss frames become loss_region, raw L_adv/L_rec text becomes math_text, detached/broken outer loops become smooth loop_arrow, reversed GAN arrows are corrected, and crowded backprop arrows are bundled.
scene_to_visio.py no longer runs this autofix implicitly for strict/exact scenes. Use --autofix-gan-tfr only when you intentionally want an explicit bootstrap/render helper path, and treat the written <basename>.autofixed.scene.json as a non-final rewritten scene until you re-author a fresh strict-replica scene from source inventory.
3. Validate scene data
Before touching Visio, validate structure and references:
python ${SKILL_DIR}\scripts\scene_validate.py <scene.json>
If validation fails, fix the scene first. Do not guess around broken ids or unsupported types inside the renderer.
For large or complex figures, run a complexity preflight before full rendering:
python ${SKILL_DIR}\scripts\scene_complexity.py <scene.json>
Use the complexity report to catch the large-image failure modes before Visio render: too few regions, uncovered nodes, over-dense modules, inconsistent font scale, text-fit risks, and likely overlaps.
For exact replicas, run a typography preflight when the source uses more than one visible font style:
python ${SKILL_DIR}\scripts\font_inventory.py --check "Times New Roman" --check "Cambria Math" --check "Calibri" --check "Microsoft YaHei UI"
Do not treat all labels as one font. Classify visible text by role before rendering:
- paper serif labels:
font_role: "paper_serif" with Times/Cambria-like candidates
- UI/product labels:
font_role: "ui_sans" with Calibri/Arial/Segoe-like candidates
- formulas/operators:
font_role: "math" or symbol_font_role: "math"
- Chinese labels:
font_role: "cjk_sans" or cjk_serif
When the source font is known or strongly inferred, store source_font_family in the node style. If that font is installed but the effective render font differs, scene_audit.py reports it as a rebuild issue.
For complex paper figures with many modules, also generate a module-level audit report:
python ${SKILL_DIR}\scripts\scene_audit.py <scene.json>
Use the audit report to review every group_container as a separate region: child count, labels, colors, internal arrows, incoming arrows, outgoing arrows, and whether cross-module arrows start from a boundary or from an internal component. Treat unchecked audit items as real defects before final export.
For exact replicas, run the rebuild gate after each rendered iteration:
python ${SKILL_DIR}\scripts\scene_validate.py <scene.json> --strict
python ${SKILL_DIR}\scripts\scene_audit.py <scene.json> --fail-on-rebuild
In strict mode, missing source_visual_inventory, missing region_plan, template-seeded starts, and recipe-rewritten exact scenes are treated as gate failures, not informal warnings. If validate/audit prints a blocking contract failure or [REBUILD] item, stop coordinate nudging. Rebuild that local subsystem with the correct semantic component (loop_arrow, dashed_region, dashed_feedback_path, boundary_port, etc.) before doing any more visual polishing.
In strict mode, missing metadata.arrow_plan, missing arrow_plan_id bindings, or route-shape violations are also gate failures. Do not render a strict replica whose long arrows still rely on center-to-center auto routing when the source shows fixed horizontal, vertical, boundary, merge, fork, feedback, or loop grammar.
For exact replica work, validation passing is necessary but not sufficient. Render a PNG and compare it with the source for:
- page aspect ratio
- container bounds
- local topology
- distinctive shapes
- connector grammar
- feature-map coloring
- source-language preservation, formulas, tiny labels, ports, and arrow endpoints
Exact mode should run as a two-stage production loop, not one rushed render:
- first render/review stage: lock layout, region bboxes, container bounds, and topology grammar
- second render/review stage: fix text layout, caption behavior, shadows, local spacing, and visual polish
If a higher-level component stays visually wrong after two strict reviews, rebuild that local subsystem with smaller components or primitives. Do not keep nudging the whole page around one stubborn panel or text cluster.
For arrow-dense local structures, review the local crop before merging it into the full scene:
- author a local scene such as
attention_core.scene.json from the local source crop and motif/arrow plan
- validate it with strict arrow-plan checks
- render only that local scene
- compare the local source crop and local replica crop as a pair
- merge into the full scene only after every arrow-plan checklist item passes
Do not ship after a first-pass exact render unless the second review round is already represented and visually clean.
4. Render into Visio
Render the scene into a Visio drawing and export deliverables:
python ${SKILL_DIR}\scripts\scene_to_visio.py <scene.json> --output-dir <exports>
Default outputs:
Use --style-profile clean_white when the user wants a polished white product/process style. Use the default paper_white for paper figures and academic module diagrams.
Read references/visio-export-flow.md when debugging Visio automation or export behavior.
After rendering complex replicas, compare the exported PNG module-by-module against the source. Do not rely on whole-image visual similarity; small topology errors often hide inside large figures.
For exact replicas, the first render is allowed to be a fast editable reconstruction pass, but the first render must be followed by at least one local-source review round before final delivery:
- Use the local/staged original image file and the exported replica PNG with
make_review_assets.py --write-review-bundle.
- The reviewer input is the original source image plus the current replica image. Do not send a generated global pair when those two full images are already available; a global pair is only a human navigation/audit artifact and usually shrinks fine details.
- Generate local crop assets only for the regions under active doubt, such as
attention_core, arrow_dense, right_output, small_text, or caption. Do not generate or review every crop by habit. If you generate a crop but neither a human nor the reviewer inspects it, it is only a stored debug artifact, not review evidence.
- Overlay assets are off by default. Generate overlays only when checking global alignment drift, frame offsets, or region bbox registration. Do not use overlays for arrow topology, text wrapping, operator endpoints, or formula fidelity; they tend to obscure those defects.
- During review, convert source-vs-replica visual comparison into two explicit checklists inside or alongside
review_findings.json: a topology checklist and a visual-layout checklist.
- The topology checklist records source facts such as branches, merges, boundary crossings, operator order, arrow endpoints, and required routes. Examples:
S3 -> vertical trunk -> S1/common path, S2/S3 -> hollow circle -> minus, Linear -> f̂ -> [] -> fused feature.
- The visual-layout checklist records overlap, label wrapping, bracket/tensor spacing, line-through-text defects, feature-stack thickness, font-role drift, and color/rounding/shadow mismatches.
- A finding should reference the failed checklist item when possible. Do not write only broad notes such as "right output is wrong" when a specific missing branch, wrong landing point, or bracket overlap is visible.
- Repair rounds must re-check the same crop and checklist items, not only rerun validation or no-op gates.
For high-fidelity work, the reviewer should compare only two images:
- the original source image
- the current replica PNG
Do not give the reviewer pair/overlay images as the prompt when the original and replica are already available. A pair image is redundant with the two full images and often hides small connector or text defects through downscaling.
Targeted crops are allowed as secondary reviewer inputs only when the current task is explicitly local and the full images are too small to judge the detail. In that case, send the original full image, the replica full image, and the smallest useful number of local source-vs-replica crop pairs. Record which crop(s) were actually inspected. The review contract is still anchored by the two full images.
For exact/strict review packaging, call make_review_assets.py --write-review-bundle to write the manifest/templates. By default it does not generate global pairs, local crops, or overlays. Use:
--include-global-pair only for human navigation/audit records.
--crops core arrow_dense caption for hand-picked named crops.
--region-crops all only when you intentionally want every metadata.region_plan crop pair.
--include-overlays only for alignment-drift debugging.
The reviewer should receive the two images and a concrete issue format. It should report specific visual differences, source appearance, replica appearance, impact on fidelity, focus regions, and the expected visible change after regeneration. Use script output only to package round evidence and to validate/export; the quality decision remains visual.
If using a separate reviewer agent, give it only the source image, the replica image, and the issue format. Do not give it intended fixes, prior conclusions, pair/crop packs, script warnings, similarity scores, or old scene JSON. The reviewer validates visual fidelity; the main agent turns that into a fresh scene rebuild.
Use the fixed reviewer prompt in references/reviewer-two-image-prompt.md.
Do not stop at natural-language review notes. In strict work, the review loop must produce:
review_manifest.json from make_review_assets.py --write-review-bundle
review_findings.json from the visual reviewer
scene_rebuild_brief.json from review_findings_to_repair_plan.py
- a regeneration packet from
prepare_regeneration_packet.py
- a no-op proof from
round_noop_gate.py
review_findings.json should contain both defect findings and the review checklists used to find them. At minimum, include:
topology_checklist: visible source topology facts, each with an id, focus region, source fact, replica status, and pass/fail/uncertain status.
visual_checklist: local layout/style facts, each with an id, focus region, source expectation, replica status, and pass/fail/uncertain status.
- findings that cite
checklist_refs for failed checklist items when applicable.
Use uncertain instead of inventing facts when a source crop is unclear. Ask for a higher-resolution source or user confirmation only when the uncertain item affects topology or final fidelity.
After writing review_findings.json, run the checklist gate before generating the rebuild brief:
python ${SKILL_DIR}\scripts\review_checklist_gate.py `
<review_findings.json> `
--manifest <review_manifest.json> `
--require-failed-refs `
--output-report <review_checklist_gate.json>
Then generate the rebuild brief with checklist enforcement:
python ${SKILL_DIR}\scripts\review_findings_to_repair_plan.py `
<review_findings.json> `
--scene <prior.scene.json> `
--manifest <review_manifest.json> `
--require-checklists `
--output <scene_rebuild_brief.json>
If either command fails, fix the review findings/checklists instead of continuing with regeneration.
For arrow-dense regions, the review checklist must be per-arrow, not only per-region. Include one checklist item per arrow_plan_id, such as:
[ ] A101 K_w -> qk_mul matches source
[ ] A102 Q_a -> qk_mul matches source
[ ] A103 qk_mul -> score grid matches source
[ ] A104 V_w -> value_mul matches source
[ ] A105 score grid -> value_mul matches source
[ ] A106 value_mul -> value grid matches source
[ ] A107 value grid -> Concat matches source
Blocking review findings should name the exact arrow id and mismatch class: unbound_source_arrows, multi_edge_plan_misuse, source_anchor_mismatch, route_shape_mismatch, or motif_rule_violation.
The no-op gate is mandatory when claiming a new round improved the scene. It fails when:
- the scene diff is metadata-only
- only weak style fields changed
- the rendered PNG pixel diff is zero
If you have a scene_rebuild_brief.json, pass it into round_noop_gate.py --rebuild-brief ... so the report keeps the focus-region and likely-scene-id evidence for that round.
Use references/review-contract.md for the structured review format and references/renderer-effective-fields.json for the current renderer-effective-field whitelist. During reauthoring, do not claim progress from notes, region-plan edits, review assets, or metadata changes alone.
Use the fixed regeneration prompt in references/full-scene-regeneration-prompt.md when authoring the next full scene after a failed review.
Use scripts/prepare_regeneration_packet.py to turn scene_rebuild_brief.json into a round-specific handoff packet and prompt file before the next LLM full-scene regeneration pass.
If the packet step cannot recover both reviewer image paths, stop and fix the review bundle instead of continuing with an incomplete rebuild handoff.
When several visual reviews say the replica looks like a semantic redraw instead of a source-faithful figure, stop component-level polishing and recalibrate the scene:
- mark the source image's real outer frame, titled region boxes, input/core/output bboxes, and major bus lines in source-pixel coordinates
- record those bindings in
metadata.region_plan and on region nodes with source_bbox_px / source_aspect_ratio
- keep region-local node density close to the source before drawing small labels
- if you generate debug pairs/crops for yourself, compare only the selected focus regions and adjust region bboxes first
- only after the region bboxes match should you tune fonts, shadows, gradients, arrowheads, and individual labels
Do not replace this loop with a student/expert mode, whole-image template selector, or automatic template matching system. Reusable templates and examples are syntax references or first-pass seeds only; every high-fidelity result must still come from source-image visual analysis, source-pixel scene authoring, rendered PNG review, and visual reviewer findings.
For repeated internal layer modules, choose the visual grammar from the source crop before rendering:
- colored 2D strips: use
layer_sequence with block_style_mode: "colored_paper_strip" and source-matched block_fills.
- if source strips are colored, preserve them with
block_fill_policy: "preserve" or preserve_block_fills: true; never leave ignore_block_fills: true on a colored sequence.
Keep scene authoring and scene reauthoring separate:
- authoring: build the first valid scene from the source image and source visual inventory
- reauthoring: consume source/replica review findings, regenerate a fresh full scene, rerender, and prove the change with the no-op gate
After review, do not patch the prior scene when the finding says the region is semantically wrong or the topology/component grammar changed; rebuild that scene or local subsystem from the source and findings. For narrow checklist failures after the topology is already correct, a small targeted repair is acceptable, but it still must be backed by the same local source crop, updated review findings/checklist status, and a no-op gate. The prior scene may be read as failure evidence, but it must not override source-image facts.
- white 2D vertical strips: use
block_style_mode: "paper_vertical_strip" and set block_fill_policy: "white" if old block_fills remain in the scene.
- white 3D/high vertical blocks: use
block_style_mode: "paper_vertical_cuboid" or white_3d; do not convert them to colored strips just because block_fills exists.
- dense gate/projection/QKV modules should set
density_mode: "source_dense" (or dense: true) after the region bbox is locked; do not enlarge the whole module to hide text/arrow problems.
- if the source already has a surrounding module frame and only the repeated bars are visible, set
layer_sequence.frame_visible: false instead of drawing a second inner frame.
- if the source layer sequence has visible arrows between adjacent strips, keep them inside the component with
draw_internal_arrows: true rather than scattering loose edge fragments.
If visual review reports text wrapping in operators, formulas, CJK labels, or rotated layer labels, treat it as a renderer/schema or scene-box defect. Do not enlarge the whole module to hide the wrap; fix the text box policy, math/operator component, local font scale, or source-coordinate label box.
Use math_text for hat variables such as f̂, concat_operator for visible [] concat brackets, and brace_merge for curly many-to-one merge braces. Do not model these as loose text glyphs or generic rectangles when the source shows a semantic operator/merge mark.
For compact math labels with word-like subscripts such as a_RGB, P_SAR, q_hrrp, f_fused, or S_i, prefer math_text / math_vector with fragment subscript rendering when the subscript contains uppercase or multi-letter tokens. Compact Unicode is only safe for digits and true Unicode subscript letters; do not render RGB, SAR, IR, or fused with superscript-looking fallback glyphs. If visual review reports letters scattered vertically, split into fuse d, or raised like superscripts, treat that as renderer/schema debt and fix the component or local text box before coordinate polishing.
For tensor-like feature maps, decide from the crop whether the source is a thick 3D cuboid stack, thin front-sheet stack, slanted-sheet stack, or oblique slab stack. Use tensor_stack.stack_render_mode: "thin_feature_slabs" for source crops with many narrow feature sheets and light perspective; use feature_cuboids only when the crop clearly shows thick black-edged cuboid blocks. A repeated review complaint that tensors look flat or too blocky is a component-mode error, not a coordinate issue.
For final concat marks, use concat_operator with glyph_mode: "source_bracket" when the source shows a compact heavy [] bracket. Use operator_node only for circular or text operators; a small bracket-like fusion symbol should not become a white rectangle or oversized Concat box.
For Top-k/probability panels, use probability_bar_list with bar_value_label and bar_value_anchor: "bar_area", "row", or "after_bar" based on the source crop. If bars run through the row text, reduce bar_max_fraction or move labels to after_bar; do not position row text as loose overlays or push it into bars with offsets unless the source visibly does that.
In strict replica mode, do not leave panel internals on defaults. Record padding, axis position, bar start, row alignments, baseline offsets, and explicit shadow presence or null.
When a defect is reported, classify it before editing:
- component problem: the chosen component family is wrong for the crop
- topology problem: branches/merges/boundaries are encoded with the wrong connection grammar
- text problem: role, baseline, rotation, math attachment, or shrink behavior is wrong
- style problem: padding, rounding, density, line weight, dash rhythm, gradient, or shadow is wrong after structure is already correct
Use one repair order for exact replicas:
- component choice
- topology and anchors
- math text and rotated text
- container/title/content proportions
- shadows, gradients, line weight, dash rhythm
If a local subsystem is still wrong after two micro-adjustment rounds, stop nudging coordinates and rebuild that local subsystem with the correct component or renderer rule.
Treat these as blocking defects in strict replica mode:
- broken or compressed vertical strip text
- wrong or missing subscript / hat / Greek math glyph
- line crossing through visible text
- long cross-module flow that still lands center-to-center
- long paper-flow segments that stay diagonal
- concat/operator syntax rendered with the wrong component family
- repeated strips, panels, or tensor geometry still depending on hidden defaults instead of explicit scene contract
For cross-module flow, do not connect large modules center-to-center by default. Use boundary ports, buses, trunks, junctions, or explicit side anchors. For math-like text, do not keep it on plain text_block just because the font looks close enough; use math_text, formula_text_block, or run-based math fragments.
For environment encoders and other tapered paper modules, use dual_wing_encoder with shape_mode: "opposing_trapezoids" or custom_polygon when the source is pinched/notched rather than a full-height three-part block. For brace aggregation near plus/sum nodes, use brace_merge with brace_shape: "tight_curly" and waist_width_in instead of a generic wavy brace when the source has a tight waist.
Component Strategy
Version 1 intentionally uses a small controlled vocabulary instead of trying to expose all Visio masters.
Supported node families:
page_background
process_box
rounded_process
stacked_process
stacked_token
notched_block
feature_map_banded
feature_map_grid
merge_bus
decision_diamond
terminator
group_container
dashed_region
loss_region
audit_region
text_pill
ellipse_node
polygon_node
trapezoid_node
cuboid_node
tensor_stack
modality_spine
math_vector
math_text
feature_vector_stack
tfr_panel
operator_node
multi_port_junction
concat_operator
brace_merge
boundary_port
boundary_fanout
wave_signal
classifier_head
layer_sequence
text_block
caption_block
grid_matrix
token_grid
bracket
junction_point
image_tile
legend_block
Supported edge families:
arrow_connector
dynamic_connector
lane_arrow
curved_arrow
loop_arrow
dashed_feedback_path
line_segment
join_connector
fork_connector
boundary_arrow
residual_connector
residual_loop
Why this matters:
- it keeps
scene.json stable
- it avoids binding the whole system to localized Visio stencil names too early
- it lets us start with primitive geometry rendering, then add real stencil/master mapping later without breaking the scene schema
Execution Rules
- Prefer editable reconstruction over screenshot embedding.
- Recreate hierarchy first: containers, major nodes, main connectors, then secondary labels.
- Preserve the source image's information design before chasing decorative detail.
- Keep coordinates in
scene.json in top-left page space; let the renderer convert to Visio coordinates.
- If a source figure contains one non-essential photographic or map tile, isolate that asset instead of rasterizing the full page.
- When a shape is ambiguous, fall back to the nearest supported component and note the approximation.
- For arrows, use
route and explicit points; do not rely on diagonal lines unless the source really uses diagonals.
- For rotated paper labels, use
text_block with angle_deg instead of rotating text inside a process shape.
- For convolution kernels, receptive fields, masks, and other regular cell diagrams, use
grid_matrix; do not manually author each square.
- For modality grouping marks such as
], [, U, and inverted U, use bracket; do not fake them with ultra-thin process boxes.
- For 2-to-1, 3-to-1, or 1-to-many arrows, place a tiny
junction_point at the merge/fan location, connect sources to the junction, then connect the junction to the destination.
- Do not connect arrows directly to
group_container. Containers frame regions only; use a nearby junction_point or explicit node on the border when a callout line is needed.
- For brackets with a middle merge arm, set
tick_positions: [0, 0.5, 1]; a plain two-arm bracket is not enough for modality merge symbols.
- For cross-container flow, split the edge through
junction_point nodes with role: boundary_anchor; set allow_cross_container: true only on the short bridge between anchors.
- For dense mini-module diagrams, keep all connectors axis-aligned with
hv, vh, or explicit aligned points. A connector must not cross through a non-endpoint node.
15a. When an exact paper-flow route has explicit points but still renders slightly diagonal, set orthogonalize_points: true or add the missing elbow point. Do not use allow_diagonal: true unless the source visibly has a diagonal callout/fan line.
- Run after authoring. Treat route-quality warnings as defects, not cosmetic suggestions, before rendering through Visio.
References
references/scene-schema.md: scene.json fields and coordinate rules
references/visio-component-map.md: supported components and renderer intent
references/visio-export-flow.md: Windows + Visio export path and current limitations
templates/style_profiles.json: paper_white and clean_white rendering profiles
templates/examples/basic_flow.scene.json: starter example
templates/examples/multimodal_paper_components.scene.json: smoke example for multimodal spines, cuboids, trapezoids, and polygons
templates/examples/gan_loop_feedback.scene.json: smoke example for smooth loop arrows, dashed regions, and dashed feedback paths
templates/examples/gan_tfr_full.scene.json: canonical first-pass GAN/TFR template using tfr_panel, loss_region, math_text, smooth loop_arrow, and bundled backprop arrows
scripts/scene_complexity.py: preflight report for large/dense figures before Visio rendering
scripts/font_inventory.py: local Windows font inventory and preferred role fallback check
scripts/stage_source_image.py: copies a source image into source/original.<ext> and records hashes for stable strict review manifests
scripts/review_checklist_gate.py: validates topology_checklist, visual_checklist, local source-image paths, and checklist_refs before rebuild planning
scripts/scene_autofix.py: deterministic GAN/TFR local grammar upgrade pass before Visio rendering
docs/updates/2026-05-19-multimodal-paper-figure.md: detailed analysis of a complex multimodal paper figure and the related component upgrade
Current Boundaries
Version 1 is deliberately conservative:
- connectors support auto snap, orthogonal routing, and explicit points before full glue-aware connectors
- core flowchart shapes use local Visio masters when available, with controlled fallbacks
- export is handled by Visio after scene rendering rather than by translating raw SVG into Visio
That is the right tradeoff for a reusable first release.