Part of the v1.3.0 lookup feature. Design: docs/superpowers/specs/2026-07-10-lookup-columns-design.md (on release/v1.3.0). Builds on the LOOKUP qualifier issue.
dBASE III's actual form model: @ 5,5 SAY "Name: " GET NAME edits the current record's field and READ writes it back — no memory-variable round trip. A field-bound GET whose column declares a LOOKUP renders as a dropdown, which is how the lookup reaches forms with a single declaration site.
Scope
Tests
Part of the v1.3.0 lookup feature. Design:
docs/superpowers/specs/2026-07-10-lookup-columns-design.md(onrelease/v1.3.0). Builds on the LOOKUP qualifier issue.dBASE III's actual form model:
@ 5,5 SAY "Name: " GET NAMEedits the current record's field andREADwrites it back — no memory-variable round trip. A field-bound GET whose column declares a LOOKUP renders as a dropdown, which is how the lookup reaches forms with a single declaration site.Scope
doAtSayGetresolves the GET name against the active table's columns; fields shadow memory variables (dBASE precedent; README documents the behavior change — demos audited, every GET usesm_/choice/pause)FormFieldgainstarget(var|field),value(prefill),options?— options via LookupResolverREADeach field-bound GET captures its alias + current-record rowid (fetchCurrentRowpath);form-submitwrites by rowid, exactly likegrid-editform-submit: branch on target; validate ALL (declared type + lookup membership) before writing ANY; targets come from the Session-retained field list, never the client messageform-errorserver message (offending fields + reasons); client keeps the form open and outlines themFormLayoutrenders<select>when options are present** Error: GET <field>: no current recordTests
tests/GridMessages.test.ts-style protocol coverage for the new form-submit branches +form-error, including a forged form-submit naming a column the form never offered