31 — Comprehensive Workflow & Human Factors Analysis

Note

Document type: Engineering analysis Created: 2026-02-23 Method: Programmatic cross-reference of CSV Manual.pdf, 44 DCL dialogs, 126 LSP modules, and csv.mnu menu definition. Scope: Complete workflow mapping, data flow tracing, human factors evaluation, and Design FMEA for ConstructiVision v11.


1. Program Purpose Statement

ConstructiVision is a tilt-up concrete panel detailing system that runs inside AutoCAD. It automates the creation of:

  1. Panel shop drawings — 3D solid models of individual concrete wall panels with openings, blockouts, reveals, chamfers, hardware, and dimensioning

  2. Site drawings — plan-view layouts showing panel placement on building footprints with grid lines, wall lines, slab edges, and footing connections

  3. Engineering data exports — structured data files sent to lift engineering firms (Dayton/Richmond, Meadow-Burke, WSB/White Cap) for crane lift analysis and brace design

  4. Materials lists — quantity take-offs for concrete, form material, hardware, chamfer, reveal strip, and connections

  5. Panel books — batch-printed drawing sets with revision history

The program replaces manual drafting of tilt-up panel details — a process that typically takes 2–4 hours per panel by hand — with a dialog-driven parametric system that generates a fully dimensioned 3D panel in minutes.


2. System Architecture Overview

2.1 Technology Stack

Layer

Technology

Detail

Host application

AutoCAD 2000 (R15.0)

32-bit, Visual LISP runtime

Application code

AutoLISP (.lsp)

126 source files, ~450 KB

Dialog definitions

DCL (.dcl)

44 files, ~530 KB, ~4,500 controls

Menu system

MNU/CUI

38 menu items in MENUGROUP=CSV

Data persistence

XRecord

Named Object Dictionary → “panel_list”

Compiled form

VLX

csv.vlx bundles 120 modules

External loader

csvmenu.lsp

Startup Suite, outside VLX

2.2 Central Data Structure: panelvar

The entire system revolves around a single association list called panelvar. Every dialog reads from it and writes back to it. It is persisted as an XRecord in AutoCAD’s Named Object Dictionary under the key "panel_list".

panelvar = (
  ("mpvar" . (...))   ;; Panel geometry: width, height, thickness, elevations
  ("rovar" . (...))   ;; Rough openings (4 slots)
  ("wdvar" . (...))   ;; Standard openings (6 slots)
  ("drvar" . (...))   ;; Man doors (6 slots)
  ("dlvar" . (...))   ;; Dock levelers (3 slots)
  ("sbvar" . (...))   ;; Rectangular blockouts (6 slots)
  ("rbvar" . (...))   ;; Round blockouts (6 slots)
  ("fhvar" . (...))   ;; Horizontal feature strips (19 slots across 3 pages)
  ("fvvar" . (...))   ;; Vertical feature strips (19 slots across 3 pages)
  ("plvar" . (...))   ;; Pilasters (2 slots)
  ("llvar" . (...))   ;; Lintels (2 slots)
  ("tpvar" . (...))   ;; Top plate / greenplate
  ("lbvar" . (...))   ;; Ledger bar / greenplate
  ("chvar" . (...))   ;; Chamfer parameters
  ("tsvar" . (...))   ;; Top steps (2 slots)
  ("fsvar" . (...))   ;; Footing steps (2 slots)
  ("ssvar" . (...))   ;; Spandrel seats (2 slots)
  ("sdvar" . (...))   ;; Slab dowels (4 slots)
  ("bpvar" . (...))   ;; Brace points (8 slots)
  ("ppvar" . (...))   ;; Pick points (8 slots)
  ("wcvar" . (...))   ;; Weld connections (15 slots across 5 pages)
)

21 variable groups × N slots each = ~1,826 discrete input parameters.

2.3 Module Classification

Category

Count

Examples

Dialog managers (_dlg)

30

mp_dlg, wc_dlg, btch_dlg

Geometry engines

12

drawpan, opening, feature, green, chamfer

Dimensioning

3

drawdim, drawdimlst, basedim

Engineering I/O

6

engexp, engimp, dreng, mbeng, wsbeng, makepan

Utilities

15

convert, panatt, updvar, rangchck, strlsort

Orchestration

5

csv, panel, finpan, btch, okcanhlp

Startup/compat

2

csvmenu, csvcompat


3. Complete Workflow Maps

3.1 Master Navigation Flow

The top-level menu is labeled “ConstructiVision” and the first item is “Drawing Setup” (renamed from “Program Options” — see Section 3.1b) — a single entry point that routes to either panel editing or site editing based on the drawing’s contents.

┌─────────────────────────────────────────────────────────────────┐
│                    AutoCAD Startup                               │
│  csvmenu.lsp → loads csv.mnu/csv.cui → "ConstructiVision" menu  │
└────────────────────────┬────────────────────────────────────────┘
                         │ User clicks "Drawing Setup"
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│  csv.lsp (c:csv)                                                 │
│  • Sets ~60 sysvars                                              │
│  • Loads 93 modules from csvlst                                  │
│  • Shows project dialog if no CV drawing is open                 │
│  • Routes based on Named Object Dictionary lookup:               │
│    ├─ "panel_list" found → pj_name → md_dlg (Panel Options)      │
│    ├─ "site_list" found  → pj_name → site_dlg (Site Options)     │
│    └─ Neither found      → dwgtype.dcl (ask user)                │
│                            ├─ "Panel Drawing" → md_dlg            │
│                            ├─ "Site Drawing"  → site_dlg          │
│                            └─ Cancel          → exit              │
└────────┬──────────────────────────┬─────────────────────────────┘
         │                          │
    ┌────▼─────┐             ┌──────▼──────┐
    │ md_dlg   │             │ site_dlg    │
    │ (Panel)  │             │ (Site)      │
    └────┬─────┘             └──────┬──────┘
         │                          │
    ┌────┴────────────┐        ┌────┴──────────────┐
    │ Panel Workflows │        │ Site Workflows     │
    │ (Section 3.2)   │        │ (Section 3.5)      │
    └─────────────────┘        └────────────────────┘

How panel vs. site detection works:

  1. Primary method (csv.lsp): Dictionary key lookup in the AutoCAD Named Object Dictionary — checks for "panel_list" first, then "site_list". This is the real routing mechanism.

  2. User choice (csv.lsp → dwgtype.dcl): If neither dictionary entry exists, the csv_ask_dwgtype function presents the Drawing Type dialog (dwgtype.dcl) with “Panel Drawing” / “Site Drawing” / “Cancel” buttons. The user explicitly chooses.

  3. Template detection (dwgnew.lsp): When creating a new drawing from an existing template, filename patterns are tried first — *site* → site, *panel*,*pnl* → panel. If the filename is ambiguous, the same dwgtype.dcl dialog is shown.

Note

The fallback no longer silently defaults to panel mode. An unrecognized drawing will always prompt the user to choose, eliminating the risk of misrouting a site drawing to the panel editor.

3.1a progcont Routing — VLX vs Source Mismatch (Updated Mar 1, 2026)

The top-level menu items set different progcont values before calling csv;. In VLX mode, the compiled bytecode reads progcont and routes to distinct dialogs. In source-mode (.lsp), the routing code is missing — all items fall through to the same dialog.

Menu Item

progcont

csv.mnu Line

VLX Behavior (working)

Source-Mode Behavior (broken)

Drawing Setup

1

8

md_dlg “Program Options” hub

md_dlg “Panel Options” (wrong dlg)

Slope Calculator

8193

59

Slope Elevation Calculator dialog

Same md_dlg “Panel Options”

Create New Project

262153

10

Project Details dialog

Same md_dlg “Panel Options”

Create New Drawing

262161

11

File chooser “Choose a template”

Same md_dlg “Panel Options”

Edit Existing Drawing

262145

12

File chooser “Choose to edit”

Same md_dlg “Panel Options”

Batch Utilities

262177

14

Batch UI dialog

Same md_dlg “Panel Options”

Root cause — VLX/source mismatch (discovered Mar 1, 2026):

The CSV.VLX was compiled from source code that does not exist in this repository. Binary analysis of the VLX reveals:

  1. VLX’s embedded md_dlg.dcl = “ConstructiVision - Program Options” with numeric button keys ("2", "8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "16384") that map to progcont bitmasks.

  2. Source md_dlg.dcl (both PB11 and TB11 folders) = “ConstructiVision – Panel Options” with string keys ("new", "old", "val", "pal", "vgp", etc.) — a completely different, lower-level dialog for panel sub-feature selection.

  3. VLX’s compiled c:csv reads progcont and routes to different dialogs per value. The source csv.lsp never reads progcont — it uses pnl and ld variables instead.

The progcont bitmask system uses base 262144 (0x40000) = “already loaded, skip project dialog”. Button keys are powers of 2. The menu sets (setq progcont N) then calls csv;. The VLX bytecode decodes the bitmask and routes accordingly. This routing code was never committed to the source tree.

The csv.mnu file is the authoritative source for all progcont values (17 menu items with their progcont assignments). The au3 test fixture replicates exactly what the menu macros do: (progn (setq progcont N)(c:csv)).

Important

progcont is NOT dead code in VLX mode — it is the primary routing mechanism. OCR evidence from VM 102 (PB11/VLX) confirms each progcont value produces a distinct dialog. To make TB11 source-mode pass the au3 validation tests, the missing progcont routing must be reconstructed in csv.lsp and the VLX’s numeric-key md_dlg.dcl / md_dlg.lsp must be reverse-engineered or rewritten from scratch based on OCR evidence of the working dialogs.

3.1b Changes Applied

The following improvements have been implemented in this sprint:

  1. Menu renamed: “Program Options” → “Drawing Setup” — the old name implied application settings, not drawing configuration. The new name accurately describes what the user is doing: setting up or configuring a drawing within ConstructiVision.

  2. Drawing type choice dialog added: New file dwgtype.dcl with helper function csv_ask_dwgtype in csv.lsp. When the Named Object Dictionary has neither "panel_list" nor "site_list", the user is now presented with:

    • “Panel Drawing” — routes to md_dlg (Panel Options)

    • “Site Drawing” — routes to site_dlg (Site Options)

    • “Cancel” — exits without action

  3. Template detection improved in dwgnew.lsp — now tries both *site* and *panel*,*pnl* filename patterns before falling back to the same drawing type choice dialog. Previously, any non-“site” filename silently defaulted to panel mode.

3.2 Panel Creation / Editing Workflow

This is the primary workflow — ~90% of user time.

Step  Dialog/Function    User Action                        Code Path
────  ─────────────────  ─────────────────────────────────  ──────────────
 1    md_dlg             Click "New Panel" or "Edit Panel"  md_dlg.lsp
 2    mp_dlg             Enter panel #, dimensions, scale   mp_dlg.lsp
 3    [sub-dialogs]      Define panel features (see 3.3)    *_dlg.lsp
 4    OK in mp_dlg       Validates, saves panelvar          okcanhlp.lsp
 5    panel()            Writes XRecord, calls drawpan      panel.lsp
 6    drawpan()          Builds 3D solid geometry           drawpan.lsp
 7    opening()×N        Subtracts openings from solid      opening.lsp
 8    feature()×N        Adds reveal strips                 feature.lsp
 9    green()×N          Adds greenplate/ledger geometry    green.lsp
10    weldconn()         Places connection blocks           weldconn.lsp
11    chamfer()          Applies edge chamfers              chamfer.lsp
12    finpan()           Center of gravity, points, dims    finpan.lsp
13    drawdim()×5        Dimension chains per layer group   drawdim.lsp
14    TITLE/BORDER       Insert title block with attributes finpan.lsp
15    Save               Write .dwg file                    finpan.lsp

Elapsed time per panel: 3–15 minutes depending on complexity. Geometry operations: 3D Boolean (UNION/SUBTRACT) pipeline.

3.3 Panel Feature Sub-Dialog Map

From the main panel dialog (mp_dlg), the user accesses feature dialogs via toggle checkboxes. Each feature has its own DCL dialog with N repeating “slots”:

Feature

Dialog

DCL File

Slots

Controls/Slot

Total Data Points

Rough Openings

ro_dlg

ro_dlg.dcl

4

15

60

Standard Openings

wd_dlg

wd_dlg.dcl

6×2pg

10

120

Man Doors

dr_dlg

dr_dlg.dcl

6

9

54

Dock Levelers

dl_dlg

dl_dlg.dcl

3

16

48

Rect. Blockouts

sb_dlg

sb_dlg.dcl

6

17

102

Round Blockouts

rb_dlg

rb_dlg.dcl

6

9

54

Horiz. Features

fh_dlg

fh_dlg.dcl

19×3pg

25

475

Vert. Features

fv_dlg

fv_dlg.dcl

19×3pg

19

361

Pilasters

pl_dlg

pl_dlg.dcl

2

17

34

Lintels

ll_dlg

ll_dlg.dcl

2

20

40

Top Plate

tp_dlg

tp_dlg.dcl

1

13

13

Ledger Bar

lb_dlg

lb_dlg.dcl

1

85

85

Chamfer

ch_dlg

ch_dlg.dcl

1

30

30

Top Steps

ts_dlg

ts_dlg.dcl

2

7

14

Footing Steps

fs_dlg

fs_dlg.dcl

2

7

14

Spandrel Seats

ss_dlg

ss_dlg.dcl

2

9

18

Slab Dowels

sd_dlg

sd_dlg.dcl

4

7

28

Brace Points

bp_dlg

bp_dlg.dcl

8

4

32

Pick Points

pp_dlg

pp_dlg.dcl

8

5

40

Weld Connections

wc_dlg

wc_dlg.dcl

15×5pg

41

615

TOTAL

~2,237

3.4 Batch Processing Workflow

Step  Dialog/Function    User Action                        Code Path
────  ─────────────────  ─────────────────────────────────  ──────────────
 1    md_dlg             Click "Batch Utilities"            md_dlg.lsp
 2    btch_dlg           Select panels, operation, layers   btch_dlg.lsp
 3    btch()             Generates .scr script file         btch.lsp
 4    AutoCAD            Executes btch.scr → opens panel    (script engine)
 5    panel() or plt()   Redraws and/or prints panel        panel.lsp/plt.lsp
 6    btch()             Recursion: next panel in pnllst    btch.lsp
 7    [repeat 4-6]       Until all panels processed         —

Batch operations available:
  • Print Only (btchp=1)         → plt for each panel
  • Redraw + Print (btchp=2)     → panel + plt for each
  • Export Engineering (btchp=3)  → panel + engexp for each
  • Import Engineering            → engimp → btch loop
  • Update Drawings              → panel for each (no print)
  • Materials List               → matl_dlg across selection
  • Revision History             → revision across selection

3.5 Site Drawing Workflow

Step  Dialog/Function    User Action                        Code Path
────  ─────────────────  ─────────────────────────────────  ──────────────
 1    sdwg_dlg           Select site operation               sdwg_dlg.lsp
 2a   grid_dlg           Define grid lines (N/S/E/W)        grid_dlg.lsp
 2b   wall_dlg           Define wall lines (64 rows × 4pg)  wall_dlg.lsp
 2c   slab_dlg           Define slab edges (64 rows × 4pg)  slab_dlg.lsp
 2d   green (site)       Footing connections, joist layout   green.lsp
 2e   tiltup             Attach/detach panels to site        tiltup.lsp
 2f   layout             Construction crane layout           layout.lsp
 3    Site print          Print selected site layouts         plt.lsp

3.6 Engineering Export/Import Workflow

Export path:
  btch_dlg → "Export Data File" → engexp.lsp
    Phase 1: read panelvar from each panel → convert to primitives
             (P/R/F/T/A/G/M/C/W/B/L geometric codes)
    Phase 2: dispatch to format writer:
             ├── dreng.lsp  → Dayton/Richmond CSV
             ├── mbeng.lsp  → Meadow-Burke proprietary
             ├── wsbeng.lsp → WSB pipe-delimited
             └── wceng       → White Cap

Import path:
  engimp.lsp → read .pan file → parse headers → extract
  brace/lift/steel/strongback data → btch loop → update panels

Import path (.pnl encrypted):
  makepan.lsp → decrypt header (char code subtraction) →
  read panelvar → validate version → write XRecord → btch loop

3.7 Materials List Workflow

  matl_dlg.lsp
    ├── Read wcl.txt (weld connection library)
    ├── Scan INSERT entities on layer "0" (title blocks)
    ├── For each panel title block:
    │   ├── Count named blocks (bolts, points, connections)
    │   ├── Tally reveals: F1(¼"), F2(½"), F3(¾"), F4(1")
    │   ├── Tally chamfers: C2, C3, C4
    │   ├── Extract: SQFT, CU (yd³), PER (perimeter LF)
    │   ├── Count braces/extensions (BT, BXT)
    │   └── Match weld connections to wcl.txt library
    └── Output → matlist.txt (formatted report)

Output sections: J Bolts, Pick Points, Brace Points, Edge Form,
  Treated Lumber, Chamfer, Reveal Strip, Connections, Concrete yd³

4. Manual ↔ Code Cross-Reference Matrix

This table maps every section of the CSV Manual.pdf to the implementing code files, validating coverage and identifying gaps.

Manual Section

DCL File

LSP File(s)

Menu ID

Status

Introduction

✅ Documentation only

License Agreement

✅ Legal (updated 2026)

Limited Warranty

✅ Legal (updated 2026)

Installation

⚠️ Describes InstallShield; obsolete

System Requirements

⚠️ Lists Win95/98, 8MB RAM

Product Support

ID_CSVSUPPORT

⚠️ Phone/FAX numbers outdated

On-Line Support (pcAnywhere)

❌ Defunct: pcAnywhere removed

Drawing Setup (was “Program Options”)

md_dlg.dcl, dwgtype.dcl

md_dlg.lsp, csv.lsp

ID_CSVRUN

✅ Renamed, improved routing

Create New Drawing

dwg.dcl

dwgnew.lsp

ID_CSV16

Edit Existing Drawing

dwg.dcl

dwgold.lsp

ID_CSV0

Create New Project

new.dcl, project.dcl

new.lsp, project.lsp

ID_CSV8

Select Drawing

✅ (getfiled dialog)

Drawing Type

dwg.dcl

Batch Utilities

btch_dlg.dcl

btch_dlg.lsp, btch.lsp

ID_CSV32

View/Print All Layers

lyr_dlg.dcl

lyr_dlg.lsp

ID_AllLayers

View/Print Selected Layers

lyr_dlg.dcl

lyr_dlg.lsp

ID_CSV128

Change 3D Viewpoint

viewpt.dcl

ID_CSV3d

Print Materials List

matl_dlg.dcl

matl_dlg.lsp

ID_CSV1024

Shading

ID_CSV8192

✅ (direct AutoCAD cmds)

Print Revision History

revision.dcl

revision.lsp

ID_CSV2048

Panel — Project Details

project.dcl

project.lsp, pj_name.lsp

Panel — Drawing Details

mp_dlg.dcl

mp_dlg.lsp

Panel — Panel Details

mp_dlg.dcl

mp_dlg.lsp

Standard Opening

wd_dlg.dcl

wd_dlg.lsp, opening.lsp

Recess / Blockout

sb_dlg.dcl, nb_dlg.dcl, rb_dlg.dcl

sb_dlg.lsp, rb_dlg.lsp

Man Door

dr_dlg.dcl

dr_dlg.lsp

Dock Leveler

dl_dlg.dcl

dl_dlg.lsp

Pilaster/Lintel

pl_dlg.dcl, ll_dlg.dcl

pl_dlg.lsp, ll_dlg.lsp

Ledger / Top Plate

lb_dlg.dcl, tp_dlg.dcl

lb_dlg.lsp, tp_dlg.lsp, green.lsp

Roof Line

ro_dlg.dcl

ro_dlg.lsp

⚠️ Manual calls it “Roof Line”; code is ro = Rough Opening

Chamfer

ch_dlg.dcl

ch_dlg.lsp, chamfer.lsp

Feature Strip

fh_dlg.dcl, fv_dlg.dcl, fs_dlg.dcl

fh_dlg.lsp, fv_dlg.lsp, feature.lsp

Slab Dowels

sd_dlg.dcl

sd_dlg.lsp, dowels.lsp

Weld Connections

wc_dlg.dcl

wc_dlg.lsp, wcpage.lsp, weldconn.lsp

WC Edit

wc_edit.dcl

wc_edit.lsp, wcmod.lsp

Pick Points

pp_dlg.dcl

pp_dlg.lsp, points.lsp, pick.lsp

Brace Points

bp_dlg.dcl

bp_dlg.lsp, brace.lsp

Special Operations

✅ (in mp_dlg)

Revisions

revision.dcl

revision.lsp, donerev.lsp

Registration Manager

ID_CSVPROG

⚠️ Uses csvreg (COM-based?)

Slope Calculator

calc_dlg.dcl

calc_dlg.lsp

ID_CSVSLOPE

Data Entry Methods

slide.lsp, editbx.lsp

✅ (describes slider/editbox)

Dimensioning Conventions

drawdim.lsp, basedim.lsp

Site Drawing Options

sdwg_dlg.dcl, site_dlg.dcl

sdwg_dlg.lsp, site_dlg.lsp

Grid Lines

grid_dlg.dcl

grid_dlg.lsp

Wall Lines

wall_dlg.dcl

wall_dlg.lsp

Slab Lines

slab_dlg.dcl

slab_dlg.lsp

Attach/Detach Panels

tiltup.lsp, panatt.lsp

Construction Layout

layout.lsp

About ConstructiVision

ID_CSVABOUT

✅ (csv.hlp)

Help

ID_CSVHELP

⚠️ csv.hlp requires WinHelp (removed Win10+)

Coverage Summary

Status

Count

Meaning

✅ Verified

38

Manual section maps to working code

⚠️ Concern

6

Exists but outdated, naming mismatch, or platform issue

❌ Broken

1

pcAnywhere remote support — product discontinued


5. Data Input Analysis

5.1 Input Categories

All user data enters the system through DCL dialog controls. There are zero command-line data entry points — the program is entirely dialog-driven.

Input Type

Control

Count

Validation

Dimensional (ft-in)

edit_box + slider

1,826

rangchck.lsp

On/Off toggle

toggle

721

Boolean only

Selection

radio_button

622

Mutual exclusion

List choice

popup_list

645

Index-based

Text (names)

edit_box

~30

String length

File paths

getfiled

~5

OS file dialog

5.2 Input Validation Architecture

Validation is handled by rangchck.lsp (11,498 bytes) which:

  • Validates numeric ranges for every dimensional edit_box

  • Displays warning dialog for out-of-range values

  • Clamps values to min/max bounds

  • Handles ft-in-fraction parsing (e.g., “6’-4 1/2””)

enable.lsp and fenable.lsp handle control enabling/disabling based on toggle states and snap-to-edge selections.

5.3 Data Processing Pipeline

User Input (DCL)
  │
  ▼
updvar.lsp — Reads all dialog tile values into panelvar assoc list
  │
  ▼
panelvar — Central data store (association list, ~1,826 parameters)
  │
  ├── XRecord write → AutoCAD Named Object Dictionary
  │
  ▼
drawpan.lsp — Converts parameters to 3D geometry primitives
  │
  ├── 3D Boolean pipeline (UNION/SUBTRACT)
  ├── opening.lsp → subtracts voids from panel solid
  ├── feature.lsp → adds/subtracts reveal strips
  ├── green.lsp → adds ledger/top plate geometry
  ├── chamfer.lsp → applies edge chamfers
  ├── weldconn.lsp → inserts connection blocks
  └── miter.lsp → edge miter geometry
  │
  ▼
finpan.lsp — Post-processing
  │
  ├── centgrav.lsp → center of gravity from massprop
  ├── points.lsp → pick/brace point placement
  ├── drawdim.lsp → automated dimension chains ×5
  ├── TITLE block insert (weight, area, volume, etc.)
  └── Save .dwg
  │
  ▼
Output:
  ├── AutoCAD .dwg file (3D panel + dimensions + title block)
  ├── matlist.txt (materials list, text)
  ├── .pan/.pnl engineering data files
  └── Hard copy print via plt.lsp

5.4 Data Output Destinations

Output

Format

Generated By

Destination

Panel drawing

.dwg (R14/R2000)

finpan.lsp

Project Files directory

Site drawing

.dwg

site_dlg.lsp

Project Files directory

Materials list

matlist.txt

matl_dlg.lsp

Project Files directory

Engineering (D/R)

CSV

dreng.lsp

File specified by user

Engineering (MB)

Proprietary

mbeng.lsp

File specified by user

Engineering (WSB)

Pipe-delimited

wsbeng.lsp

File specified by user

Hard copy

Print

plt.lsp

Selected plotter

Revision history

Text

revision.lsp

Project Files directory

Batch script

btch.scr

btch.lsp

Working directory (temp)

Batch listing

cvplst.bat output

csv.lsp

Working directory (temp)


6. Critical Workflow Test Matrix

These are the workflows that must be tested for any release. Each row is an independently testable path through the system.

6.1 Core Panel Workflows

ID

Workflow

Entry

Steps

Exit Criteria

Priority

P-01

Create new project

Menu → Drawing Setup

pj_name → new.dcl → OK

Project directory created

Critical

P-02

Create simple panel

md_dlg → New Panel

mp_dlg → dimensions only → OK

.dwg with solid + dims + title

Critical

P-03

Panel with openings

mp_dlg → Openings toggle

wd_dlg → define 1+ windows → OK

Openings subtracted from solid

Critical

P-04

Panel with doors

mp_dlg → Doors toggle

dr_dlg → define 1+ doors → OK

Door openings + swing arc drawn

High

P-05

Panel with blockouts

mp_dlg → Blockouts toggle

sb_dlg → define 1+ blockouts → OK

Rectangular voids subtracted

High

P-06

Panel with round blockouts

mp_dlg → RndBlk toggle

rb_dlg → define 1+ circles → OK

Cylindrical voids subtracted

Medium

P-07

Panel with reveals

mp_dlg → Features toggle

fh_dlg + fv_dlg → OK

Reveal strips visible, hatch applied

High

P-08

Panel with pilaster

mp_dlg → Pilaster toggle

pl_dlg → define pilaster → OK

Extrusion added to panel edge

Medium

P-09

Panel with lintel

mp_dlg → Lintel toggle

ll_dlg → define lintel → OK

Extrusion added above opening

Medium

P-10

Panel with chamfer

mp_dlg → Chamfer toggle

ch_dlg → select edges → OK

Edge chamfers applied

High

P-11

Panel with top plate

mp_dlg → TP toggle

tp_dlg → define plate → OK

Greenplate geometry drawn

Medium

P-12

Panel with ledger

mp_dlg → LB toggle

lb_dlg → define ledger → OK

Ledger geometry drawn

Medium

P-13

Panel with weld connections

mp_dlg → WC toggle

wc_dlg (5 pages) → define → OK

Connection blocks placed

Critical

P-14

Panel with pick points

mp_dlg → PP toggle

pp_dlg → define 1+ points → OK

Pick point blocks placed

Critical

P-15

Panel with brace points

mp_dlg → BP toggle

bp_dlg → define 1+ points → OK

Brace point blocks placed

Critical

P-16

Panel with slab dowels

mp_dlg → SD toggle

sd_dlg → define dowels → OK

Dowel inserts placed

Medium

P-17

Panel with dock leveler

mp_dlg → DL toggle

dl_dlg → define 1+ → OK

Dock leveler openings subtracted

Medium

P-18

Panel with spandrel seat

mp_dlg → SS toggle

ss_dlg → define → OK

Spandrel geometry applied

Low

P-19

Panel with top/footing steps

mp_dlg → TS/FS toggle

ts_dlg + fs_dlg → OK

Step geometry at panel edges

Low

P-20

Panel with ALL features

mp_dlg → all toggles on

All sub-dialogs → OK

All features composed correctly

Critical

P-21

Edit existing panel

md_dlg → Edit Panel

mp_dlg loads existing → modify → OK

Modified panel regenerated

Critical

P-22

Copy panel as template

md_dlg → existing selected

New panel # → OK

New panel with copied data

High

P-23

Radius panel

mp_dlg → Radius toggle

Enter radius value

Curved panel solid generated

Medium

P-24

Opposite-hand panel

Menu → Special Ops

Select base panel

Mirrored panel created

Medium

6.2 Batch & Print Workflows

ID

Workflow

Entry

Steps

Exit Criteria

Priority

B-01

Batch print all

btch_dlg → All + Print

Select printer → OK

All panels printed

Critical

B-02

Batch redraw all

btch_dlg → All + Redraw

OK → wait

All panels regenerated

Critical

B-03

Batch print range

btch_dlg → Range

Set min/max → OK

Range subset printed

High

B-04

Batch update drawings

btch_dlg → Update

OK → wait

All panels rebuilt to current version

High

B-05

Print single panel

md_dlg → Print All Layers

Select printer → OK

Current panel printed

Critical

B-06

Print selected layers

md_dlg → Print Layers

lyr_dlg → select → OK

Filtered print

Medium

B-07

Print materials list

md_dlg → Materials List

matl_dlg processes

matlist.txt created

Critical

B-08

Print revision history

md_dlg → Revision History

OK

Revision report printed

Medium

6.3 Engineering Export/Import Workflows

ID

Workflow

Entry

Steps

Exit Criteria

Priority

E-01

Export Dayton/Richmond

btch_dlg → Export

dreng_dlg → OK

CSV file generated

Critical

E-02

Export Meadow-Burke

btch_dlg → Export

mbeng_dlg → OK

MB format file generated

Critical

E-03

Export WSB

btch_dlg → Export

wsbeng_dlg → OK

Pipe-delimited file generated

Critical

E-04

Import .pan file

engimp → browse

Parse → validate → batch

Panels updated with eng data

Critical

E-05

Import .pnl file

makepan → browse

Decrypt → validate → batch

Panels created from external source

High

E-06

Round-trip export-import

Export → manual edit → Import

Full cycle

Data integrity maintained

High

6.4 Site Drawing Workflows

ID

Workflow

Entry

Steps

Exit Criteria

Priority

S-01

Create site drawing

sdwg_dlg → New Site

project → drawing type

Blank site drawing created

Critical

S-02

Define grid lines

sdwg_dlg → Grid Lines

grid_dlg (208 edit boxes) → OK

Grid lines drawn

High

S-03

Define wall lines

sdwg_dlg → Wall Lines

wall_dlg (4 pages) → OK

Wall lines drawn

High

S-04

Define slab edges

sdwg_dlg → Slab Lines

slab_dlg (4 pages) → OK

Slab edges drawn

High

S-05

Attach panels to site

sdwg_dlg → Attach

Select panels → place

Panels referenced in site

Critical

S-06

Construction layout

sdwg_dlg → Layout

layout.lsp calculations

Crane layout generated

Medium

S-07

Print site layouts

sdwg_dlg → Print

Select viewports → OK

Site plans printed

High

6.5 Utility / Cross-Cutting Workflows

ID

Workflow

Entry

Steps

Exit Criteria

Priority

U-01

Slope calculator

Menu → Slope Calculator

calc_dlg → enter values → OK

Elevations calculated

Medium

U-02

Change 3D viewpoint

Menu → Change 3D

viewpt → select view

Viewpoint changed

Low

U-03

WC Edit (connection specs)

wc_dlg → Edit button

wc_edit.dcl → modify → OK

Connection library updated

High

U-04

Change project search path

md_dlg → options

Browse → select folder

Path updated

Medium

U-05

Version conversion

Open old panel

convert.lsp auto-triggers

panelvar upgraded to V2.25

High

U-06

Registration

Menu → Reg Manager

csvreg → enter code

License activated

Critical


7. Issues & Discrepancies Found

7.1 Broken Functionality

#

Issue

Severity

Detail

BRK-01

pcAnywhere remote support

❌ Defunct

Symantec discontinued pcAnywhere in 2014. The manual documents it extensively but the feature is dead. Remove from manual and menu.

BRK-02

csv.hlp Help file

❌ Non-functional on Win10+

WinHelp (.hlp) viewer removed from Windows Vista+. Help menu item and all acad_helpdlg calls fail silently. Need CHM or HTML conversion.

BRK-03

csv.GID index

❌ Orphaned

Global index for csv.hlp — useless without WinHelp runtime.

BRK-04

progcont routing missing from source

⚠️ Source-mode broken

Every menu item sets progcont via (setq progcont N) before calling csv;. The VLX bytecode reads progcont and routes correctly (confirmed by OCR evidence from VM 102). However, no .lsp source file reads progcont — the routing code exists only in compiled VLX bytecode from uncommitted source. The source csv.lsp uses pnl/ld variables instead. In source-mode, all menu items fall through to the same md_dlg “Panel Options” dialog. See Section 3.1a for full analysis including bitmask decoding and VLX binary evidence.

BRK-05

Source md_dlg ≠ VLX md_dlg

⚠️ Missing source

The VLX’s embedded md_dlg.dcl is “Program Options” with numeric button keys (powers of 2 mapping to progcont bitmasks). The source md_dlg.dcl is “Panel Options” with string keys ("new", "old", "val", etc.) — a completely different, lower-level dialog. The VLX version is the top-level hub that routes menu items to different features. The source version is a panel sub-feature selector. The VLX was compiled from source that was never committed to the repository. Menu renamed from “Program Options” to “Drawing Setup”; progcont routing reconstruction required for source-mode.

BRK-06

Panel/site auto-detection is fragile

✅ Fixed

Drawing type was determined by dictionary lookup with no user override; fallback always defaulted to panel mode. Now: when neither "panel_list" nor "site_list" exists, dwgtype.dcl asks the user to choose. Template detection in dwgnew.lsp also improved with *panel*,*pnl* pattern and dwgtype.dcl fallback.

7.2 Naming / Documentation Discrepancies

#

Issue

Detail

DIS-01

“Roof Line” vs “Rough Opening”

Manual section “Roof Line” refers to ro_dlg which is actually “Rough Opening.” The ROofline naming exists nowhere in the code. Confusing for maintainers.

DIS-02

Manual says “Version 10.nn”

About dialog says v10.nn but TB11 files are v11. Manual was never updated for v11 release.

DIS-03

Address discrepancy

Manual lists two addresses: Mill Creek (main) and Bremerton (support). These may both be outdated.

DIS-04

“AutoCAD 2000 or higher required”

Manual says this but also references R14 compatibility. csvcompat.lsp supports back to R14 for menu loading but program itself requires AC2000+.

DIS-05

Spanish language option

Manual notes “the Spanish option does not work very well at present.” Code has language selection in project dialog but status is unclear.

DIS-06

File path references

Manual references C:\Program Files\ACAD2000\Csv\ in multiple places. csv.prj was already updated to C:\Program Files\ConstructiVision\ but the manual still has old paths.

7.3 Unclear / Undocumented Behavior

#

Issue

Detail

UNC-01

Script recursion for batch

btch.lsp creates a .scr file that opens drawings and calls back into CV functions. If a panel has errors, the entire batch stops with no recovery. No error handling in the recursion loop.

UNC-02

Encrypted .pnl import

makepan.lsp decrypts .pnl files using char-code subtraction with fixed offsets (51+n, 79+n, 81+n, 91). This is security through obscurity — the “encryption” is trivially reversible.

UNC-03

No undo for batch operations

Batch redraw/update overwrites drawings with no backup mechanism. Manual mentions “Warning message will be displayed” but there is no undo path.

UNC-04

massprop parsing

centgrav.lsp reads massprop output from a text file generated by AutoCAD’s MASSPROP command run via script. This is fragile — depends on exact text formatting of AutoCAD’s output.

UNC-05

cv.bat / cvplst.bat

csv.lsp generates batch files at runtime for directory listing and path setup. These are not documented and may trigger antivirus warnings on modern systems.


8. Human Factors Analysis

8.1 Heuristic Evaluation (Nielsen’s 10 Usability Heuristics)

#

Heuristic

Rating

Assessment

H1

Visibility of system status

⚠️ Fair

process.dcl shows “Please Wait” but no progress bar, no % complete, no panel count during batch ops.

H2

Match between system and real world

✅ Good

Uses construction industry terminology (tilt-up, pilaster, ledger, greenplate, chamfer). Domain experts will understand.

H3

User control and freedom

❌ Poor

No undo within dialogs. Cancel loses ALL changes, not just the last one. Batch operations are irreversible. Three menu items (New Project / New Drawing / Edit Existing) promise distinct actions but route to the identical dialog — user has no shortcut to the action they selected.

H4

Consistency and standards

⚠️ Fair

Consistent edit_box+slider pattern is good. But dialog layout varies — some use pages (wc: 5 pages), some use long scrolling layouts. Toggle placement inconsistent across dialogs. Menu items suggest different functions but all lead to the same place, violating the principle of least surprise.

H5

Error prevention

⚠️ Fair

rangchck.lsp validates ranges well. But no validation on cross-field dependencies (e.g., opening wider than panel triggers warning only after drawing fails).

H6

Recognition over recall

❌ Poor

Users must remember panel numbers (3 digits), feature slot numbers, and coordinate conventions. No visual preview of panel during editing.

H7

Flexibility and efficiency

✅ Good

Template system (copy panel), batch operations, slider+editbox dual entry. Power users can work fast.

H8

Aesthetic and minimalist design

❌ Poor

DCL dialogs are dense, cluttered. wc_dlg has 615 controls across 5 pages. Wall_dlg has 711 controls across 4 pages. Information overload.

H9

Help users recognize/recover from errors

⚠️ Fair

Warning dialogs exist but error messages are terse. No suggestion of how to fix. No contextual help in dialogs.

H10

Help and documentation

❌ Broken

csv.hlp (WinHelp) non-functional on Win10+. Context help buttons call dead links. Manual is PDF-only (now also .md).

8.2 Complexity Metrics

Metric

Value

Assessment

Total data input fields

1,826 edit_box controls

Extremely high — rivals ERP systems

Max fields per dialog

615 (wc_dlg, 5 pages)

Very high — cognitive overload risk

Max dialog depth

3 levels (md_dlg → mp_dlg → wc_dlg)

Acceptable

Total unique dialogs

65

High — large learning curve

Clicks to create simple panel

~15 (menu → project → drawing → mp_dlg → OK)

Acceptable

Clicks for complex panel (all features)

~200+ across 20 sub-dialogs

Very high

Batch processing visibility

None (script recursion, no progress)

Poor

8.3 Error Probability Analysis

Based on human factors research, error rates increase with:

  • Number of data entry fields (Wickens & Hollands: ~0.3% per field)

  • Lack of visual feedback before committing

  • Similarity of adjacent controls (slot repetition)

Scenario

Fields

Est. Error Rate

Impact

Simple panel (dims only)

16

~5% (1 field wrong)

Geometry error, rework

Panel + 4 openings

76

~20% (1+ field wrong)

Subtraction errors

Panel + all features

2,237

~99% (likely errors)

Must review carefully

Weld connections (15)

615

~85% (1+ entry wrong)

Engineering safety concern

Wall lines (64 rows)

711

~89% (1+ entry wrong)

Site geometry errors

8.4 Improvement Opportunities (Modern GUI Principles)

Area

Current State

Recommended Improvement

Effort

Visual preview

None — panel drawn only after OK

Live 2D schematic preview in dialog

High

Input validation

Post-entry range check only

Real-time validation with visual indicators

Medium

Panel templates

Copy existing panel manually

Template library with thumbnail browser

Medium

Weld connections

5 pages, 615 controls

Table/grid interface with add/remove rows

High

Wall/slab definition

64-row fixed grid

Dynamic row count, add/remove as needed

High

Feature slots

Fixed N slots per type

Dynamic — add/remove features as needed

High

Undo

None within dialogs

Per-field undo stack, or dialog-level undo

Medium

Progress feedback

“Please Wait” only

Progress bar with panel count / time estimate

Low

Help system

Dead WinHelp

Embedded HTML help or tooltip-style help

Medium

Keyboard shortcuts

None in dialogs

Tab order + keyboard accelerators

Low

Data import

Manual entry only

CSV/Excel import for repetitive data

Medium

Preset management

None

Save/recall named preset configurations

Medium


9. Design FMEA (Failure Mode & Effects Analysis)

DFMEA Scope

Analyzing failure modes in the design of ConstructiVision’s user interface, data pipeline, and output generation. Severity (S), Occurrence (O), and Detection (D) are rated 1–10. RPN = S × O × D.

#

Component

Failure Mode

Effect on User

S

Cause

O

Current Controls

D

RPN

Recommended Action

1

edit_box (dimensional)

Wrong value entered (typo in ft-in)

Panel geometry wrong, physical panel defective if not caught

9

Manual data entry, 1826 fields, no visual preview

7

rangchck.lsp range validation

5

315

Add visual schematic preview; highlight changed values

2

wc_dlg (weld connections)

Wrong connection type selected

Incorrect hardware on panel, potential structural failure during tilt

10

popup_list with 15 identical slot patterns across 5 pages, cognitive overload

6

User review of printed drawing

6

360

Reduce to table/grid UI; add connection validation against structural rules

3

drawpan Boolean pipeline

Overlapping openings not detected

AutoCAD Boolean failure, corrupt solid, drawing unusable

8

No pre-check for opening intersections

4

AutoCAD error message (cryptic)

7

224

Pre-validate opening intersections before Boolean ops

4

btch.lsp script recursion

Error in one panel stops entire batch

Partial batch completion, user must identify failure point and restart

6

No try/catch in AutoLISP, script recursion pattern

5

No detection — user sees frozen AutoCAD

9

270

Add per-panel error logging; skip failed panels; report at end

5

engexp.lsp engineering export

Wrong face code (U vs D) assigned

Lift engineering receives incorrect data, brace placement error, tilt-up accident risk

10

Complex face-code logic, opposite-hand detection

3

Engineering firm reviews data independently

4

120

Add face-code validation pass; visual face-code overlay on panel drawing

6

makepan.lsp encrypted import

Decryption offset error

Corrupted panel data loaded silently

9

Fixed char-code subtraction, version-sensitive

2

Version check (“V3.60”)

5

90

Add checksum validation; deprecate char-code “encryption”

7

centgrav.lsp massprop parsing

AutoCAD output format changes

Incorrect center of gravity, pick points miscalculated, lift safety risk

10

Relies on exact text formatting of MASSPROP output

3

Manual visual check on drawing

6

180

Parse massprop with regex patterns; add sanity-check bounds

8

matl_dlg.lsp materials list

Block count misses inserted blocks

Inaccurate material quantities, cost estimating errors

7

Scans only layer “0” INSERT entities

4

User cross-checks with drawings

5

140

Scan all relevant layers; add quantity verification mode

9

convert.lsp version migration

Missing field in old format

Default values silently substituted

6

Version format changes, no field presence validation

4

Default values are industry-reasonable

3

72

Log converted fields; flag defaults vs. actual data

10

csv.hlp help system

Help file non-functional on Win10+

User cannot access contextual help or documentation

5

WinHelp viewer removed from Windows 10

10

None — completely broken

10

500

Convert csv.hlp to CHM or HTML; urgent priority

11

toggle (feature enable)

Feature left enabled with default 0 values

Zero-size geometry in panel, potential Boolean failure

7

Checkbox stays on but user didn’t enter values

5

No check for zero-value fields when enable is on

7

245

Validate: if toggle enabled, required fields must be non-zero

12

slide.lsp (slider control)

Slider snaps to integer, precision lost

Fractional dimensions rounded, panel geometry off

6

DCL slider resolution limited

4

edit_box shows actual value, user can correct

3

72

Document that edit_box is authoritative, slider is approximate

13

progcont routing missing from source

Menu sets variable that only VLX reads

In source-mode: all menu items route to same dialog (“Panel Options”). In VLX mode: works correctly — each progcont value produces a distinct dialog. VLX compiled from uncommitted source; source md_dlg.dcl is wrong dialog.

8

VLX compiled from uncommitted source; routing code + numeric-key md_dlg never checked into repo

10

VLX mode works; source-mode completely broken

3

240

Reconstruct progcont routing in csv.lsp; reverse-engineer numeric-key md_dlg from OCR evidence of working VLX dialogs

18

Panel/site auto-detection

Drawing misidentified as panel or site

Panel editor opens for site drawing (or vice versa); user cannot do site operations on misrouted drawing

7

Dictionary lookup with no user override; new-from-template uses crude filename match *site*

3

Experienced user would notice wrong dialog

5

105

Add explicit panel/site choice to project dialog; validate dictionary contents on load

14

cv.bat / cvplst.bat generation

Runtime batch file creation

Antivirus may quarantine or block execution

6

Writes .bat files to working directory at runtime

4

None — no alternative path

8

192

Replace with native AutoLISP directory listing (vl-directory-files)

15

panelvar XRecord overwrite

Cancel pressed after partial edits already saved

Some sub-dialog changes committed while others lost

7

okcanhlp pattern: each sub-dialog updvar is immediate

3

User aware of commit-per-dialog behavior

6

126

Implement transaction: buffer changes until top-level OK

16

Spanish language option

Incomplete translation

Mixed English/Spanish on drawings, unprofessional output

5

Manual admits “does not work very well at present”

2

Manual warns user

3

30

Either complete the translation or remove the option

17

btch_dlg panel selection

“Select All” selects damaged/incomplete panels

Batch processes panels that will fail

5

No validation of panel health before batch start

4

Individual panel errors may crash batch

7

140

Pre-validate panel data before batch processing; report unloadable panels

19

AutoCAD profile/registry

Menu registration missing from profile

CV menu not visible; csv; command fails with “setvars Function cancelled” when menu-dependent code paths execute

8

Profile migration, registry corruption, incomplete install, or VM cloning without full config

3

None — silent failure until menu item invoked

7

168

Add menu registration check to Configure-ConstructiVision.ps1; validate on startup; add recovery path

20

Startup Suite / VLX loading

VLX crash during Startup Suite load

AutoCAD crashes with 0xC0000005 at LocalizeReservedPlotStyleStrings+533; CSV command unknown

9

Startup Suite loads VLX before printer/plot subsystem is fully initialized; incomplete installation environment

3

None — crashes silently on startup

8

216

Defer VLX loading via acaddoc.lsp; investigate printer/plot config dependency; add to deployment script

21

Project Settings / registry

Project path not registered

File Open dialog cannot navigate to project drawing subdirectories; user cannot open sample/project drawings from CV dialogs

7

Manual/incomplete installation skips registry key creation for Project Settings\CV\RefSearchPath

3

None — user must navigate manually

6

126

Add RefSearchPath registration to Configure-ConstructiVision.ps1; validate project paths on startup

31

CV Update per-user registry

New user profile has no CV configuration

When a new Windows user logs in and opens AutoCAD, ConstructiVision is completely unconfigured: no Startup Suite, no search path, no project paths. CV does not load.

9

CV Update writes to HKCU only; no mechanism to configure all user profiles or provide a machine-level default

3

None — user sees blank AutoCAD with no CV menu

8

216

Enumerate HKEY_USERS profiles in CV Update; or add first-run self-configuration in csvmenu.lsp/acaddoc.lsp; or configure HKLM default profile template

32

cvplst.bat PATH resolution

cvplst not found by AutoCAD shell command

btch_dlg hangs in infinite loop waiting for pnllist.txt that will never be created; AutoCAD appears frozen; user must task-kill

8

csv.lsp creates cvplst.bat in acaddir but shell command PATH may not include acaddir; works in VLX mode but not guaranteed in source mode

3

None — AutoCAD appears completely frozen

8

192

Use full path (strcat acaddir "cvplst") in btch_dlg.lsp shell call; or create cvplst.bat in curdir

33

Site drawing path resolution

Site drawing path malformed or file not found

Drawing open fails with “Cannot find the specified drawing file”; site workflow completely blocked

7

Path construction for site drawings depends on correct curdir, project setup, and drawing filename; crash cascading from prior test may corrupt state

3

Error dialog visible to user

6

126

Validate file existence before (command "open" ...) call; add defensive path checking

34

progcont dispatch context gate

CV menu command executed with no project loaded

Operation runs against AutoCAD install directory or default untitled drawing; pj_name produces garbage project name from ACAD install path; files read/written to install dir

5

progcont > 1 dispatch block had no project-context guard; analog of the existing guard on the default (pc=1) path was missing

3

None — command ran silently in wrong context

3

45

Add pre-check: if (or (= acaddir curdir) (= olddwg nil)) and progcont > 1 and progcont /= *pc-new-project*, alert user and abort. Fixed: Bug 92, commit a9146d1f

35

scr.lsp VLA document switch

COM/ActiveX VLA calls crash .NET Core CLR

AutoCAD 2024+ crashes with 0xC0000005 ACCESS_VIOLATION in coreclr.dll during (vla-open) + (vla-activate). Application terminates — user loses unsaved work. Edit Existing Drawing completely non-functional.

9

AutoCAD 2024+ migrated from .NET Framework to .NET Core; legacy COM interop path through coreclr.dll has incompatible memory management or thread marshaling

7

None — crash is silent (no error dialog before termination); only CER minidump captures the event

3

189

Replace all vla-open/vla-activate with (command "_.open" ...). Audit ALL VLA/ActiveX calls for AutoCAD 2024+ compatibility. Fixed: Bug 93, commit 64d8675a5. UPDATE 2026-05-20 (CV-526): the (command "_.open") replacement is INCOMPLETE for document-SWITCHING — from document context it leaks the filename (Unknown command "DWG") and does not make the new doc active. The verified .NET-native fix is the plugin open_documentApplication.DocumentManager.Open from a CommandFlags.Session command (no COM, no leak, real doc-switch). Used by the CvLab anchor harness; vendored at tools/autocad-mcp-plugin

36

scr.lsp / csv.lsp path logic

_.open sub-prompt or path derivation fails on modern installs

Drawing does not open: “Unknown command DWG” leaks to command line (Bug 94); default directory points to My Documents instead of CV Project Files (Bug 96); project getfiled never shown because while loop condition always false (Bug 97). Edit Existing Drawing flow blocked at multiple points.

7

AutoCAD 2025+ _.open with filedia=0 may have different sub-prompt sequence; dwgprefix on untitled drawings = Documents; (= acaddir curdir) comparison assumes legacy install layout where CV lived inside ACAD dir

5

[CSV] trace points added (commit cb3a1a472); findfile guard on scr.lsp

4

140

Investigate _.open prompt sequence in AC2027 interactively; use projdir derived from (findfile "csv.lsp") instead of acaddir. Bugs 96/97 fixed: commit e5ad3aa41. Bug 94 still open.

37

csv.lsp error handling

Silent failures: (exit) terminates with no output; no *error* handler

Errors during c:csv silently abort the entire command. No diagnostic output reaches the command line. Sysvars not restored after failure — AutoCAD left in modified state (cmdecho=0, osmode changed, etc.). Debugging requires guessing which function failed.

6

Pre-existing code design: (exit) used as bail-out with no error message; c:csv modifies ~60 sysvars with no handler to restore them on failure

4

None — errors propagated to default AutoCAD handler with generic “; error:” message

7

168

Install *error* handler in every c: command (Copilot Rule 19). Replace all (exit) with diagnostic messages + clean bail-out. Fixed: Bugs 98/99, commit cb3a1a472.

38

panatt.lsp / mp_dlg entry path

Panel data initialization assumed for all mp_dlg callers — panatt blocks new drawings

panatt reads XRecord for panel attributes; if pnl=“new” no XRecord exists yet, panatt returns nil data. Downstream wclist.lsp crashes on nil file path. “Create New Project” flow completely blocked.

7

mp_dlg always calls panatt before presenting editor; no guard for pnl=“new” where XRecord has not been written yet

6

None — crash is immediate and visible (“bad argument” error)

5

210

Skip panatt when pnl=“new”; use convert.lsp defaults instead of XRecord read. Fixed: Bug 100, commit 95730f624.

39

projdet.lsp / project details dialog

Project details not persisted — projdet_edit captures globals but never writes to XRecord or file

User fills all 21 project detail fields (concrete PSI, contractor, superintendent, phones, email, measurement system, precision, language, page size), clicks OK. Data appears accepted but is lost on AutoCAD restart. Only 5 of 21 fields partially survive via title block ATTRIBs (contractor, location, city/state/zip). 16 fields are completely volatile. VLX has compiled persistence code absent from TB11 source — same class of mismatch as DFMEA-013.

7

projdet_edit() accept callback stores all 21 values as runtime globals but never calls XRecord write, title block update, or file save. VLX/source mismatch: persistence code was compiled into VLX from uncommitted source

10

Title block ATTRIBs partially cover 5 of 21 fields as fallback on reopen

3

210

Add project_list NOD dictionary (DXF 1/2/3 format matching panel_list). Write on projdet_edit accept; read on startup + dialog open. Bug 104. Design: Project Data Persistence Architecture.

40

cvxpproj.lsp / validation export

Export naming mismatch — cvxp-snapshot-globals probes bare names for csv_-prefixed globals

cvxpproj.lsp reports null for 19 of 21 project globals even when populated in memory. Only concpsi and concpcf export correctly. All contact info, measurement system, precision, language, and page size silently export as null. Diagnostic/validation data is unreliable.

5

projdet_edit() stores 19 of 21 values with csv_ prefix (csv_super, csv_dprec, csv_msys). cvxp-snapshot-globals() probes bare names (super, dprec, msys). Mismatch created when export script was written without cross-referencing projdet_edit accept callback.

10

None — export silently returns nulls; no warning or error message

8

400

Probe csv_-prefixed names first with bare-name fallback. Add individual csv_city/csv_state/csv_zip probes. Bug 103.

41

pjdll.lsp / cipher line reader

AutoLISP text-mode (open "r") returns LF not CR — line reader checks only CR, lines never terminate

csv_pjdll-read-line-bytes reads entire pj.dll as one garbled line. Cipher decoder returns nil for all 58 fields. pj.dll data (schedule, notes, estimator, and 55 other fields) silently missing from Project Details. No error message — silent data loss.

7

AutoLISP (open ... "r") is text mode on Windows; C runtime translates CRLF→LF. read-char returns LF (10) at line boundaries, not CR (13). Line reader checked only (= ch 13) — never matched.

8

None — decoder silently returns nil; no error logged to command line

4

224

Check for CR (13) OR LF (10) as line terminator. Fixed: Bug 105, commit e16f8f898.

42

projdet.lsp / pj.dll import gate

Import gate condition triggers on wrong field — blocks pj.dll-only data import

pj.dll import never fires even when pj.dll exists and contains valid data. Schedule, notes, estimator fields permanently empty. User sees empty fields in Project Details despite pj.dll file existing in project directory.

7

Import gated on csv_contractor empty. Title block ATTRIBs populate csv_contractor via csv_read-title-block before pj.dll check runs. Gate evaluates false → import skipped. Fields exclusive to pj.dll (schedule, notes, estimator) have no other data source.

8

None — import silently skipped; no log message

5

280

Gate on pj.dll-exclusive fields (csv_schedule, csv_notes, csv_estimator) instead of shared fields. Fixed: Bug 106, commit e16f8f898.

43

csv.lsp / csv_dwgtype Tier 1

First c:csv call — panatt errors during csv_dwgtype auto-detect, *error* masks error from caller

First c:csv invocation on a panel drawing silently aborts mid-execution. vl-catch-all-apply sees normal return (no error object). progcont not cleared, csv_dwgtype stays nil, pcr stays nil. Caller cannot detect the failure. Second call works because panelvar was partially set by the aborted first call. Cascading: 4+ downstream route tests appear to fail but are artifacts of the aborted first call leaving stale state.

7

csv_dwgtype Tier 1 calls (panatt) unguarded after fresh module load. panatt errors on uninitialized state. CSV *error* handler catches the error and terminates c:csv. Because *error* handles it, vl-catch-all-apply does not see an error object — it gets *error*’s return value (nil from (princ)). No cleanup code in c:csv executes after the error point.

7

CSV *error* handler prints diagnostics (but c:csv still aborts); no vl-catch-all-apply guard around panatt

6

294

Wrap (panatt) in vl-catch-all-apply inside csv_dwgtype Tier 1 cond clause. If panatt errors, log warning but still set csv_dwgtype = "panel" (NOD check already confirmed panel). Bug 107.

44

matl_dlg.lsp / material collation

Cond default clause has stray = operator — “too few arguments” crash on custom blocks

Materials List generation crashes when any block name doesn’t match the known prefix patterns (PP*, BP*, J_BOLT, CU, Edge Form, Chamfer, Reveal, SQFT, dimension patterns, TOP_PICK, Extension, Brace, WC). The = function receives one argument instead of two → “too few arguments” error. *error* fires mid-mapcar. Materials dialog never displays.

7

matl_dlg.lsp cond default was typed as ((T = (set 'matcnt ...))) instead of (T (set 'matcnt ...)). The (T evaluates to T, then the subform (= (set 'matcnt ...)) is evaluated. = requires exactly 2 numeric arguments; with 1 it throws “too few arguments”. Syntax error in original code — likely a transcription error from the VLX source.

8

None — crash occurs inside (mapcar ...) with no guard

3

168

Remove stray = and fix double-wrapping parens: (T (set 'matcnt ...)). Bug 108.

45

matl_dlg.lsp / wcl default entry

(cons) misplaced paren — wcl default initialization crashes with “too few arguments”

Materials List dialog crashes with “too few arguments” when wcl.txt has no entry with key 0. (cons (list 0 ...) ) closes cons with 1 arg; wcl is standalone. Panel drawings where wall components don’t include a default (key 0) entry always crash. CSB001’s wcl.txt has only keys 6 and 7. Pre-existing PB11 paren bug — VLX test data always had a key-0 entry, masking this code path.

7

(set 'wcl (cons (list 0 " " 0.0 ...) ) wcl) — closing ) after (list ...) ends cons with 1 argument. wcl evaluates as standalone expression (result discarded). (cons single-arg) → “too few arguments”. Only triggered when (not (assoc 0 wcl)) is true, i.e., wcl.txt lacks a default entry.

5

Error message “too few arguments” appears but same as Bug 108’s symptom — misdirects debugging

5

175

Move closing paren: (set 'wcl (cons (list 0 ...) wcl)). Bug 109.

46

okcanhlp.lsp / cancel handlers

action_tile "cancel" callback missing (done_dialog) — 6 dialogs uncancellable

Layer dialog (lyr_dlg) traps user in uncancellable while-loop — clicking Cancel, pressing Escape, and clicking X all do nothing. Only recovery is taskkill. Same pattern affects Wall Line, Non-Rect Blockout, Window/Door Page, Weld Connections Page, WC Edit. All 6 route cancel through okcanhlp but the callback only sets state variables without dismissing the dialog. Discovered during G2-panel automated testing (test 4, View Select Layers).

7

action_tile "cancel" overrides DCL default (done_dialog 0). okcanhlp cancel handlers for ly/wl/nb/wd/wc/we set state (pnl, ok) but never call done_dialog. start_dialog blocks forever — dialog stays open. lyr_dlg has (while (/= pnl "cancel")) loop that depends on start_dialog returning; it never does. The other ~31 cancel handlers in okcanhlp are dead code — those dialogs handle cancel directly in their own action_tile calls.

8

Dialog appears to hang — no error message, no command-line output

3

168

Add (done_dialog) to all 6 reachable cancel handlers in okcanhlp.lsp. Bug 110.

47

csv.lsp, plt.lsp / layer commands

(command "layer" ...) without dash prefix opens Layer Properties Manager palette — arguments fall through

All 4 print/layer route handlers (View All Layers, Print All, Print Setup, Print Select) silently fail. Layer Properties Manager palette opens (modeless) and returns immediately; subsequent arguments (“t”, “*”, “u”, “on”, “s”, “0”) are sent to command processor as invalid commands. *error\*fires, catches error, restores sysvars, returns normally.pcrnever set to T.vl-catch-all-apply sees normal return, not error. G2 test reports DEFAULT. Same pattern in plt.lsp batch layer management.

7

(command "layer" ...) without dash prefix invokes LAYER dialog mode (Layer Properties Manager). In AutoCAD 2027, this palette is modeless — opens and returns control immediately. -LAYER (with dash) forces command-line mode where t/u/on/off/s are valid subcommands. PB11 VLX likely handled this internally or ran on AutoCAD 2000 where LAYER behavior differed. Also: View All Layers used (command "expert" 5) instead of (setvar "expert" 5).

9

CSV *error* handler prints diagnostics but hides the actual failure from the test — pcr stays nil, no user-visible crash

4

252

Change all (command "layer" ...) to (command "_.-layer" ...). Use (setvar) for sysvar changes. Bug 111.

48

Multiple .lsp files / error handling

Unguarded API return values — load_dialog nil, findfile nil, (exit) as error handler

Three failure sub-classes: (1) 47 (exit) calls terminate calling chain silently — no error message, sysvars not restored, user sees unexplained command cancellation. (2) 12 load_dialog calls pass nil/negative to new_dialog — dialog subsystem crashes. (3) findfile "acad.exe" nil passed to strlen/substr — “bad argument type: stringp nil” crash. Bugs 113 (load_dialog) and 114 (findfile) FIXED with [CSV-ERROR] guards. Bug 112 (47 exit calls) remains open — highest remaining code quality issue.

7

Original code assumed controlled lab environment: files always present, dialogs always load, acad.exe always on SFSP. No defensive nil checks. (exit) used as error handler instead of diagnostic message + clean return — violates Rule 19.

7

Bugs 113/114 fixed with [CSV-ERROR] guards + findfile diagnostics. Bug 112 unfixed — requires per-file refactoring of 47 (exit) calls.

5

245

Replace all 47 (exit) calls with [CSV-ERROR] message + clean bail-out (set pcr=T or equivalent). Bugs 112, 113, 114.

49

drawdim.lsp / dimension unit format

DIMUNIT deprecated in AutoCAD 2004+ — DIMLUNIT/DIMDEC not set, DIMLINEAR produces integer-inch output instead of architectural fractions

Panel width and span dimensions display incorrect precision (e.g., 23’ 7” instead of 23’ 6-3/4”). Fabrication decisions made from the panel drawing use wrong measurements. Discrepancy only apparent by visually comparing against golden or by sub-inch measurement.

7

DIMUNIT=6 was the AutoCAD 2000 mechanism for setting dimension units (value 6 = Windows Desktop regional format). In AutoCAD 2004+, DIMLUNIT supersedes DIMUNIT; in AutoCAD 2026 DIMUNIT is effectively read-only. TB11 drawdim.lsp set DIMUNIT but never DIMLUNIT, so DIMLINEAR inherited whatever unit format the current DIMSTYLE specified. Without DIMLUNIT=4 (architectural) + DIMDEC=2 (1/4” precision), output defaulted to integer inches. PB11 (golden) was immune: DIM1+DIMASSOC=0 embedded text via (rtos val 4 N), bypassing DIMSTYLE entirely.

9

Parity-test DXF dimension-text comparison catches sub-inch divergence from golden (Phase 9 / Bug 121); DIMDEC=4 set explicitly in 267e355df

2

126

Set (setvar "dimlunit" 4) and (setvar "dimdec" 2) in drawdim entry block alongside legacy DIMUNIT. Fixed: Bug 121 + DIMDEC=4 in 267e355df.

50

cv-gui-draw / module loader

Load-path divergence — production and the two test harnesses load LISP modules via three different mechanisms; one can silently get a stale copy from AutoCAD’s default SFSP

Edits to src/x64/TB11-01x64/*.lsp appear to have no effect in the GUI test, while the headless test sees them. Developer concludes the change is wrong, reverts, or rewrites — the actual fix is invisible. Diagnostic prints don’t fire. Days of churn before the load-path mismatch is recognized.

7

csv.lsp (production) loads each module by short name via SFSP. cv-auto-draw.lsp (headless) loads by absolute path from cv-base. cv-gui-draw.lsp (GUI) historically used short-name loading and silently picked up an older copy on the AutoCAD support path. (setenv "ACAD" ...) updates the registry but not the in-memory SFSP for the running session.

6

All three loaders standardized on absolute-path module loading; cv-gui-draw bullet-proof FILEDIA restore in 08df02112

3

126

Standardize all loaders on absolute-path module loading ((load (strcat cv-base m ".lsp"))). Fixed in cv-gui-draw 2026-05-05 + 08df02112. Smoke test pending.

51

scripts/Run-ParityTest.ps1 / log capture

Stale reports/auto-test/acad-console.log is not overwritten on subsequent runs — log file looks current (right name, right directory) but is from a previous day

Developer reads the stale log searching for (princ) diagnostics, sees none, concludes the code path isn’t executing, adds more diagnostics, repeats. ~30 minutes lost per occurrence. Misleads root-cause hypotheses. The actual current log is per-session at reports/auto-test/CSB001_<hash>.log.

4

accoreconsole.exe redirects stdout to a temp file at session start; Run-ParityTest.ps1 no longer copies that temp into acad-console.log, but the file from a prior workflow persists. No timestamp banner, no clear/truncate at run start.

8

None — the file looks alive

9

288

Either delete acad-console.log at the start of Run-ParityTest.ps1, redirect accoreconsole stdout into it explicitly, or remove it and document the per-session log path in CLAUDE.md.

52

drawdim.lsp / nested defun pattern

Nested (defun basedim …) / (defun drwbas …) / (defun elevmrkr …) inside drawdim body silently overwrites the standalone basedim.lsp, drwbas.lsp, elevmrkr.lsp modules every time drawdim is called

A developer reading elevmrkr.lsp (or modifying it) is editing dead code. The active code is the nested copy inside drawdim.lsp. Searches for “where is elevmrkr” land on the standalone first. New behavior added to standalones is dropped on the next drawdim call. Mental-model error during code archaeology.

6

csv.prj loads the standalone files at startup. drawdim.lsp redefines them as nested defuns when drawdim runs (which is on every panel draw). AutoLISP defun is global — the nested redefinition wins.

9

None — both files exist, both are loaded, no warning that one supersedes the other

8

432

Delete the standalone shadow files (basedim.lsp, drwbas.lsp, elevmrkr.lsp) and remove from csv.prj, OR extract the nested versions back to standalones and remove the nesting. Document the chosen direction.

53

drawdim.lsp / dim1 arrowhead overshoot

With DIMASSOC=0 + dimblk1=elev + arg1/arg2 0.001 apart, AutoCAD’s dim1 command emits a horizontal “tail” past the ELEV block that visibly penetrates the circle on staggered markers (snake-tongue artifact)

Right-side staggered elevation markers (e.g., WC at +11.5″ stagger) showed a horizontal line passing through the ELEV circle from inside out, visually unacceptable. Non-staggered markers looked fine, masking the bug for months. Caused multiple visual reports before the root cause (dim line extension, not leader geometry) was identified.

5

dim1 draws the dim line between defpoints with arrowhead extensions on each side equal to dimasz. With near-coincident defpoints, the extensions overshoot in opposite directions. With DIMASSOC=0 the result becomes a raw LINE entity in model space, not a managed dim — so it can’t be edited away.

7

Parity DXF leader-vertex inspection catches the snake-tongue artifact; Phase 4 + slot-9 panel-half flip in 7786f0b25

3

105

Bypass dim1 for elevation markers — entmake SOLID + 3 LINEs + INSERT ELEV + MTEXT directly. Fixed in dd-marker-l / dd-marker-r 2026-05-05 + slot-9 flip in 7786f0b25.

54

drawdim.lsp / dd-cy-l / dd-cy-r reset

Stagger trackers reset to -99999 at the start of every elevmrkr call, so markers drawn on different drawdim passes (FS/RL on the feature pass, WC on the connections pass, RL fallback on the perimeter pass) cannot see each other and overlap visually

Right-side cluster (RL at 21’-8″, WC at 21’-10½″, FS at 21’-0″, WC at 19’-11½″) collapsed onto each other within ~0.5″. Symptom: “21’-8 RL” and “21’-10½ WC” labels stacked on top of each other, illegible. Required cross-pass coordination of the kind dd-elev-multi already does within a single pass.

7

The reset comment said “reset each draw” — implying intent. The reset was correct for a single-pass model but wrong for the actual six-pass-per-panel model in finpan.lsp. Latent inconsistency between elevmrkr’s design assumption and finpan’s call pattern.

8

dd-elev-flush unified accumulator catches cross-pass overlap; parity DXF text-position diff flags drift

3

168

Move the panel-scoped accumulators (dd-l-acc / dd-r-acc) into finpan reset block; do not reset trackers per elevmrkr call; drain accumulators once at the end via (dd-elev-flush). Fixed 2026-05-05.

55

scripts/Run-ParityTest.ps1 / x32-x64 auto-sync

The parity script copies x64 → x32 only when x64 is newer. Editing x32 first does not block the test from loading the (older) x64 copy, so the developer sees the test run against unchanged code.

Developer edits src/x32/TB11-01x32/drawdim.lsp first (older muscle memory from 32-bit-first era). Headless test loads from src/x64/TB11-01x64/. Test result reflects no edit. Two cycles wasted before recognizing the canonical source is x64.

4

x64 is canonical; x32 is a derived artifact. The auto-sync is one-directional. Documentation of “edit x64, not x32” lives in inline comments and Run-ParityTest.ps1 only — easy to miss.

6

Run-ParityTest.ps1 prints “Synced N file(s) x64 → x32” when sync runs — but doesn’t warn when the developer edited x32 directly

7

168

Add CLAUDE.md guardrail listing src/x64/TB11-01x64/ as canonical and naming the auto-sync direction. Optionally have the parity script error if x32 has uncommitted changes that x64 lacks. UPDATE 2026-05-20 (CV-528): worse than one-directional — the sync was a SILENT NO-OP: Get-ChildItem $dir -Include '*.lsp','*.dcl' with no -Recurse/wildcard path matches 0 files, so the copy never ran at all (the trees could drift unbounded). CvLab Sync-CvBuildTree has the corrected filter (opt-in, NOT wired — x32 has intentional AC2000 differences). Detection control: a unit test asserts Sync-CvBuildTree actually copies. Bug 175.

56

drawpan.lsp / EXPLODE on 3D feature solids

EXPLODE’ing a 3D-strip solid produces a REGION per face (front + back + sides). Hatching all of them creates the visible front-face HATCH plus a back-face HATCH whose UCS-stored coords are at negative-x — a mirror copy off the panel

DXF has 2x the expected HATCH count per feature strip; mirror copies are off-panel and invisible to the user but bloat entity counts and obscure parity-test signal. 15 such ghosts on CSB001 (2 per strip × 4 strips + similar pattern on other features). Class: “off-panel entity creation invisible to user.”

4

EXPLODE on a 3D solid produces all 6 face REGIONs, not just the visible one. Bulk hatch via ssget "x" doesn’t filter for visibility; both faces get hatched.

8

Off-panel detector at scripts/cv-find-offpanel-entities.py + parity entity-count diff catch any reappearance

3

96

After explode-then-hatch loop, scan FEATURE-layer HATCHes and entdel any whose bbox lies entirely outside the panel (max_x ≤ 0 or min_x ≥ panel_right). Fixed: Bug 129, commit 0e8e37ebe. Generic detector: scripts/cv-find-offpanel-entities.py.

57

finpan.lsp / multi-item perimeter pass

Feature-type sections (wdvar/drvar/dlvar/llvar/fsvar/rovar/plvar) flow through finpan’s pass-6 perimeter sweep with clayer="perimeter", so their dim entities land on perimeter_dim instead of feature_dim. Pure classification drift, not visible — but breaks plot-style / layer-state tooling that depends on layer naming.

Feature-strip dims, window/door dims, and pilaster dims display correctly in GUI but on the wrong CAD layer. Engineering shops with layer-aware plot styles (.ctb/.stb) print these dims at wrong lineweight/color. Layer-state managers can’t toggle “feature dims” independently of “perimeter dims.” DWG export to other CAD systems carries the wrong layer hierarchy.

4

finpan calls (drawdim '("mpvar" "tsvar" "ssvar" "wdvar" "drvar" "dlvar" "llvar" "fsvar" "rovar" "plvar")) once with clayer=“perimeter”. drawdim appends “_dim” → all entities go to perimeter_dim. PB11/golden routed feature types separately to feature clayer.

5

Per-layer entity-type breakdown in batch parity catches layer-routing drift; Phase 5 fix in 2ef30d6ff

4

80

Split finpan’s pass-6 perimeter sweep into two sub-passes: (a) feature types → clayer="feature", (b) pure perimeter (mpvar/tsvar/ssvar) → clayer="perimeter". Fixed: Phase 5 / Bug 130, commit 2ef30d6ff.

58

drawpan.lsp / EXPLODE post-explode hatch (at-panel duplicates)

After Bug 129 / DFMEA-056 fix removed the off-panel mirror HATCHes (negative-x bbox), a residual class of at-panel duplicate HATCHes survives. EXPLODE on a 3D feature solid yields multiple coplanar regions (front face + back face after UCS rotation lands them at the same x/y bbox, plus side slivers). Bulk-hatching all surviving regions creates overlapping HATCHes whose boundary signature is identical and whose bbox lies entirely on the panel — invisible in the GUI (perfect overlap) but counted in DXF entity totals.

DXF entity count is +10 over golden on FEATURE layer (4 strips × ~2 extra duplicates + 2 panel-wide variants). User-invisible in the GUI; flagged by parity test only. Off-panel detector at scripts/cv-find-offpanel-entities.py does NOT catch them — both copies are on-panel. Bloats DWG file size and obscures parity-test signal for new feature work.

4

EXPLODE on a 3D solid produces all 6 face REGIONs. The Bug-129 cleanup removed the obvious negative-x mirror copies, but coplanar front/back faces project to the same on-panel bbox after UCS rotation, and bulk hatch via ssget "x" doesn’t dedupe by boundary signature — both regions get hatched.

7

Phase 3 dedupe in drawpan.lsp + per-layer HATCH count in parity report catch any reappearance

3

84

Add a post-pass dedupe step: scan FEATURE-layer HATCHes after explode-then-hatch, hash each by (bbox + vertex count + pattern name), entdel duplicates. Fixed: Phase 3 / Bug 131, commit 15d83a98f.

59

weldconn.lsp / drawdim.lsp wcvar single-item branch

WC dim path emits ELEV markers for every weld connection but never fires the LEADER subtype that golden uses for connections placed in tight or angled regions (e.g., near miters, near other features). Two specific WC slots in golden have an angled LEADER from a label position outside the elevation column to the actual connection point on the panel face; TB11 omits both.

DXF has 0 LEADER entities on connections_dim layer vs golden’s 2 — a -2 delta. Visual symptom: in the affected layout, the WC label sits in the elevation column but no line connects it to the actual connection point — fabricator must infer which connection the label refers to. For tightly clustered WCs or WCs in angled regions, this is ambiguous and could lead to a connection being installed at the wrong point.

5

wcvar single-item branch in drawdim emits MTEXT + ELEV INSERT but never invokes the csv_dim1 "leader" subtype. The condition under which golden emits LEADER (likely “WC closer than threshold to another marker” or “WC in chamfered/mitered region”) was either not implemented or was lost in the VLX-to-source migration.

6

LEADER/connections_dim count gated in batch parity report; Phase 4 + slot-9 panel-half flip in 7786f0b25

3

90

(1) Inspect golden DXF, identify which WC slots in CSB001 carry a LEADER and at what defpoints. (2) Trace PB11’s csv_dim1 “leader” path. (3) Add a LEADER-emission branch to wcvar in drawdim. Fixed: Phase 4 + slot-9 flip / Bug 132, commits d73e3aab8 + 0a28b287d + 7786f0b25.

60

panatt.lsp / pp/bp section decoder

Schema variance across CSB001 vs CSB002+ — pp/bp activation predicate and Y-position formula differ between schemas; a fixed-position decoder silently activates wrong rows or skips rows in mid-project panel sets

PP/BP markers appear at wrong y-coordinates on CSB002/CSB003 (pos1 used as absolute Y instead of pos1 = mpl1−Y for CSB001 schema), or activate based on the wrong field, causing some panels to render extra spurious markers and others to drop legitimate markers — fabricator gets the wrong PP/BP placement in the panel book

8

Two distinct schemas in the wild for the pp/bp NOD XRecord rows; original decoder was matched only to CSB001’s schema; CSB002+ panels use a last-element=1 universal activation flag with pos0 indicating Y-formula schema

7

Universal last-element activation flag + pos0-based schema detection (Phase 1 panatt rewrite); per-panel batch parity report flags any pp/bp row count anomaly

5

280

Decode pp/bp activation via universal last-element flag; switch Y-position formula based on pos0 (CSB001=2/1 → mpl1−pos1; CSB002+=0 → pos1 directly). Fixed: commits 5b45a64ea, 263bc5457, 786501ff9.

61

drawdim.lsp / wcvar narrow-dim leader

Narrow X-edge dim with DIMTAD=1 + DIMTIX=0 floats text above the dim line, while the inboard WC label leader points the opposite direction — creating a “snaketongue” fork where the dim text and annotation leader land on opposite sides of the dim line

Visually ambiguous label cluster on lower-half R-side WC slots: dim text floating up, annotation leader plunging down-left, fork-shaped around the dim line — fabricator must read past the visual artifact to identify which connection is being labeled

5

Fixed leader angle (210° R-side) was correct for upper-half slots (which need to clear the PP/BP dim band above) but produced a fork against the floating dim text on lower-half slots

6

Leader-angle heuristic flipped by panel-half: lower-half slots tilt up-inboard (150° R / 30° L), upper-half slots tilt down-inboard (210° R / 330° L); parity DXF leader-vertex inspection catches reappearance

6

180

Tilt the wcvar single-insert leader UP when the slot is in the lower half of the panel (cy < mpl1/2), DOWN when in the upper half. Fixed: commit 7786f0b25.

62

csvutil.lsp / csv_dim1 “leader” subtype

csv_dim1 with the “leader” subtype emits an unwanted shoulder/hook line in addition to the bare leader, colliding with adjacent entities in tight regions; AC2027 also deprecated the underlying DIM1 LEADER subcommand

WC annotation leaders had a stray ~22” horizontal LINE extending beyond the leader tip — collided with PP at slot 33 in CSB001 (e.g., x=223.75) and with adjacent dim text in tight clusters; visual clutter and ambiguity

4

csv_dim1 “leader” wraps DIM1 LEADER which historically appended a horizontal annotation shoulder for text underline; AC2027 dropped DIM1 LEADER entirely so direct port produced only the MTEXT half — neither path produced a clean LEADER+MTEXT pair

7

Replaced csv_dim1 “leader” calls in wcvar with direct entmake LEADER + entmake MTEXT — single MTEXT at tip, no shoulder; parity DXF entity-count diff (LEADER vs LINE) catches reappearance

6

168

Bypass csv_dim1 “leader” for wcvar single-insert WC labels; emit LEADER + MTEXT directly via entmake, attach 71=4 (Middle-Left) for L-side / 6 (Middle-Right) for R-side. Fixed: commits 70af07115, 9c5ac9da2.

63

drawdim.lsp / entmod after csv_dim1 (latent)

AC2027 with DIMASSOC=0 — (entlast) after csv_dim1 returns the rendered MTEXT, not the DIMENSION metadata entity, so any subsequent entmod that intends to override the DIMENSION’s group 11 (text-mid) silently modifies the MTEXT’s x-axis direction vector instead

Phantom hook lines and stray “diagonal leader with no label” — the entmod fired on the wrong entity, so the dim looked like it had a leader pointing at empty space; latent because the rendered visual was still mostly correct, just decorated with a useless artifact

7

DIMASSOC=0 triggers AC to flatten the DIMENSION block into raw entities; the DIMENSION metadata is preserved but is no longer “last” — the rendered MTEXT is. PB11 / older AC kept DIMENSION as entlast, hiding this divergence

6

None at runtime — the entmod call returned successfully (it did modify some entity), so error monitoring did not flag it; only DXF inspection of the modified entity’s group codes revealed the discrepancy

8

336

Avoid (entlast) + entmod for DIMENSION group-11 overrides post AC2024+. Either supply explicit group 11 to csv_dim1 at creation, or accumulate the dim’s entity name from (ssget "L") after the rendered fan-out completes. Encountered during Phase 4; current path bypasses entmod entirely — but warrants explicit DFMEA row because any future code that assumes entlast = DIMENSION will hit this.

66

weldconn.lsp / WC type-table lookup

(assoc x14 wcl) returns nil when the WC type referenced in panel data isn’t in the project’s wcl.txt → gate at weldconn.lsp:680 silently drops the WC; if it had run, placecon would nil-deref on (nth 2 (assoc x14 wcl)). Affects 9 of 13 distinct WC types in the CSB Sample Building corpus (the project’s own wcl.txt only has keys 0/1/6/10/11/12; panel data references types 2/3/4/5/7/8/9 too). User context (2026-05-07): in production this is testism — the dialog has no missing-type option for current customers; only legacy file up-conversion can trigger it, and few customers have legacy files. Defensive fix is still required for legacy migration safety

Fabricator panel book missing entire WC stacks — embed slots that should be drawn at panel-edge connection points are silently absent; only the WC summary table at the bottom hints that something exists. Single-panel parity test on CSB001 happened not to expose this because CSB001 only uses covered types. The 59-panel corpus sweep makes it visible: 56 of 59 panels have at least one WC silently dropped

8

Two distinct paths to the bug. (1) Customer wcl.txt is incomplete or stale relative to the panel data the project has accumulated (legacy file scenario). (2) Source-code gate intentionally skips type 0 (“not configured / default”) to prevent crashes; the same gate also accidentally skips legitimate types missing from wcl. The text-file-as-catalog architecture (per-project mutable copies) makes both paths likely

9

Multi-panel batch parity sweep + per-layer entity count surfaces the silent drop; post-fix 1c613c30 the source-code fallback emits a RED INSERT (block contents color 1, name suffixed _FB<orig>) + RED warning TEXT below the WC notes table AND a [CSV-WARN] line to CLI — visible in the printed panel book. Detection control validated by 59-panel sweep showing zero entity-count regression on panels not exercising the fallback.

4

288

(i) ✅ Tactical (A6, landed 2026-05-07 in 1c613c30): source-code fallback at weldconn.lsp:680. Computes panel’s most-common WC type via csv_compute-wc-fallback-type pre-pass; substitutes x14 with the fallback when type missing; placecon checks _wc_used_fallback flag, suffixes block name with _FB<orig>, uses color 1 (RED) for SOLID + 4 LINEs of block geometry. Post-table emits one RED TEXT per fallback occurrence: Slot K: type N not in catalog; placeholder = <fab> (RED). Plus [CSV-WARN] to CLI. (ii) Strategic: replace per-project wcl.txt with a structured global catalog (SQLite / JSON registry / cv-web data layer / XData library .dwg); see Plan §“Catalog data must move out of text files”. Test fixture in Run-BatchParity.ps1 already expanded to all 13 types as parity-test workaround (commit 322c6133d).

67

weldconn.lsp / WC summary table generator RETRACTED 2026-05-07

Hypothesis: bottom-of-panel WC summary table iterates the entire wcl alist… Investigation of CSB005 and CSB046 entity diffs disproved the hypothesis: the table generator at weldconn.lsp:1004-1037 ALREADY filters via (ssget "x" ...) and (if (> _wc_cnt 0) ...) — only types with at least one INSERT on the panel produce a row. CSB046 TEXT/connections_dim went 28→16 post-fixture (FEWER rows, not more). The +51 shift on CSB046–049 was composite: +63 title-block-exploded (accepted #170/171/174), −25 ATTRIB layer 0 (same), +28 feature_dim entities (Phase 5 layer routing), −39 connections_dim (Phase 4 consolidation).

~~~~

~~~~

~~~~

~~~~

~~~~

RETRACTED. No source-code change required; the table generator is correct. The actual finding is DFMEA-068 (pre-DXF baseline staleness) below.

71

panatt.lsp RL-SCAN / multi-segment Roof Line decoder

RL-SCAN captured only the FIRST active lt-section row matching pos8≠0 pos14=1, ignoring additional active rows. CSB022 has 2 contiguous RL segments (rows 7+8) at very different elevations. Decoder produced csv_rl_elev_l=210.88, ignored row 8’s 333.0.

Fabricator panel book shows roofline at wrong elevation on multi-segment panels. CSB022 left RL drew at 17’6 7/8” (210.88”) and right RL at 17’8” (212”) instead of golden 27’9”/28’2”. Cascading effect: WCs that reference “Roof Line” sentinel resolve to wrong elevation (Bug 144).

8

One-line gate (not csv_rl_elev_l) exited the RL-SCAN loop after the first match. Schema-supported multiple segments (different rows for left vs right rooflines) but the decoder didn’t iterate.

4

Multi-panel batch parity sweep + GUI walkthrough flagged the issue (entity-count diff insufficient because the wrong elevation produces same entity count).

7

224

Fixed 2026-05-07 in commit a96cedb83. RL-SCAN now builds panatt_rl_list of (x_start, elev_l, x_end, elev_r) tuples; csv_rl_elev_l/r preserved for backward compat (first segment). Verified on CSB022: 2 segments captured matching golden values. D drops 7→3 (validated control = list-builder + GUI verification on multi-RL panels). RPN 224→96.

72

drawpan.lsp / single-RL drawing

drawpan emitted ONE DASHED LINE using csv_rl_elev_l/r as endpoints across the full panel. Two-roofline panels rendered as one continuous mis-elevated line.

Visual: roofline appears wrong on the panel. Per CSB022 user GUI walkthrough: “the roof line does not run the whole length of the panel but instead starts at 4’11 3/4” and end on the right edge of the panel” — symptom of the single-line approach using mismatched left/right elevations.

6

Original code assumed single-RL panels; multi-RL was never in the original CSB001 baseline so the simplification went unnoticed until CSB022 was added.

4

GUI walkthrough; pre-DXF entity comparison would also flag the missing second LINE on connections layer.

6

144

Fixed 2026-05-07 in commit a96cedb83. drawpan iterates panatt_rl_list and emits one DASHED LINE per segment. Legacy single-RL fallback preserved when panatt_rl_list is unbound. D drops 6→2 (validated by pre-DXF LINE count + GUI verification). RPN 144→48.

73

panatt.lsp WC-on-RL elevation resolver

WC slots with wce="Roof Line" sentinel resolved to csv_rl_elev_l + offset unconditionally, regardless of which RL segment the WC’s X position fell under. Multi-segment panels: all WCs forced to first RL’s elevation.

Safety-critical — welder installs WC hardware at wrong height. CSB022 user observed WCs supposed to be on upper RL (~338”) were drawn at lower RL + offset (~215”). Per fabricator inspection of panel book: visual WC position would be ~10’ below where lift should occur.

9

Decoder used the single legacy csv_rl_elev_l global; per-segment routing wasn’t supported because RL-SCAN itself didn’t capture multiple segments.

5

GUI walkthrough; visual position verification on multi-RL panel. Tier 1 entity-count parity catches the wrong COUNT of WCs but not the wrong ELEVATION.

8

360

Fixed 2026-05-07 in commit a96cedb83. New helper csv_resolve-rl-elev (x_abs offset) does per-segment lookup with linear slope interpolation. WC-on-RL slot decoder calls it with the WC’s absolute X (computed from wcd + wcq). Verified on CSB022: WC slot 26 anchor resolves to y=342.22 (correct, was 215.60). Multi-insert repeats inherit anchor Y — limitation tracked separately. D drops 8→3. RPN 360→120.

70

panatt.lsp PP-DECODE + pick.lsp / per-row vs grid layout mismatch (FIXED)

TB11 source-mode PP-DECODE assumes pick.lsp’s “4 cols × 4 rows = 16 grid” model, but the NOD compact data uses two distinct schemas neither of which matches the grid: (a) CSB001 schema (pos0=2, pos6=0) — each (elevation, side) row encodes ONE PP with its own L/R distance. 4 NOD rows = 4 PPs (one per row). L distance VARIES by elevation. (b) CSB022 schema (pos0=0, pos6>0) — each (elevation, side) row encodes a SET of PPs spaced by pos6 from a starting offset pos5. pos5=29 + pos6=78 → PPs at 29, 107, … until panel midline. STANDARDS-TRACE: ACI 551R-92 §2.12.3.2 — pick-point grid up to 16 PPs, layout (4×4 or 2×8) depends on panel aspect ratio.

Source-mode produces wrong PP count + positions on most panels. CSB022: 4 PPs drawn instead of 8 (missing right-side mirror). CSB001: 4 PPs drawn at x=59 for both elevations instead of x=59 (lower) and x=51.625 (upper) per VLX-rendered pre-DXF. GUI inspection by user 2026-05-07 surfaced both.

8

Original PP-DECODE only captures the FIRST L distance and FIRST R distance; pick.lsp grid loop assumes ppd1-4 are 4 columns shared across all rows. Neither schema fits this model: CSB001 needs per-row distance; CSB022 needs spacing-based expansion.

7

None at runtime — PP entities draw, just at wrong positions / count. Visible only via GUI comparison against pre-DXF. Tier 1 entity-count parity caught the bug because CSB022 redraw produces 4 PP INSERTs vs pre-DXF 8. Bug 141 from CSB022 GUI walkthrough.

3

192

Fixed 2026-05-07 in commit b93381bce. Approach (i): PP-DECODE builds explicit panatt_pp_list of (x, y, is_top) tuples; pick.lsp iterates the list when bound, falls through to legacy grid loop otherwise. Both schemas (CSB001 per-row, CSB022 spacing) handled natively. Gap-deduction inset (x_L = pos5 + mpgl, x_R = mpw1 − pos5 − mpgr) matches pre-DXF convention. CSB001/002/003 remain PASS; CSB022 PP count 4 → 8 with all positions matching pre-DXF exactly. D drops 7 → 3 (validated control = list-builder + corpus sweep gate). Symmetrical BP fix still pending.

69

pick.lsp / PP block-name + geometry truncation

TB11 source-mode pick.lsp:114-123 builds the pick-point block name as "PP_" + <panel_thickness> (e.g., "PP_11-25" for an 11.25” panel). The original VLX produced richer block names encoding pick-point variant + lift-hardware type (e.g., PPEdgeZZSuperLift_III, PP7-250ZZSuperLift_III). In addition to the name being truncated, the geometry inside the simpler TB11 block is missing the lift-hardware 3DSOLIDs that lived inside the VLX variant block. Symmetrical issue exists for BP (brace-point) blocks: VLX BP7-250ZZSuper_22XX truncates to TB11 BP_7-25.

Fabricator panel book shows simpler pick-point markers without the engraved lift-hardware variant indicator that mat’l-list cross-references, plus 30+ hardware 3DSOLIDs missing from each affected panel. Visual: panel face shows just the pick-point triangle, no embedded hardware geometry. Material list cross-references break because the block name no longer encodes the lift hardware variant. CSB053–059 cluster (7 small panels) shows this with −33 hardware/3DSOLID per panel; CSB046–049 cluster shows it with smaller deltas.

6

Source-mode panatt PP-DECODE / BP-DECODE doesn’t decode the pick-point variant + lift-hardware type from the NOD XRecord (or wherever VLX stored that data). pick.lsp builds a generic block name from panel thickness only. The original VLX block geometry is in the customer’s existing .dwg file but TB11 redraw creates a NEW block with simplified geometry, replacing the rich block. Like DFMEA-066 (WC silent-drop), this only manifests on legacy file up-conversion — current customers selecting from the dialog don’t see this because dialog selections use the simpler block.

7

59-panel CSB corpus sweep flags the issue via per-layer entity-type breakdown (3DSOLID/hardware delta). Pre-rebaseline reference at reports/batch-parity/pre-rebaseline-reference.csv shows the cluster. Visible-equivalence (Tier 3) GUI inspection would show the missing hardware geometry on each pick-point.

8

336

(i) Strategic (preferred): replace pick-point + brace-point block library with a structured catalog (same approach as DFMEA-066 WC silent-drop) — encode variant, lift-hardware type, geometry as data, not as block name. Source-code generates names from catalog metadata. Customer can configure new variants without code changes. (ii) Tactical (interim): extend panatt.lsp PP-DECODE / BP-DECODE to decode the variant + hardware-type fields from the NOD XRecord, then pick.lsp builds the full block name and pulls block geometry from a master library .dwg. Requires reverse-engineering VLX naming convention from pre-DXF samples (PPEdgeZZSuperLift_III, PP7-250ZZSuperLift_III, BP7-250ZZSuper_22XX) — the variant data is project-specific and not in TB11 source. (iii) Acceptance-deviation (do nothing): document as known limitation; customers who need rich pick-point blocks must keep using VLX or migrate to cv-web (Phase 10/E). This is what Phase 1-9 implicitly chose.

68

parity test methodology / pre-DXF baseline

Per-panel pre-DXF baselines were captured before Phase 1-9 source-code fixes landed (Phase 5 layer-routing fix in particular changed which layer feature dim entities go to). The headless redraw post Phase 1-9 produces correct entities on feature_dim where the pre-DXF has them on perimeter_dim (or absent). Single-pass entity-count delta vs stale baseline conflates “real bug” with “fix applied since baseline”

Corpus sweep PASS/PARTIAL/FAIL distribution is dominated by accepted-deviations and post-fix corrections, not actual bugs. The 59-panel CSB sweep showed 37 FAIL panels post-fixture; deeper diagnosis on CSB046 revealed +51 of +51 was composite of accepted #170/171/174 + Phase 5 routing fix, with no real bug behind it. PASS/PARTIAL/FAIL counts mislead engineering prioritization

5

Per-panel pre-DXF strategy was introduced (commit 2e776dcf3) to eliminate manual golden curation. The strategy is sound but the baselines need to be regenerated whenever a structural source-code fix lands; otherwise every fix shows as a “regression” in the parity report

8

Three-tier comparison cascade in Run-BatchParity.ps1: snap.dxf compared against <panel>-expected.dxf (locked-in post-fix baseline) when present, then <panel>-pre.dxf (auto-regenerated each run, captures DWG rest state), then legacy golden/<panel>-golden.dxf. Re-baseline = copy snap.dxf → expected.dxf for all panels after a structural fix lands, then re-run sweep to confirm Δ=0. Validated 2026-05-07 post-A6 (commit 1c613c30): 59-panel re-sweep with expected.dxf in place produced 59 PASS / 0 PARTIAL / 0 FAIL — full corpus at parity.

3

120

Three-tier baseline cascade landed in Run-BatchParity.ps1. Re-baseline policy: copy snap.dxf → expected.dxf for affected panels after each structural source-code change. Pre-rebaseline reference snapshots saved at reports/batch-parity/pre-rebaseline-reference.csv so prior FAIL flags remain auditable. Documented in doc 45 §“Phase 5b: Multi-panel Batch Parity”.

74

panatt.lsp panatt_section_active-p per-tag schema variance

panatt_section_active-p (line 555) was tuned to CSB001’s NOD layout where pos0 is the per-row draw-toggle. Lowes / Segale / Smartcap / Arlington Building A panels use different schema variants — pos0 stays 0 even on active rows; the real activation flag lives at pos3 (Lowes), in the entity geometry (Segale wcvar), or elsewhere. Predicate rejects every row → feature stays mp<flag>=0 → entire section silently dropped from the panel book.

Entire feature sections (windows, plates, lumber blockouts, weld connections) vanish from panel books on ~80% of the affected projects’ panels. Wrong fabricator output: openings missing in the printed book; mat’l-list cross-references break because per-feature counts read 0. Corpus sweep CV-472 measured: Lowes FDC Centralia 65-69% parity (~80 entities short per panel); Segale Properties 162/P152/P161 18-30% parity (~1000-1500 entities short on the worst); Smartcap DC North A/B 28-29%; Arlington Airport Building A 51-62%. Concrete LFC028 case: so row 1 = (0 198.25 228.0 1 8 48.0 0 72.0 0) clearly real opening data, rejected because pos0=0.

8

The predicate authors assumed CSB001’s per-tag toggle conventions generalized — they don’t. NOD layout drift across project generations (older VLX versions wrote with different per-row schemas) was never reverse-engineered. Tier 1 entity-count parity caught the FAIL panels in CSB/STS via the WC catalog miss (DFMEA-066); the predicate variance gap surfaces only when a project has different-schema rows AND the wrong predicate decision silently keeps the feature off.

9

[COMPACT] feature OFF: <tag> -> mp<flag> (no row passed activation predicate) log line ALREADY emits — but it looks identical to a panel that legitimately has no rows of that feature type. D=6 because the same log line covers both real-OFF and false-OFF cases; corpus sweep’s per-panel entity-count gap is the only discriminator. Detection drops to D=3 once Track A’s [CSV-WARN] schema-variance detected, applying fallback predicate lands and distinguishes the two.

6

432

(i) Track A — predicate loosening (in flight, Bug 163): per-tag fallback activation branches. so adds (pos0=0 AND (pos3=1 OR last-elem=1 OR pos1/2/5/7 non-zero)) predicate; pl/lt add (pos0=0 AND real downstream data); wc already has nameless-recovery via wctypes.lsp commit 947f41b0. Validates on CSB001 + worst-panel triggering panel. Projected RPN 432 → 144 (D drops 6→2 with schema-variance warning). Sprint 20 TECT042 push landed the so (CV-481) + ch (CV-482) Track-A branches (commits c19224978 + 170776d98). (ii) Track C — NOD schema-version sniffer (architectural follow-up): detect schema variant per panel (CSB / Lowes / Segale) at top of panatt_section_active-p and dispatch to right per-tag decoder. Cleans up Track A’s and-or branch sprawl; projected RPN 144 → 48 (D drops further as variant detection becomes the primary control). (iii) Track B — wcvar-from-entity-geometry import (Segale-specific, deferred): wcvar NOD empty + 46 WC<n> INSERTs in entity geometry — synthesize wcvar section from positions. RPN impact on Segale-specific panels only.

75

demo-cycle harness / modal-dialog blocking

Run-CVDemoCycle stalls indefinitely when AutoCAD shows Windows’ “File In Use — Choose a Different Name” modal dialog on the BEFORE side (drawing locked by another session). Side-by-side tiling at end-of-cycle uses stale AC window handles captured before AC re-spawned.

Dev/demo lab harness stalls; engineer waits for timeout, manually dismisses dialog, restarts. No customer impact (harness-only). Side-by-side tiling occasionally tiles the wrong AC windows (or no windows at all) because hWnd cached at script start is dead after re-spawn.

4

Demo harness scripted AutoCAD interaction without modal-dialog dispatch; assumed AC’s hWnd is stable across script lifetime. Modal dialog has no command-line interface so script just waits for an AC ready signal that never comes.

5

Script-side timeout flags the stall after N minutes; user notices wrong tile on visual inspection.

5

100

✅ Fixed in Sprint 20 (commits a6cc58281b0a2f8642 AppActivate+SendKeys final approach; 880317327 for handle-refresh). CV-484. Detection drops D=5→3 (modal-dialog handler now logs visible CLI line on dispatch).

76

feature.lsp / fs strip clip targets

Feature-strip clip pass iterated only drvar (doors) and wnvar (windows). wdvar (Standard Openings — used by TECT for non-window non-door rectangular openings) was not in the clip-target list, so fs strips ran straight through SO openings on the panel face.

Fabricator panel book shows feature strip continuous across an opening. Welder/fabricator may install or weld across a region where the panel is actually open — workmanship + safety class.

7

Original strip clip logic was written for the CSB corpus where wdvar was rarely used. TECT projects exercise wdvar heavily and surfaced the gap.

4

Sprint 20 GUI walkthrough on TECT042 caught the visible artifact; corpus sweep would also flag a strip-entity-count delta if regenerated.

4

112

✅ Fixed in Sprint 20 (commit b9353a046). CV-487. Added wdvar to the clip-target iteration so each fs strip is intersected against drvar ∪ wnvar ∪ wdvar before draw. STANDARDS-TRACE: Common-Practice (shop drawings remove all assumptions).

77

drawdim.lsp / wdvar visual annotation

Standard Openings (wdvar) previously rendered as plain rectangle outline with no internal marker or dim labels. Golden uses a dashed-X (two DASHED LINEs corner-to-corner forming an X inside the opening rectangle) plus W and H dimensions placed INSIDE the rectangle.

Fabricator must infer SO geometry from outline only — no internal label confirms width × height; corner-to-corner X marker absent means SO can be visually confused with surface texture / pattern. Visual ambiguity class.

6

Source-mode wdvar emitter was a minimal stub from early TB11 reconstruction; never reconciled against golden rendering.

4

Sprint 20 GUI walkthrough on TECT042 surfaced the gap.

3

72

✅ Fixed in Sprint 20 (commit 914f6930d). CV-488. Added two DASHED LINEs corner-to-corner + inside W/H dim entries using the new DIMZIN/DIMLUNIT settings from sibling commit 2790a1ced.

78

DCL non-ASCII literal encoding (mp_dlg ±)

DCL source files with non-ASCII glyphs (e.g., ± plus-minus) silently fail when AutoCAD reads them under a CP-1252 codepage. Octal escape \261 must be used as a literal in the .dcl source for any character outside the 7-bit ASCII range.

Dialog renders garbled glyph in place of the intended symbol. User sees ? or replacement-character box; meaning is lost. Class: cosmetic but persistent (rendered every dialog open).

4

DCL files were transliterated from PB11 source via UTF-8 round-trips; non-ASCII bytes were lost in transit on at least the ± glyph.

8

Visible in every dialog open of mp_dlg — but only noticed by users who know the original glyph was there.

6

192

✅ Fixed in Sprint 20 (commit 4b1610edf, bundle). CV-489. Switched ± to octal \261. Action: audit all .dcl files for non-ASCII bytes; canonicalize to octal escapes per CV-489 pattern. Test: open every dialog post-canonical-escape and OCR-verify glyph rendering.

79

gui-draw / MCP state-callback race

Async race between AutoCAD MCP server’s drawing-state observer and the gui-draw restore-state block. When MCP fires mid-restore, view-apply overwrites the wrong viewport state, leaving the panel zoomed wrong or CLI partially expanded.

Dev/demo lab inconsistency; occasional wrong-zoom on c:cv-gui-draw output. No customer impact (MCP is dev-tool only).

4

Original restore-state had view-apply and CLI-collapse as separate async fragments scheduled across an MCP callback boundary.

5

Visual inspection of cv-gui-draw output post-run; corpus sweep does not catch (output is dialog-correct just zoomed wrong).

6

120

✅ Fixed in Sprint 20 (commit 18f3c3096). CV-485. Sequenced view-apply + CLI-collapse synchronously inside restore-state; removed MCP-race window.

80

wd_dlg / per-side notch toggles

Standard Opening dialog previously had no per-side (L/R/T/B) notch toggle — user could only enable “notch” globally for the SO, which generated uniform notches on all four corners. TECT042 geometry requires per-corner notch control.

Fabricator gets uniform corner notches when corner-specific notches are needed. Wrong physical geometry on panels with asymmetric notch requirements.

6

Original wd_dlg DCL collapsed the notch column to a single checkbox. No per-side fields existed in the wdvar row schema until Sprint 20 added them.

5

GUI walkthrough on TECT042 surfaced the limitation; no automated detector.

3

90

✅ Implemented in Sprint 20 (commit c447b72c3). CV-495. Per-row L/R/T/B notch toggles with column header. Persisted to wdvar row; decoder propagates to drawpan emitter.

81

DCL key case-insensitivity (wdT vs wdt collision)

DCL key lookup via get_tile and action_tile is case-insensitive. wdT and wdt keys silently alias to the same callback. Click on T (top-notch toggle) also triggered t (legacy per-row trim toggle) and vice versa. Latent: no error, no warning, just wrong state.

Wrong wdvar field persisted on user click; SO row reflects state changes the user did not request. Discovery only via dialog functional test.

7

DCL author idiom (any AutoLISP/DCL developer) — mixed-case naming under the assumption keys are case-sensitive like LISP atoms. AutoCAD silently binds both spellings to the same tile callback.

5

Sprint 20 dialog walkthrough on TECT042 surfaced the cross-firing toggle behavior.

4

140

✅ Fixed in Sprint 20 (commit 2d811a416). CV-496. Renamed case-clashing keys to disjoint forms. Action: project-wide audit for any DCL key pair differing only in case; rename per CV-496 pattern. Add lint rule to scripts/cv-dcl-keylint (future work).

82

Validation harness / source-dwg safety

The draw pipeline’s qsave (finpan/cv-gui-draw) writes back into the OPEN dwg; validation that opened the SOURCE directly mutated src/Project Files panels + byproducts (-panel-dump.txt, -post-finpan.dxf).

Corrupts the golden source drawing during a test run; silent dirty diff in git; repeated source-restores.

7

Validation opened the source path instead of a scratch copy; the pipeline’s qsave is unconditional.

7

git status after a run shows dirtied source — not caught at runtime.

3

Fixed 2026-05-20 (CV-529, commits 173fe243b/f514b88e1). All validation paths (gate Run-CVAutoTest, anchor Invoke-CvAnchorBatch, Run-BatchParity, Run-ParityTest, Run-CVDemoCycle) open SCRATCH COPIES; sources stay read-only. RPN 147. Bug 173.

83

finpan title-block / fixed-annotation placement

A title-block frame relocation (logo-banner clearance, 2026-05-12, finpan centroid 70.525→63.0) left a pre-existing custom-layer MTEXT note (“Roof Line = Joist Bearing”) OUTSIDE the printed frame.

Customer-facing drawing defect: a standard note prints off-sheet / outside the title block.

6

Note was a saved free-floating custom-layer entity, not a title-block ENG field; the frame moved, the note didn’t.

5

Visible on print / Tier-4 before-after compare.

3

Fixed 2026-05-20 (CV-532, commit 0f33182eb). Note captured into ENG4/ENG5 (directly under ENG3 Exp. Gap); stray MTEXT erased. Control: standard notes belong in title-block ENG slots, not free MTEXT. RPN 90. Bug 174.

84

Tier-4 print pipeline / physical-printer pacing

A physical -plot blocks the AC command processor ~12-20s while spooling; on a full book the printer queue backs up (Canon hit 38 jobs), the CLI-clear wait times out, and the next gui-draw fires into a busy CLI → draw fails / cascades. Also: run status “OK” = drew+queued, NOT physically printed — a dropped/cleared print is not detected.

A long physical book run drops panels (no page) and/or stalls; progress shows OK for pages that never came out.

6

Inkjet print speed << page-generation speed; spool blocks the single AC command processor; no print-completion verification.

6

Watch printer queue depth + paper output; the run’s OK status does not reflect physical print.

4

Mitigated 2026-05-20 (CV-527): per-panel retry + clean-CLI restart, 90s CLI-clear wait, print-queue pacing (drain ≤8). Residual: print-completion not verified → R33. RPN 144. Bug 175 (related).

85

CV-IDN spend pipeline / retry storm

Network blip between cv-web/cv-cad and /spend triggers client retry without idempotency. Two retries land — ledger inserts two -1 rows, user is double-charged.

Customer is silently charged twice for one export. Trust loss; refund work for ops.

8

UUID idempotency_key is generated client-side; if client retries without preserving the key, the unique constraint doesn’t fire.

3

(a) Spend endpoint hard-fails on duplicate idempotency_key (unique constraint) and returns prior row; (b) exportGateway generates the key once per export and reuses it for the retry stamp; (c) _shared/auth.ts rejects mismatched body.app vs caller app.

4

96

Add client-side unit test in exportGateway.test.ts: simulated 5xx mid-flight followed by retry must use the same idempotency_key. CV-IDN bug bar.

86

CV-IDN stripe-webhook / drop

Stripe webhook delivery fails or is delayed; balance/membership state diverges from Stripe truth. Customer paid but cv-web still shows old balance and refuses exports.

Customer-facing trust hit (paid but can’t export). Support escalation.

7

Edge-function 5xx, Supabase project bounce during deploy, expired webhook secret, or Stripe-side outage.

3

(a) Webhook handler is idempotent on stripe_event_id; (b) Stripe auto-retries with exponential backoff for 3 days; (c) ops runbook covers webhook re-enable + event replay; (d) cv-web window-focus refresh + ?checkout=success cleanup re-fetches entitlement after redirect.

5

105

Synthetic monitor: post a test event every 15 min via Stripe CLI; alert if stripe_event_id doesn’t land in token_ledger within 30s. Doc CV-IDN runbook §“Incident: Stripe webhook outage”.

87

CV-IDN OAuth provider outage

One of five providers (Google/Apple/LinkedIn/Dropbox/Autodesk APS) returns 5xx during OAuth dance. New users blocked from that provider; existing users with active session unaffected.

New-user signup conversion drops for affected provider until outage clears.

5

Provider-side outage, deprecated OAuth API version, or revoked client credentials.

4

(a) Five providers + email/password = 6-way fallback; (b) SignInPanel shows all options; (c) status banner runbook turns on provider-specific message; (d) email/password always enabled.

5

100

Synthetic monitor each provider’s auth endpoint hourly; if 5xx for >10 min, post status banner via app_config row. Doc CV-IDN runbook §“Incident: OAuth provider down”.

88

CV-IDN offline grace / abuse

cv-cad offline grace allows optimistic spend if cached entitlement < 24h old. Adversary cuts network and burns through far more exports than tokens cover, expecting offline reconciliation.

Negative-balance accounts; ops must claw back via Stripe disputes. Revenue leak proportional to user fleet × 24h × export rate.

5

Cached entitlement file is local and tamper-able; reconciliation happens on next online sync.

3

(a) 24h grace window cap; (b) optimistic spends queued with idempotency_key — once online, /spend rejects them if balance < queue depth; (c) negative ledger rows allowed (collections review flag); (d) operator manual review of any account that goes negative > 5 tokens.

6

90

Lower grace cap to 4h for new accounts (first 30 days); add automated collections-review alert on first negative-balance crossing. Tracked in CV-IDN runbook.

89

CV-IDN Stripe / mid-cycle payment failure

Subscription card declines on renewal. Stripe sends invoice.payment_failed then transitions sub to past_due. cv-web user wakes up read-only mid-day, mid-edit, without explanation.

Member loses edit access during active work session. Trust + revenue loss if they don’t fix the card.

6

Card expired, fraud lock, address change, insufficient funds.

4

(a) Stripe Customer Portal accessible via welcome-account-link “Manage” → fix card; (b) Stripe auto-retries dunning over ~3 weeks; (c) AuthProvider window-focus refresh picks up past_due and renders ReadOnlyBanner.cv-banner-readonly with “manage” CTA; (d) period_end preserved across past_due → editor stays usable until period ends if Stripe is still retrying.

4

96

Add email-template trigger from Stripe (already supported) plus in-app banner copy: “Card declined — fix to keep editing” with Customer Portal deep link. Validate during P5 closed beta.

90

CV-IDN license JWT tampering (drawing-level)

Adversary edits the SIMPLESTRUCT_LICENSE NOD XRecord directly — flips a byte of license_jwt, swaps in a JWT they generated with alg: "none", or transplants a valid JWT from a drawing they own into a drawing they don’t.

Unlicensed drawing plots without spending tokens; or a paid drawing’s JWT gets reused across the org’s other drawings (or someone else’s) without the server seeing a spend. Revenue leak; license-per-drawing model collapses.

7

NOD XRecord is plain DXF; any user with file-level write can entmod it. The ES256 sig is the only thing standing between a tampered drawing and a successful plot.

2

(a) LicenseVerifier.VerifyOrThrow (CV-803) hard-rejects alg=none and any header.alg != “ES256” BEFORE looking at the sig (commit 3ef09314b); (b) IEEE P1363 signature shape check pre-empts DER substitution (bad_signature_shape before bad_signature); (c) jti claim MUST equal the current drawing’s NOD UUID (CV-801) — defeats JWT transplant between drawings; (d) every plot/print/export gate calls the verifier — no path skips it; (e) LicenseException fails the gate CLOSED (no artifact produced).

2

28

Production-verify all four rejection paths on AC2027 as part of CV-805 QA matrix items 7 + tamper variations. Add [CV-IDN] LicenseException("<code>") log line to every gate so support can grep tamper attempts in customer dumps.

91

CV-IDN signing-key rotation break

cv-web rotates the ES256 signing key (security incident, scheduled rotation, or operator error) without coordinating a matching Resources/license-public.pem bump in SimpleStruct.Cad.Licensing.dll. Every cv-cad install in the field has a stale public key.

Every cv-cad install starts rejecting freshly-issued license JWTs as bad_signature. Existing licensed drawings keep working (their JWTs were signed under the old key, but the old key is now revoked server-side and the cv-cad verifier doesn’t know that). New /spend calls return signed JWTs that no cv-cad in the field can verify. Customer-visible plot failure across the entire fleet within hours of rotation.

9

Rotation procedure currently lives in docs-sensitive/cv-idn/runbook.md (Track B addendum) but has no cv-cad-side handshake — cv-web rotates the server key, cv-cad doesn’t know until the next assembly ship.

4

(a) Runbook procedure stipulates: ship a new cv-cad assembly with the new PEM AT LEAST 30 days BEFORE cutting over server-side; (b) the .NET assembly version (SimpleStruct.Cad.Licensing.csproj <Version>) bumps every PEM swap so support can confirm fleet version from CVIDN_PING output; (c) JWKS lookup path is deliberately NOT implemented — embedded PEM is the single source of truth, so a rogue key swap can’t be socially engineered.

6

216

Add a CVIDN_VERSION ARX command that prints assembly_version + pem_fingerprint(SHA-256 first 8 bytes) so support can verify install state at-a-glance without shell access. Wire the same fingerprint into the boot-gate log line so failed verification logs include “fleet pem=ab12cd34” for triage. Document the 30-day double-trust window in docs-sensitive/cv-idn/runbook.md §“Signing-key rotation procedure” — both keys verify during the window, server flips to new-only after, then old-PEM cv-cad installs auto-fail with a clear error.

92

CV-IDN license JWT replay across orgs

Adversary obtains a valid license JWT for drawing A (e.g. extracts from a customer’s published .dwg attachment, or buys it on a grey market) and re-uses it on a drawing they generated for their own org’s drawing B.

Drawing B plots successfully because the JWT signature is valid and the server never sees a /spend. Adversary gets free licenses; revenue leak proportional to JWT availability. The jti = drawing_uuid check (DFMEA-090) blocks within-process replay but doesn’t help if adversary regenerates drawing B’s UUID to match the stolen JWT’s jti.

6

(1) JWT is in the NOD — easy to extract; (2) cv-cad has no online-verify step before plotting (offline-first is the whole point of contract §1 decision 2 — perpetual licenses); (3) sub is the org UUID, not bound to the machine, so the JWT travels across machines + orgs by design.

4

(a) JWT contains the original sub (org UUID); cv-cad COULD display “Licensed to: ” in the title block / About dialog from the sub claim — visible deterrent against shipping a stolen JWT (the fabricator’s customer sees a stranger’s org); (b) drawing_id collision check server-side (409 cross-org-claim) prevents two orgs from claiming the same UUID via /spend, but doesn’t help offline; (c) the perpetual-license model is contract-locked — no exp claim by design; (d) cv-cad’s CVIDN_HASTOKEN / CVIDN_ENTITLEMENT flow ties the device to an org via SID + DPAPI, so any spending the adversary does goes against THEIR org, not the victim’s.

7

168

(i) Display licensed-org name in the About dialog + (optional) title-block watermark — purely deterrent, doesn’t block replay but raises social cost. (ii) Long-term: add a display_name server-side endpoint that translates sub UUID → org display name + caches it client-side; cv-cad pulls on first license verification per session. (iii) Document explicitly in docs-sensitive/cv-idn/runbook.md §“License replay scenarios” that this is an accepted trade-off of the perpetual-license model — the alternative (require online verification or short-lived JWTs) breaks contract decision 2 and the entire offline-forever promise.

93

CV-IDN lost/stolen device + token harvesting

Customer’s paired laptop is lost, stolen, or sold without first running CVIDN_FORGET. The DPAPI-encrypted device token at HKCU\Software\SimpleStruct\cv-cad\device_token is bound to the Windows user account, so a thief with the SAME Windows account credentials can decrypt it and continue spending tokens against the victim’s org.

Adversary spends tokens against victim org until victim notices and manually revokes the device token in cv-web UI. Revenue leak proportional to org balance × time-to-detect. Worst-case: adversary spends entire token bundle before victim revokes.

6

(a) DPAPI CurrentUser scope binds the blob to the Windows account, NOT to the physical machine. A stolen laptop where the thief knows the Windows password decrypts cleanly; (b) the contract’s sliding 90-day revoke (§6) doesn’t help if the thief is actively using the token; (c) cv-cad has no per-spend re-authentication step.

5

(a) cv-web device-list page lets the org owner manually revoke any device token (contract §6 — covered by CV-557 / CV-617 cv-web side); (b) sliding 90-day inactivity revoke (§6) caps the worst-case if the thief stops using the token; (c) the SID-bound machine_id at /redeem means the thief can’t just paste the token into a NEW pair flow — they’re stuck with the existing token until it’s revoked; (d) ChromeDriver / DPAPI behavior: if the Windows user account is changed (forced password reset by IT), DPAPI key derivation changes and the cached blob fails to decrypt → DeviceTokenStore.Load() returns null → next session prompts re-pair, evicting the thief.

6

180

(i) Account-takeover playbook in docs-sensitive/cv-idn/runbook.md §“Customer reports lost device”: revoke ALL device tokens for the account from cv-web, force password reset on the cv-web side, run a token-balance audit query for the past 30 days, refund any spend after the report timestamp. (ii) Add an in-cv-cad “Pair list” command (CVIDN_DEVICES) that pulls the current device list from a new cv-web /device-tokens GET endpoint so the customer can self-revoke other machines from the cv-cad they still own. (iii) Optional: cv-cad-side periodic re-validation (/entitlement once per week) that pulls the device-token’s revoked_at timestamp and self-revokes if set. Lower D from 6 → 3 with this change.

DFMEA Summary

RPN Range

Count

Action Level

300–500

7

Immediate — redesign required (Help system, weld connections, dimensional entry, export naming mismatch, nested defun shadowing, DFMEA-063 entlast latent, DFMEA-069 PP/BP truncation) — DFMEA-070 PP layout schema fixed (192)

200–299

14

High — design improvement recommended (batch error handling, Boolean validation, feature toggles, VLX crash, progcont routing, per-user registry, panatt new-drawing guard, project details persistence, pjdll line reader, import gate condition, first-call panatt error, unguarded API return values, stale log capture, DFMEA-060 pp/bp schema variance, DFMEA-066 WC silent-drop (post A6 fallback) — DFMEA-067 retracted; DFMEA-071/072/073 fixed (CSB022 GUI)

100–199

22

Medium — improvement desired (centgrav parsing, materials, .bat generation, panel selection, XRecord, panel/site detection, project paths, VLA/COM interop crash, OPEN sub-prompt/path derivation, silent failure/error handling, matl_dlg cond syntax, matl_dlg cons paren, okcanhlp cancel handlers, x32/x64 sync, DIMUNIT precision (post-fix), load-path divergence (post-fix), cross-pass tracker reset (post-fix), DFMEA-061 snaketongue, DFMEA-062 csv_dim1 shoulder, DFMEA-068 pre-DXF baseline staleness (post A7 re-baseline))

<100

8

Low — monitor or document (convert, slider, encryption, translation, dim1 overshoot (post-fix), off-panel mirror hatches (post-fix), feature-dim layer routing (post-fix), at-panel hatch duplicates (post-fix), WC dim missing LEADER (post-fix))

Top 5 risks by RPN (post A6 fallback, 2026-05-07):

  1. RPN 500 — csv.hlp Help system — completely non-functional, affects all users

  2. RPN 432 — drawdim.lsp nested defun shadowing (DFMEA-052) — three standalone modules silently overwritten by nested copies on every drawdim call. Top remaining engineering risk.

  3. RPN 400 — cvxpproj.lsp export naming mismatch — 19 of 21 project globals silently exported as null (Bug 103)

  4. RPN 360 — Weld connection data entry — cognitive overload + safety-critical output

  5. RPN 336 — DFMEA-063 — AC2027 entlast returns rendered MTEXT not DIMENSION (latent issue)

(DFMEA-066 WC silent-drop dropped from #1 RPN 576 to #7 territory at RPN 288 after A6 tactical fallback landed in 1c613c30. DFMEA-068 baseline staleness at RPN 240 is in the High band.)


§9-SEC. Security Failure Modes (Pillar 1–10 program seed)

Security-focused DFMEA extension authored alongside the Security SDLC program (Epics CV-627 through CV-636, Sprint 22 → Sprint 37). Each row corresponds to a RISK-NNN entry in docs-sensitive/security/risk-register.md and a row in docs/source/modernization-2026/32-tb11-bug-tracker.md “Security Bugs” table. Seeded from the 2026-05-27 cv-web spike audit (10 rows).

S/O/D scoring uses the same 1–10 convention as §9 above; RPN = S × O × D. A row crosses the §9 threshold of 300 → “Immediate” when RPN ≥ 300, mapping to Sprint 22 priority P0 in the security program.

#

Component

Failure Mode

Effect on User

S

Cause

O

Current Controls

D

RPN

RISK row

Recommended Action / Sprint

§9-SEC-001

/spend Edge Function

Non-atomic charge — select balance + update balance race enables concurrent double-spend

User who scripts parallel requests drains paid tokens beyond their balance; refund/reconciliation cost; revenue loss

10

Read-then-write without SERIALIZABLE isolation or pg_advisory_xact_lock

6

None — only customer-side rate-limiting

6

360

RISK-001

Atomic RPC inside a single transaction; idempotency key; reproducer test. Sprint 22 P0.

§9-SEC-002

instrument.ts Sentry init

sendDefaultPii: true + enableLogs: true ships user PII (emails, IPs, request bodies) to Sentry

PII leaves the Supabase region and lands in a third-party SaaS without lawful-basis review; GDPR exposure

9

Sentry SDK default opt-in; no beforeSend scrubber

8

None — Sentry receives raw events

4

288

RISK-002

Set sendDefaultPii: false; add beforeSend scrubber; document residency. Sprint 22 P0.

§9-SEC-003

cv-cad device-token handoff

Device token delivered via URL fragment leaks via referrer headers, browser history, and shared screenshots

Captured token enables takeover of paired cv-cad session; lateral access from a stale browser tab

9

Long-lived bearer in URL fragment; no one-time-redemption code

6

Token rotated only on explicit logout

6

324

RISK-003

One-time pickup code; redemption swaps for short-lived bearer; reproducer test. Sprint 22 P0.

§9-SEC-004

Stripe webhook → token grant

Coupon discount ignored — full SKU value credited to token ledger even when customer paid less

Over-granting tokens equal to coupon face value; revenue loss; coupon abuse vector

8

Webhook handler reads amount_subtotal, not amount_total; no proration

7

Stripe-side coupon analytics catches in arrears

6

336

RISK-004

Use amount_total; prorate token grant by discount; reproducer with mocked Stripe event. Sprint 22 P0.

§9-SEC-005

/checkout Edge Function

Arbitrary SKU input accepted — server allows checkout for SKUs that map to over-priced or hidden products

Discount abuse; competitive-pricing leak; potential token-grant exploit if SKU id is also used as ledger key

8

No Zod allowlist of SKU ids on server

6

None server-side

6

288

RISK-005

Server-side SKU allowlist; reject unknown SKUs; reproducer. Sprint 23 P1.

§9-SEC-006

/refund (absent)

No reverse-token endpoint — refunds via Stripe leave token balance over-credited

Customer refunds purchase via Stripe but keeps tokens granted by the original charge; effectively free tokens

8

Endpoint not implemented; webhook charge.refunded not wired

7

None — manual reconciliation only

6

336

RISK-006

Implement /refund endpoint + charge.refunded webhook handler; reverse ledger atomically. Sprint 23 P1.

§9-SEC-007

Import file pipeline (.cvpanel)

Missing file-size cap + Zod schema slack — oversized or malformed import can crash worker or trigger DoS

UI freeze; worker OOM; possible parser-driven RCE if schema gaps allow type confusion

7

No Content-Length gate; Zod schemas permissive on optional fields

7

Browser memory limits eventually OOM the tab

5

245

RISK-007

Hard size cap; strict Zod schemas with .strict(); reproducer with malformed .cvpanel. Sprint 23 P1.

§9-SEC-008

Device-token lifecycle

Device tokens never expire — stolen token remains valid until manual revoke

Compromised cv-cad workstation retains access indefinitely; no automatic forced-rotation window

8

No expires_at column on device-token table; no rotation cron

5

None — manual revoke via admin only

6

240

RISK-008

Add expires_at + rotation cron + EF check; reproducer. Sprint 24 P1.

§9-SEC-009

cv-web response headers (CloudFront)

Missing CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy headers

Increased blast radius for any XSS or clickjacking surface; mixed-content attacks

6

No response-headers policy attached to CloudFront

8

None

4

192

RISK-009

CloudFront response-headers policy (Terraform under webpage/); CSP report-only first, then enforce. Sprint 26 P2.

§9-SEC-010

PWA Service Worker cache

Authenticated responses cached and served to subsequent users on shared device

Stale PII / token-balance / panel data served to next user of the same browser profile

5

Cache policy doesn’t vary on auth state

6

None

4

120

RISK-010

Cache policy keyed on auth; cache-busting on logout; reproducer in BrowserStack. Sprint 27 P2.

§9-SEC threshold guide

RPN band

Security priority

Sprint behavior

≥ 300

P0

Ship in Sprint 22; reproducer test mandatory

200–299

P1

Ship in Sprints 23–25

100–199

P2

Ship in Sprints 26–31

< 100

P3

Ship in Sprints 32–37 (program close)

§9-SEC rows are added by: the spike-audit (initial 10 rows above), every new threat-model session (Pillar 2), every pentest finding (Sprint 33), every security incident retro (Pillar 9). The §9-SEC table is the canonical predicted-risk register; risk-register.md is the actionable working register.



11. Cross-References


Appendix A: Complete Call Graph

[AutoCAD Launch]
└── csvmenu.lsp → csv.mnu / csv.cui

[Menu Click] → csv;
└── c:csv (csv.lsp)
    ├── setvars → 60 sysvars
    ├── pj_name → project path
    ├── Load 93 modules
    └── Route:
        ├── md_dlg (Panel Options hub)
        │   ├── New/Edit Panel → panel.lsp
        │   │   ├── mp_dlg.lsp (Main Panel dialog)
        │   │   │   ├── panatt.lsp → convert.lsp
        │   │   │   ├── ro_dlg → wd_dlg → dr_dlg → dl_dlg
        │   │   │   ├── sb_dlg → rb_dlg → nb_dlg
        │   │   │   ├── fh_dlg → fv_dlg → fs_dlg → ts_dlg → ss_dlg
        │   │   │   ├── ch_dlg → pl_dlg → ll_dlg
        │   │   │   ├── tp_dlg → lb_dlg
        │   │   │   ├── sd_dlg → pp_dlg → bp_dlg
        │   │   │   └── wc_dlg (5 pages) → wc_edit
        │   │   │       └── All handled by okcanhlp.lsp
        │   │   ├── Save panelvar → XRecord
        │   │   └── drawpan.lsp
        │   │       ├── opening.lsp (per opening type)
        │   │       ├── rndblock.lsp (round blockouts)
        │   │       ├── feature.lsp (reveal strips)
        │   │       ├── green.lsp (greenplate/ledger)
        │   │       ├── weldconn.lsp (connection blocks)
        │   │       ├── chamfer.lsp, miter.lsp, thick.lsp
        │   │       ├── dowels.lsp (slab dowels)
        │   │       ├── 3D Boolean: UNION adds + SUBTRACT voids
        │   │       └── finpan.lsp
        │   │           ├── centgrav.lsp (center of gravity)
        │   │           ├── pick.lsp, ppcent.lsp (pick points)
        │   │           ├── brace.lsp (brace points)
        │   │           ├── drawdim.lsp ×5 (dimension chains)
        │   │           │   └── basedim.lsp, drawdimlst.lsp
        │   │           ├── TITLE + BORDER block insert
        │   │           └── Save .dwg → plt.lsp (optional print)
        │   ├── Batch Utilities → btch_dlg.lsp
        │   │   └── btch.lsp (script recursion loop)
        │   ├── Materials List → matl_dlg.lsp → matlist.txt
        │   ├── Revision History → revision.lsp
        │   ├── View/Print → lyr_dlg.lsp / plt.lsp
        │   └── Slope Calculator → calc_dlg.lsp
        ├── sdwg_dlg (Site Options hub)
        │   ├── grid_dlg.lsp (grid lines)
        │   ├── wall_dlg.lsp (wall lines, 4 pages)
        │   ├── slab_dlg.lsp (slab edges, 4 pages)
        │   ├── tiltup.lsp (attach/detach panels)
        │   ├── layout.lsp (construction layout)
        │   └── green.lsp (footing/joist connections)
        └── External I/O
            ├── engexp.lsp → dreng/mbeng/wsbeng (export)
            └── engimp.lsp / makepan.lsp (import)

Appendix B: DCL Control Count by Dialog

Dialog

edit_box

popup

toggle

radio

slider

button

Total

wc_dlg

90

30

210

180

90

15

615

wall_dlg

448

256

0

0

0

7

711

slab_dlg

385

256

0

0

0

7

648

fh_dlg

114

38

133

76

114

5

480

fv_dlg

76

38

95

76

76

5

366

grid_dlg

208

1

4

12

0

6

231

wd_dlg

60

0

60

24

60

3

207

nb_dlg

48

0

18

42

48

1

157

sb_dlg

24

0

30

24

24

1

103

lb_dlg

28

12

8

8

28

1

85

ro_dlg

16

0

12

16

16

1

61

dr_dlg

16

0

8

16

16

1

57

rb_dlg

18

0

6

12

18

1

55

mp_dlg

16

2

20

0

10

1

49

dl_dlg

18

0

6

6

18

1

49

site_dlg

2

0

11

0

0

29

42

pp_dlg

8

0

9

16

8

1

42

ll_dlg

15

0

3

6

15

1

40

bp_dlg

8

0

5

12

8

1

34

pl_dlg

12

0

3

6

12

1

34

lyr_dlg

0

0

31

0

0

0

31

ch_dlg

0

0

5

24

0

1

30

revision

30

0

0

0

0

0

30

sd_dlg

12

0

3

0

12

1

28

calc_dlg

15

0

0

0

9

3

27

dreng_dlg

15

2

0

8

0

0

25

wsbeng_dlg

15

2

0

8

0

0

25

mbeng_dlg

13

2

0

8

0

0

23

btch_dlg

0

3

10

8

0

1

22

md_dlg

0

0

0

0

0

19

19

ss_dlg

6

0

2

4

6

1

19

ts_dlg

4

0

2

4

4

1

15

fs_dlg

4

0

2

4

4

1

15

wc_edit

8

0

0

0

3

4

15

tp_dlg

3

3

1

2

3

1

13

viewpt

0

0

0

0

0

10

10

sdwg_dlg

0

0

0

0

0

7

7

dwg

0

0

0

0

0

4

4

project

0

0

0

0

0

4

4

warning

0

0

0

0

0

3

3

new

2

0

0

0

0

0

2

process

0

0

0

0

0

1

1

invar

1

0

0

0

0

0

1

matl_dlg

0

0

0

0

0

0

0

TOTAL

1,826

645

721

622

~1,750

172

~5,736