ZMail filters, universes, and Profile semantics
Reconstruction claim
For the maintained LM-3 System 303 source profile pinned below, an implementation can reproduce the source-visible semantics of:
- named and editable message filters, including the constructor-generated form subset, search-key dispatch, header and address matching, date boundaries, compilation, and definition recovery;
- named and editable universes, including the exact serialized grammar, set operations, mapping order, late binding, and historical validation defects;
- the executable ZMail Profile source document, generated option block, optional compiled cache, and separately selected filter/universe definition sections; and
- the complete denominator of 69 textual
DEFINE-ZMAIL-USER-OPTIONforms in the selectedzmail/defs.lisp, with exact source name, type, default, applicability, persistence class, and Profile-update behavior.
This page is a normative System 303 companion to the broader ZMail and mail-composition reimplementation specification and the MIT CADR ZMail dossier. The broader specification controls application lifecycle, layouts, commands, mail files, composition, and transport. This page controls the narrower Filter, Universe, Profile, and selected-option contracts.
The claim is deliberately source-bounded. The tested System 303-0 load band advertised Mail but did not contain a resident ZWEI:ZMAIL-FRAME; loading stopped at an unsited file-host dependency. Therefore this page does not claim that the maintained source was the exact code compiled into that band, that a historical site used these defaults, or that the visible Filter, Universe, and Profile panes have been exercised in the preserved runtime.
The compatibility boundary is source-visible C303 behavior. This specification does not reserve or imply compiled-band, exact historical-release, or pixel compatibility.
Normative language and evidence classes
MUST, MUST NOT, SHOULD, and MAY are reconstruction requirements. A strict C303 profile preserves the pinned source's ordering, executable-input boundary, and defects. An implementation that rejects arbitrary Lisp, makes edits transactional, fixes the (ALL) or reverse-map defects, or normalizes malformed forms MUST identify itself as a safer or corrected profile.
| Code | Evidence class | What it establishes |
|---|---|---|
C303-F |
public maintained source | filter construction, predicates, definition recovery, universe grammar, expansion, and mapping |
C303-P |
public maintained source | Profile pane lifecycle, source editing, named-definition selection, Save/Compile/Reset order |
C303-D |
public maintained source | ZMail object helpers, all 69 declarations, restrictions, header families, and option registration hooks |
C303-CVV |
public maintained source | generic user-option registration, reset, pruning, and LOGIN-SETQ serialization |
C303-CMD |
public maintained source | option-to-command-documentation associations and their concrete update effects |
C303-CASE |
public maintained source | ordinary STRING-SEARCH and STRING-EQUAL ignore alphabetic case unless explicitly told otherwise |
C303-RUN-BLOCKED |
runtime observation | the tested band exposed the Mail launcher but could not load the ZMail system in the isolated unsited session |
The maintained LM-3 Fossil branch is a restoration source profile, not a claim that its 2020s check-in date is the historical authorship or release date.
Release and artifact profile
The normative public source check-in is 4df393c68d7f083ce42d5c377039d26043cc18a9031ace28258dc97f4137eb91. Paths in this table are relative to that System checkout.
| Evidence | Public source | Bytes | SHA-256 | Principal spans |
|---|---|---|---|---|
C303-F |
zmail/filter.lisp |
92,892 | 97e7dd830fd71d621b6aca7517e1cd5e1f138c741d64c57a152cdb202e788a31 |
585–845, 847–1312, 1710–2089 |
C303-P |
zmail/profil.lisp |
45,394 | be6d2632a8fbb82e8244714939824921031e84c27c18fc2811ba472a7c14d0c3 |
5–503, 718–1051 |
C303-D |
zmail/defs.lisp |
49,882 | 6f0b1401d0e48f049671088286685311f38e72a623f94ce242fa8df05431b00e |
196–215, 285–384, 880–957, 945–1161 |
C303-P, mail |
zmail/mail.lisp |
83,733 | 9bcf41074afa3524fee48f5b61af130a0115223c447db778f12b79ef138b7705 |
5–18, 557–603, 1802–1841 |
C303-CMD |
zmail/comnds.lisp |
114,870 | 9a9e0d68cc3a3bbc358aa48ff407feaaba406bd717ec61d6d32681297d75ea93 |
235–247, 277–360, 1170–1332, 1724–1735 |
C303-CMD |
zmail/window.lisp |
41,968 | df732df25f9da4aeded86dedec7c5adeebc7e40882d293c9e7337249c627db6e |
240–275, 454–467, 725–732 |
C303-CVV |
window/choice.lisp |
84,440 | 866900e06a7f55855d84df71dbbb77c07040a4db586cba39e665c93f945f6dbd |
1747–1834, 1933–1955 |
C303-CASE |
sys2/string.lisp |
49,754 | 070c8f058bca3410ba5871ac1dbf00cb53d0d01b077111925d1fd314c29b12a5 |
358–463, 797–838 |
The files, sizes, and hashes were rechecked with GNU stat and sha256sum on 2026-07-19. The source links pin content rather than a moving branch name.
Compatibility levels
| Level | Contract | Status |
|---|---|---|
C303-FUP-L1 |
objects, serialized grammars, predicate and set semantics | specified from public maintained source |
C303-FUP-L2 |
exact mutation, abort, definition, mapping, and persistence order | specified from public maintained source |
C303-FUP-L3 |
exact selected 69-option metadata denominator and update associations | specified from public maintained source |
C303-FUP-L4 |
behavioral match to a runnable System 303 ZMail | reserved pending the runtime oracles below |
C303-FUP-L5 |
exact historical release, QFASL, saved-band, or pixel compatibility | out of scope and unclaimed |
Levels are cumulative. Source-derived tests alone do not establish C303-FUP-L4.
User-interface substrate
Filter, Universe, and Profile are implemented as ZWEI editor closures embedded in TV constraint frames and panes. Their controls are TV button, menu, choose-variable- values, mode-line, and editor-window flavors; command input is dispatched through the ZMail/ZWEI command loops. This selected source has no CLIM system dependency, application-frame definition, presentation translator, port, or CLIM protocol use. A reconstruction MUST classify this as TV + ZWEI, not CLIM and not Genera Dynamic Windows.
Object and ownership model
Filter definition
A named filter has separately mutable runtime parts (C303-F):
FilterDefinition {
name-symbol
optional menu documentation
USER-FILTER-ALIST entry
FILTER-FUNCTION property
optional EXPR-FILTER-FUNCTION property saved immediately before compilation
}
The Profile source section is a separate persistence representation. Evaluating a definition mutates the runtime entry and function; saving options does not add that definition to the Profile source.
Universe definition
A named universe has only two registered parts in this profile:
UniverseDefinition {
name-symbol in ordered UNIVERSE-LIST
serialized expression in the symbol's UNIVERSE property
}
There is no expanded-object property and no universe cache. Every mapping request re-expands the current serialized expression, so named dependencies are late-bound.
Profile document
The Profile is executable Lisp source, not a passive preferences file (C303-P). Its editor buffer owns:
- source pathname, file identity, package/readtable/base attributes, and save tick;
- an option-variable tick and a separate editor-variable tick;
- a generated leading run of non-default
LOGIN-SETQforms; - arbitrary user-authored Lisp outside that generated run;
- selected
DEFINE-FILTERandDEFINE-UNIVERSEsections; and - an optional compiled init file tracked by a compile tick.
The option block and named-definition sections are maintained by different paths. Neither is an atomic snapshot of all runtime ZMail state.
Filter definition language
Outer form and executable boundary
The persisted form grammar is (C303-F):
filter-definition := (DEFINE-FILTER name-symbol (message-variable)
[documentation-string]
body-form*)
body-form* is unrestricted Lisp. It can read global state, call arbitrary functions, mutate objects, or signal. A strict profile therefore evaluates trusted Profile code with the historical authority. A declarative clone MAY reject general Lisp, but MUST call that a compatibility divergence.
The macro always gives the generated property function auxiliary variables named STATUS and KEYWORDS. On every call, before the user body, it parses the message and extracts the parsed keyword list. Unlike the Genera 8.5 profile, this work is not conditional on free references in the body.
An empty body-form* has an unexpected result: the generated setup assignment is the function's last form, so the filter returns the message's keyword list. It is therefore true exactly when that returned list is non-null. The new-filter editor initially contains an empty body; completing it without adding a clause is not a constant-false filter in this source profile.
Constructor-generated subset
The Filter frame's panes synthesize the following exact subset (C303-F):
| UI operation | Inserted semantics |
|---|---|
| Not, And, Or | open an ordinary NOT, AND, or OR form and leave point inside it |
| Close | move out over the next containing list using the standalone editor command |
| Any keyword | return the parsed KEYWORDS list itself |
| one keyword | identity-membership of the selected keyword symbol in KEYWORDS |
| Deleted, Unseen, Recent, Answered, Filed | property lookup on parsed STATUS |
| Search | full-message literal/FSM/FSM-expression search selected from an extended key |
| To | address-aware search of only :TO |
| To/Cc | address-aware search of the complete recipient-header family |
| From | address-aware search of only :FROM |
| Subject | recursive string search of :SUBJECT |
| Other | recursive or address-aware search of a selected header name |
| empty header key | non-null property test for that header; no search call |
| Before, On, After | absolute or execution-relative comparison against parsed :DATE |
| named user filter | call the named filter through MSG-FITS-FILTER-P |
The recipient-header family is exactly :TO, :CC, :BCC, :REDISTRIBUTED-TO, :FORWARDED-TO-TO, :FORWARDED-TO-CC, :REDISTRIBUTED-TO-CC, :REMAILED-TO, :RESENT-TO, and :RESENT-CC. The constructor's From choice does not expand to all sender-type headers.
Completion, compilation, and failure order
Done and Sample share this sequence (C303-F):
- Reset the editor input stream to the interval start and read exactly one Lisp object with the special search-string readtable. A trailing object is ignored.
- Evaluate that object.
- Require the returned object to be a property function name whose first element is
:PROPERTYand third element isFILTER-FUNCTION. - Take its second element as the filter name.
- Copy the current
FILTER-FUNCTIONproperty toEXPR-FILTER-FUNCTION. - Compile the property function.
- If compiler output left the typeout window incomplete, ask whether the result is acceptable. Declining aborts the current command.
- Return the filter name. Done exits; Sample then surveys the selected universe.
Evaluation precedes result validation, expression capture, compilation, and warning acceptance. The definition macro updates or appends the menu entry before defining the property function. Thus arbitrary evaluation effects, a menu entry, a source function, and the saved expression can exist after a wrong-result, compile, warning, or Sample failure. There is no rollback.
The read helper catches reader errors without replacing the initial EOF sentinel; both true EOF and a caught error consequently become the same “unbalanced parentheses” failure. This does not erase effects of a form that was read and then evaluated successfully.
Names, redefinition, and recovery
Filter names are symbols interned in the task's current package. Left-clicking Name reads a new string and rewrites the symbol in the editor form. Every non-left button path opens the existing-definition menu; cancellation aborts the command. The pane documentation mentions only a right-click menu, but the executable branch controls strict compatibility.
Defining a new name appends its menu item. Redefining an existing name replaces the item's tail in place and retains its position. Calling a named filter looks up its current FILTER-FUNCTION property on every call, so a parent sees a later child redefinition without recompilation. An absent property signals “not the name of a filter.”
Definition recovery first inspects FILTER-FUNCTION; if that value is atomic it falls back to EXPR-FILTER-FUNCTION. It accepts only a recognizable non-atomic NAMED-LAMBDA whose property name identifies the requested filter. It reconstructs the argument from the lambda list and takes the body tail after the generated setup form. Otherwise it reports the filter as compiled. This recovers an equivalent generated form, not author formatting. The optional documentation was removed before generating the function and is not recovered, so a Profile round-trip through this accessor loses that documentation string.
Predicate contract
Built-in truth and status predicates
The predicate protocol takes (message, argument). Mapping calls the processing function only when the predicate returns non-null. Opposite predicates are separate functions, not a generic wrapper.
- Any-keyword and one-keyword predicates read the message keyword property; one- keyword membership uses symbol identity.
- Attribute predicates test a named message property. The five constructor status names are Deleted, Unseen, Recent, Answered, and Filed.
- True and false predicates return canonical
TandNIL. - Named-filter predicates dynamically resolve the current property function and canonicalize success with a non-null test. The negative form applies
NOTto the child result. - The direct Subject predicate accepts a scalar subject string or a list of subject strings and succeeds when any contains the key.
- Direct From, Recipient, and Sender-or-Recipient predicates parse the message and apply the same address matcher described below.
Search keys, coercion, and case
Filter source embeds either an ordinary string or an ART-16B extended-search object (C303-F, C303-CASE):
- An ordinary string selects literal
SEARCHfor message intervals. - An object whose array type is exactly
ART-16Bis parsed intoSEARCH,FSM-SEARCH, orFSM-EXPR-SEARCHplus a transformed key. - Any other object is rejected as an invalid search key. Because
ARRAY-TYPEis called before the final rejection, a non-array can first signal its own type error.
Full-message search supports all three parser results. Header search maps literal search to STRING-SEARCH and finite-state search to FSM-STRING-SEARCH, but has no mapping for FSM-EXPR-SEARCH; the generated header form consequently has an invalid callee. Address-header search likewise has no defined FSM-expression branch and can fail while inspecting the transformed key. A strict C303 profile preserves this header/full-message asymmetry.
Ordinary STRING-SEARCH and STRING-EQUAL are case-insensitive for letters because their default “consider case” input is null. Literal subject/header and full address comparisons therefore ignore alphabetic case. FSM case behavior is determined by the extended-search compiler and MUST NOT be inferred from STRING-SEARCH.
An empty constructor key is converted to a header-presence test before search macro expansion. A handwritten empty address-search key can fail when the macro indexes its first and last characters.
Header and address matching
Non-address headers may be a string or a list. Literal and FSM string search succeeds if any list element matches. A missing property is false.
Address properties are lists of parsed recipient records (C303-F):
- An FSM key searches only a record's
:INTERVALbounds. A record with no interval is skipped; no original-string fallback exists in this profile. - A literal key surrounded by the source's byte
0x18and byte0x19delimiters has those delimiters stripped and performs case-insensitive substring search in each record's:NAME. - Every other literal key is a full mailbox match. If it contains
@, the entire record:NAMEmust equal the key prefix and the first element of the record's:HOSTlist must equal the key suffix. Without@, the entire:NAMEmust equal the entire key.
There is no bang-path or percent-route normalization, true-name fallback, suffix- only mode, prefix-only mode, or personal-name comparison in the selected matcher. Host comparison uses only the first parsed host. Equality and partial substring comparison ignore alphabetic case.
Date semantics
The constructor first parses the entered date while requesting an interpretation not in the future. If the parser calls it relative, the user is asked whether it should remain relative to filter execution time. Declining converts the parsed instant to a fixed printed date/time. A zero-hours/minutes/seconds result omits the time; otherwise the generated source retains hours and minutes and retains seconds when nonzero (C303-F).
All comparisons use parsed STATUS property :DATE; a missing date is false.
| Predicate | Boundary |
|---|---|
| On absolute | threshold <= message-date < threshold + 86,400 seconds |
| Before absolute | message-date < threshold |
| After absolute | message-date >= threshold |
| On relative | the same half-open 86,400-second interval, with its threshold recomputed from current universal time on each call |
| Before/After relative | the same strict/inclusive comparisons against that recomputed threshold |
“On” is an interval anchored at the parsed threshold, not forcibly at civil midnight. A handwritten relative macro whose date is parsed as absolute computes a moving offset from its separately supplied NOW string; the constructor normally uses the relative macro only after the parser reported a relative date.
Universe description language
Serialized grammar and operator octets
The intended surface language is:
universe-definition := (DEFINE-UNIVERSE name-symbol () expression)
expression := NIL
| file-name-string
| pathname-object ; validator only; evaluator defect below
| PRIMARY
| CURRENT
| defined-name-symbol
| (any-symbol) ; shallow singleton escape
| (not-operator expression)
| (intersection-operator expression*)
| (union-operator expression*)
The source operator print names are one-byte characters, not portable ASCII words:
| UI label | Source octet | Required semantic role |
|---|---|---|
| Not | 0x05 |
complement |
| Intersection | 0x12 |
set intersection |
| Union | 0x13 |
set union |
A portable reimplementation MAY serialize named ASCII or Unicode tokens, but an importer for the C303 source profile MUST map these exact octets without guessing their modern glyph identities.
Exact validator behavior
Validation order is observable (C303-F):
- accept strings, pathname objects,
NIL,PRIMARY, andCURRENT; - accept a symbol only when its current
UNIVERSEproperty is non-null; - reject every other atom;
- accept any singleton list whose sole element is a symbol without validating that symbol;
- for Not, require exactly one operand but do not recursively validate it;
- reject any other non-singleton operator except Intersection and Union;
- recursively validate all Intersection/Union children. Empty forms are accepted.
Consequences include accepted (UNDEFINED), accepted (not-operator) because it is intercepted by the singleton rule, and accepted Not forms with an invalid nested operand. Atomic ALL is not accepted by the validator. Forward references are rejected when written atomically but pass through the singleton escape.
The Universe editor initializes a new buffer with only (DEFINE-UNIVERSE new-name ()), omitting the required expansion argument. Done on that untouched form fails macro argument checking. The user must insert a component or edit the form.
Definition and completion order
DEFINE-UNIVERSE runs the validator during macro expansion. If validation fails, the generated registration code is not run. On success, evaluation:
- appends a new name to
UNIVERSE-LISTif it is not already present; then - replaces the symbol's
UNIVERSEdescription property.
Redefinition retains the name's list position. These two writes are not wrapped in a transaction. There is no eager expansion or cache installation.
Universe Done reads one form with the same reader helper and directly evaluates it. Unlike Filter Done, it performs no result-shape check and no compile step. An arbitrary form can have effects and its return value becomes the task result. A valid definition normally returns the result of its final property write.
Name selection has the same left-versus-non-left behavior as Filter. Selecting an existing name reconstructs its current property in a DEFINE-UNIVERSE form; an absent property is represented as NIL rather than diagnosed by that accessor.
Expansion semantics and source defects
Every MAP-OVER-DEFINED-UNIVERSE call expands the current description afresh:
| Expression | Expansion |
|---|---|
NIL |
NIL, which later mapping code cannot treat as a buffer |
PRIMARY |
current primary ZMail buffer |
CURRENT |
current selected ZMail buffer |
runtime-only atomic ALL |
empty-arity Intersection, meaning union of all currently known buffers |
| other symbol | recursively expand its current UNIVERSE property; an undefined property becomes NIL |
| string | resolve or visit the named mail file with creation/loading enabled |
| Not | expand operand, then build a temporary complement |
| Union | expand children, then build a temporary union |
| Intersection | expand children, then build a temporary intersection |
| singleton list | recursively expand the current property of its sole symbol |
Two mismatches are normative defects of the strict source profile:
- The validator accepts pathname objects, but the evaluator has no pathname branch and next applies list access to the object. A normal pathname object therefore reaches a type failure rather than the string file-resolution path.
- The visible Universe menu adds an All item and wraps every item selected from that menu in a singleton list. It therefore inserts
(ALL), which uses named- symbol property lookup and normally expands toNIL; it does not reach the runtime-only atomicALLbranch. A corrected clone may map this item to true All, but cannot call that exact C303 behavior without a compatibility switch.
Undefined names and cycles are not detected explicitly during expansion. Undefined names collapse to NIL and fail when a caller expects a buffer. Cycles recurse without a source-defined cycle guard.
Set membership, order, and loading
All set membership is message-object identity membership (C303-F, C303-D). Temporary set-result buffers are newly allocated and are not automatically appended to ZMAIL-BUFFER-LIST.
- Not scans
ZMAIL-BUFFER-LISTin list order, considers disk buffers only, and visits each buffer's currently active messages. It emits each message absent from the operand, preserving that scan order. It does not first force files fully loaded. - Union sorts the newly constructed child-buffer list by descending active message count. It emits each child's messages in buffer order and suppresses later identity duplicates. Equal-size child order depends on the historical sort and is not strengthened here.
- Intersection with children sorts them by ascending active message count, scans the first/smallest in its order, and emits messages present by identity in every remaining child. An empty Intersection delegates to Union over the complete current
ZMAIL-BUFFER-LIST; this can include both disk and temporary buffers and deduplicates overlapping messages. - Empty Union creates an empty temporary buffer.
Because expansion sorts and scans concrete buffers immediately, a NIL child can fail in message-count or buffer-array access. Any file visits and temporary buffers created before that failure remain ordinary side effects; there is no rollback.
Standard map functions
The source also defines exact mapping domains used with filters:
| Mapper | Order and loading contract |
|---|---|
| one message | test that object once |
| one buffer | forward over its current active array; no forced load |
| rest of buffer | start after the current message when it is the current buffer, otherwise at zero; request one next message whenever the index reaches the initially active length, stopping when the buffer refuses |
| beginning of buffer | reverse traversal; strict defect below |
| loaded buffers | in ZMAIL-BUFFER-LIST order, disk buffers only; force each fully loaded before forward mapping |
| all buffers | map loaded buffers first, then resolve string/pathname entries returned by the buffer-alist provider, force them fully loaded, and map them |
| defined universe | re-expand the named expression, then forward-map the resulting concrete buffer |
The beginning-of-buffer mapper ignores its argument's array and always binds the array from the current ZMail buffer. If the argument is the current buffer it starts before the current message; otherwise it scans the current buffer's entire active array backward. A corrected implementation should fix this, but a strict C303 compatibility test must expose it.
Callbacks are invoked in visit order only for matching messages. A callback failure or nonlocal exit aborts traversal with no transactional undo of prior callback effects or file loads.
Profile persistence contract
Entering and reading Profile
Profile selects the current user, initializes its editor closure on first use, locks background processing, switches to the Profile window configuration, and visits the init source (C303-P). If an already visited file differs from the file computer's version, the user can choose the new version. A missing file creates a Lisp-mode source header and immediately inserts current non-default options.
When the init pathname names a compiled file, Profile reads its recorded source identity, opens the newest corresponding source file for editing, and compares source identity and creation dates. A missing compiled file, different recorded source, or newer source marks the compile tick stale. The editable buffer pathname always denotes text even while the ordinary init pathname denotes the compiled file.
The source is read in its declared package/readtable/base. Older files missing readtable or base attributes are assigned Zetalisp syntax and decimal base as buffer-attribute updates.
Generated LOGIN-SETQ run
INSERT-CHANGED-VARIABLES runs only when forced, or when the option-variable tick is newer than the editor-variable tick; :ASK additionally requests confirmation. It then (C303-P, C303-CVV):
- ensures the existing buffer ends at a line boundary;
- examines top-level forms beginning at the start of the source;
- removes the first leading contiguous run whose forms begin with
(LOGIN-SETQ; if the first top-level form is different, it inserts before it; - writes non-default ZMail options, then non-default ZMail hardcopy options;
- writes a newline, requests text redisplay, and advances the editor-variable tick.
The scan does not search for or own arbitrary later LOGIN-SETQ forms. Conversely, user-authored material placed inside the leading generated run's deletion interval is not protected. A reimplementation MUST delimit ownership equivalently for strict compatibility or use an explicit safer block marker in a different profile.
Option serialization
Every selected option is registered in one alist by pushing at declaration time; therefore the unpatched baseline serializes the 69 options in reverse declaration order. Redeclaring an option removes its prior entry and pushes the new one. The declaration records a DEFAULT-VALUE property before DEFVAR; reevaluating a declaration updates metadata/default while preserving an already bound current value (C303-CVV).
Only values unequal to their recorded defaults are written. The comparison binds alphabetic-case-sensitive string comparison. Each value becomes one LOGIN-SETQ form:
- numbers,
T, andNILare emitted directly; :HOST-OR-NILhost objects are reconstructed by name throughSI:PARSE-HOST, and string/symbol host designators are quoted inside that parse call; and- every other nontrivial value is quoted.
Reset-to-default iterates the registered alist and assigns every variable its DEFAULT-VALUE. Restriction metadata affects Profile visibility only; hidden values remain registered, resettable, and serializable.
Save, compile, Reset, Defaults, and Edit
| Profile action | Ordered effects |
|---|---|
| left/keyboard Save | optionally ask to insert changed variables; save source; if a compiled profile exists and its tick differs, ask whether to recompile |
| right-menu Save file | save current text without first inserting changed variables |
| right-menu Insert changes | regenerate option forms without saving |
| middle / Make init compiled | if not compiled, choose a distinct source pathname, rename the editor buffer, mark source and compile state stale; then save if needed, compile to the ordinary init pathname, load it, and record the compile tick |
| Recompile file | fail if the profile is not already compiled; otherwise save if needed, compile, load, then record the compile tick |
| Reap file | offer old source versions and, when compiled, old ordinary-init versions for deletion |
| Reset | assign all defaults, then load the ordinary init file, recompute compiled/source match, refresh choices and all associated command documentation, advance the variable tick, and optionally revert or regenerate a modified source buffer |
| Defaults | assign all defaults, mark the profile uncompiled, refresh choices/documentation, advance the variable tick, and optionally regenerate a modified source buffer |
| Edit | first regenerate changed settings without asking; run the standalone source editor; sectionize; reset all options; evaluate the whole edited source; refresh choices/documentation; then synchronize both option ticks |
Declining insertion during save-all does not cancel the subsequent source save. An error during Reset after defaults were assigned, during edited-source evaluation after some forms ran, or during compile after saving is not rolled back. The compile tick advances only after compiler output is loaded successfully.
Named filter and universe sections
The Filters and Universes Profile buttons choose which registered runtime definitions are represented in the source (C303-P):
- Section metadata identifies symbols already associated with this Profile buffer.
- A multiple-choice menu selects the desired set and may launch a new-definition task.
- Existing sections excluded from the result are deleted one by one.
- Newly selected names are appended at end of file, one reconstructed definition per section, in selected order.
- The buffer is redisplayed and resectionized.
Unlike the later Genera implementation, this source performs no preflight recovery of every addition before deletion. A recovery or insertion failure after removals can leave Profile text partially rewritten. Removing a section does not remove its runtime menu/property definition. Adding a filter can fail because its compiled shape is not recoverable; adding a universe can serialize an undefined property as NIL.
The four hidden association options are edited by dedicated Profile menus. Their setters mutate alists and advance the Profile variable tick. They do not invoke the generic command-documentation callback at that moment, even for options that have a documentation association; Reset and Edit later call the global refresh path.
Complete 69-option metadata contract
Inventory rules and codes
This denominator is exactly the active textual forms matching DEFINE-ZMAIL-USER-OPTION in pinned zmail/defs.lisp. It excludes the separately declared site-alist option *MAIL-SENDING-MODE*, the hardcopy option alist, patch files, backup revisions, and globals that are not registered by this macro.
The Type values are choose-variable-values descriptors, not Common Lisp type declarations. Lowercase source spellings in rows 9, 41, 52, and 68 read as the same uppercase symbol names under the selected readtable; spelling is retained to make a textual audit reproducible.
Applicability codes are:
CVV: ordinary Profile choice;SPECIAL (:NEVER): hidden from the generic pane and edited by a dedicated path;CVV if GMSGS: shown only when site option:GMSGSis non-null; andCVV if COMSAT: shown only when site option:COMSATis non-null.
All 69 rows have persistence code ND: registered, resettable, and emitted as LOGIN-SETQ only when non-default, even when hidden by a restriction. Update codes:
tick: a direct CVV edit changes the variable and Profile variable tick only;summary: also rebuild command/label documentation and, on an explicit Profile edit, ask once whether to recompute already cached summary lines in disk buffers;*-doc: recompute the named pointer/command documentation;special: dedicated-menu mutation and tick, with no immediate generic documentation callback;alias: establish the legacy forwarded value cell noted after the declaration; anddeclared-only: the selected source explicitly says the option is unimplemented and contains no consumer outside its declaration.
Exact inventory
| # | Option source spelling | Type | Default source → value | Purpose | Applicability | Persist | Update |
|---|---|---|---|---|---|---|---|
| 1 | *OTHER-MAIL-FILE-NAMES* |
:PATHNAME-LIST |
NIL |
remembered non-primary mail files | SPECIAL (:NEVER) |
ND | special |
| 2 | *FILTER-KEYWORDS-ALIST* |
:SEXP |
NIL |
filter-to-keyword associations | SPECIAL (:NEVER) |
ND | special; keyword docs refresh only on global refresh |
| 3 | *FILTER-MOVE-MAIL-FILE-ALIST* |
:SEXP |
NIL |
filter-to-move-file associations | SPECIAL (:NEVER) |
ND | special; Move docs refresh only on global refresh |
| 4 | *FILTER-REFERENCE-UNIVERSE-ALIST* |
:SEXP |
NIL |
filter-to-universe associations | SPECIAL (:NEVER) |
ND | special |
| 5 | *FILTER-SUMMARY-WINDOW-FRACTION* |
:NUMBER-OR-NIL |
NIL |
Summary fraction in filter layout | CVV | ND | tick |
| 6 | *SUMMARY-WINDOW-FRACTION* |
:NUMBER |
0.45s0 → short float 0.45 |
ordinary Summary pane fraction | CVV | ND | tick |
| 7 | *SUMMARY-SCROLL-FRACTION* |
:NUMBER |
0.2s0 → short float 0.2 |
Summary scrolling increment | CVV | ND | tick |
| 8 | *NEW-MAIL-FILE-APPEND-P* |
:MENU-ALIST |
:STICKY |
append/prepend policy for new mail files | CVV | ND | tick |
| 9 | *default-mail-buffer-generation-retention-count* |
:NUMBER-OR-NIL |
nil |
generation retention for new mail files | CVV | ND | tick |
| 10 | *DEFAULT-SUMMARY-TEMPLATE* |
:SEXP |
T |
default Summary display format | CVV | ND | summary; alias |
| 11 | *GMSGS-OTHER-SWITCHES* |
:STRING |
"//Z" |
extra switches supplied to GMSGS | CVV if GMSGS | ND | tick |
| 12 | *RUN-GMSGS-P* |
:ASSOC |
:NO |
whether/when to run GMSGS before inbox retrieval | CVV if GMSGS | ND | tick |
| 13 | *MAIL-FILE-FOR-DRAFTS* |
:PATHNAME-OR-NIL |
NIL |
mail file used to store drafts | CVV | ND | tick |
| 14 | *DEFAULT-DRAFT-FILE-NAME* |
:PATHNAME-OR-NIL |
NIL |
default file for saving a draft | CVV | ND | tick |
| 15 | *DEFAULT-MOVE-MAIL-FILE-NAME* |
:PATHNAME-OR-NIL |
NIL |
default Move destination | CVV | ND | move-doc |
| 16 | *MOVE-FILE-NAME-STICKY-FN2* |
:BOOLEAN |
T |
inherit Move file type from default | CVV | ND | tick |
| 17 | *TEXT-MAIL-FILE-SEPARATOR* |
:STRING |
"" |
text-file message separator | CVV | ND | tick |
| 18 | *ZMAIL-STARTUP-FILE-NAME* |
:PATHNAME-OR-NIL |
NIL |
file read at ZMail startup | CVV | ND | tick |
| 19 | *ZMAIL-USUAL-MAIL-FILE-DIRECTORY* |
:PATHNAME-OR-NIL |
() → NIL |
usual mail-file directory | CVV | ND | tick |
| 20 | *FORWARDED-MESSAGE-END* |
:STRING |
"" |
text after forwarded messages | CVV | ND | tick |
| 21 | *FORWARDED-MESSAGE-SEPARATOR* |
:STRING |
"" |
text between forwarded messages | CVV | ND | tick |
| 22 | *FORWARDED-MESSAGE-BEGIN* |
:STRING |
"" |
text before forwarded messages | CVV | ND | tick |
| 23 | *DONT-REPLY-TO* |
:STRING-LIST |
'("INFO-*") → ("INFO-*") |
addresses/patterns excluded from Reply | CVV | ND | tick |
| 24 | *MIDDLE-REPLY-MODE* |
:MENU-ALIST |
:SENDER |
middle-button Reply recipients | CVV | ND | reply-doc |
| 25 | *MIDDLE-REPLY-WINDOW-MODE* |
:MENU-ALIST |
:SHOW-ORIGINAL |
middle-button Reply layout | CVV | ND | reply-doc |
| 26 | *1R-REPLY-MODE* |
:MENU-ALIST |
:SENDER |
Reply recipients for numeric argument one | CVV | ND | tick |
| 27 | *REPLY-MODE* |
:MENU-ALIST |
:ALL |
ordinary Reply recipients | CVV | ND | reply-doc |
| 28 | *REPLY-WINDOW-MODE* |
:MENU-ALIST |
:LIKE-MAIL |
ordinary Reply layout | CVV | ND | reply-doc |
| 29 | *DEFAULT-MAIL-WINDOW-CONFIGURATION* |
:MENU-ALIST |
:NORMAL |
composition window layout | CVV | ND | tick |
| 30 | *SEND-HEADER-FORMAT* |
:MENU-ALIST |
:INCLUDE-PERSONAL |
recipient format in sent headers | CVV | ND | tick |
| 31 | *REPLY-HEADER-FORMAT* |
:MENU-ALIST |
:SHORT |
recipient format inserted in replies | CVV | ND | tick |
| 32 | *DEFAULT-HEADER-FORCE* |
:MENU-ALIST |
:NONE |
default COMSAT header force | CVV if COMSAT | ND | tick |
| 33 | *LOCAL-MAIL-HEADER-FORCE* |
:MENU-ALIST |
:ITS |
local-message header force | CVV | ND | tick |
| 34 | *LOCAL-MAIL-INCLUDE-SUBJECT* |
:BOOLEAN |
T |
create Subject for local mail | CVV | ND | tick |
| 35 | *DELETE-EXPIRED-MSGS* |
:MENU-ALIST |
:PER-FILE |
automatic expired-message deletion | CVV | ND | tick |
| 36 | *DEFAULT-FCC-LIST* |
:PATHNAME-LIST |
NIL |
initial file-copy destinations | CVV | ND | tick |
| 37 | *DEFAULT-CC-LIST* |
:ADDRESS-LIST |
NIL |
initial Cc recipients | CVV | ND | tick |
| 38 | *REQUIRE-SUBJECTS* |
:MENU-ALIST |
NIL |
outgoing-subject requirement | CVV | ND | tick |
| 39 | *GENERATE-IN-REPLY-TO-FIELD* |
:BOOLEAN |
T |
automatic In-Reply-To generation | CVV | ND | tick |
| 40 | *GENERATE-MESSAGE-ID-FIELD* |
:BOOLEAN |
T |
automatic Message-ID generation | CVV | ND | tick |
| 41 | *preserve-msg-references-across-expunge* |
:boolean |
T |
intended preservation of conversation references | CVV | ND | declared-only |
| 42 | *SUMMARY-MOUSE-MIDDLE-MODE* |
:MENU-ALIST |
:DELETE-OR-UNDELETE |
Summary middle-button operation | CVV | ND | summary-mouse-doc |
| 43 | *NEXT-MIDDLE-MODE* |
:MENU-ALIST |
:LAST-UNDELETED |
Next middle-button movement | CVV | ND | next-doc |
| 44 | *PREVIOUS-MIDDLE-MODE* |
:MENU-ALIST |
:FIRST-UNDELETED |
Previous middle-button movement | CVV | ND | previous-doc |
| 45 | *MAP-MIDDLE-MODE* |
:ASSOC |
NIL |
Map middle-button command | CVV | ND | map-doc |
| 46 | *MAIL-MIDDLE-MODE* |
:MENU-ALIST |
:BUG |
Mail middle-button operation | CVV | ND | mail-doc |
| 47 | *DEFAULT-INITIAL-WINDOW-CONFIGURATION* |
:MENU-ALIST |
:BOTH |
initial reader layout | CVV | ND | tick |
| 48 | *DELETE-MIDDLE-MODE* |
:MENU-ALIST |
:BACKWARD |
Delete middle-button movement | CVV | ND | delete-doc |
| 49 | *NEXT-AFTER-DELETE* |
:MENU-ALIST |
:FORWARD |
ordinary movement after Delete | CVV | ND | delete-doc |
| 50 | *PRUNE-HEADERS-AFTER-YANKING* |
:BOOLEAN |
NIL |
prune headers of yanked messages | CVV | ND | tick |
| 51 | *INHIBIT-BACKGROUND-MAIL-CHECKS* |
:BOOLEAN |
NIL |
disable background new-mail checks | CVV | ND | tick |
| 52 | *notify-on-new-mail-in-background* |
:assoc |
nil |
converse/notify/never background notification | CVV | ND | tick |
| 53 | *INHIBIT-BACKGROUND-SAVES* |
:BOOLEAN |
NIL |
disable automatic save after inbox retrieval | CVV | ND | tick |
| 54 | *ONE-WINDOW-AFTER-YANK* |
:BOOLEAN |
T |
show one message window after yank | CVV | ND | tick |
| 55 | *ALWAYS-JUMP-AFTER-GET-NEW-MAIL* |
:BOOLEAN |
NIL |
move to first message even with no new mail | CVV | ND | tick |
| 56 | *FORWARDED-ADD-SUBJECT* |
:BOOLEAN |
T |
add Subject to forwarded messages | CVV | ND | tick |
| 57 | *QUERY-BEFORE-EXPUNGE* |
:BOOLEAN |
NIL |
display and confirm before expunge | CVV | ND | tick |
| 58 | *DELETE-AFTER-MOVE-TO-FILE* |
:BOOLEAN |
T |
mark message deleted after moving it | CVV | ND | tick |
| 59 | *MAIL-HEADER-DELIMITER* |
:STRING |
"--Text Follows This Line--" |
draft header/body separator | CVV | ND | tick |
| 60 | *DELETE-UNDIGESTIFIED-MESSAGE* |
:BOOLEAN |
T |
delete original after undigestifying | CVV | ND | tick |
| 61 | *CLIP-UNDIGESTIFIED-MESSAGE* |
:BOOLEAN |
() → NIL |
clip original contents after undigestifying | CVV | ND | tick |
| 62 | *INHERIT-SUBJECT-FIELD* |
:BOOLEAN |
T |
identify digest source in extracted Subject | CVV | ND | tick |
| 63 | *DEFAULT-MAIL-TEMPLATE* |
:SEXP |
NIL |
template for ordinary composition | CVV | ND | tick |
| 64 | *DEFAULT-REPLY-TEMPLATE* |
:SEXP |
NIL |
template for replies | CVV | ND | tick |
| 65 | *DEFAULT-BUG-TEMPLATE* |
:SEXP |
NIL |
template for bug reports | CVV | ND | tick |
| 66 | *DEFAULT-FORWARDING-TEMPLATE* |
:SEXP |
NIL |
template for forwarding | CVV | ND | tick |
| 67 | *DEFAULT-REFORMATTING-TEMPLATE* |
:SEXP |
NIL |
template for incoming-header reformatting | CVV | ND | tick |
| 68 | *from-user-id* |
:string-or-nil |
nil |
default user name in From fields | CVV | ND | tick |
| 69 | *FROM-HOST* |
:host-or-nil |
NIL |
default host in From fields | CVV | ND | tick; host-special serialization |
Immediately after row 10, *SUMMARY-INCLUDE-DATE* is forwarded to the same value cell as *DEFAULT-SUMMARY-TEMPLATE*; it is a legacy alias, not a seventieth option. Rows 11–12 and 32 are pruned only from display when their site predicates are false. Row 41 remains visible and persistent even though the source marks it unimplemented.
Command-documentation update graph
Only these selected options have source-registered documentation associations:
DEFAULT-SUMMARY-TEMPLATE
-> SET-MSG-SUMMARY-LINE
-> CHANGE-MSGS-SUMMARY-LINES
SUMMARY-MOUSE-MIDDLE-MODE -> ZMAIL-SUMMARY-MOUSE
NEXT-MIDDLE-MODE -> COM-ZMAIL-NEXT
PREVIOUS-MIDDLE-MODE -> COM-ZMAIL-PREVIOUS
NEXT-AFTER-DELETE --------+-> COM-ZMAIL-DELETE
DELETE-MIDDLE-MODE -------+
MAP-MIDDLE-MODE -> COM-ZMAIL-MAP
MAIL-MIDDLE-MODE -> COM-ZMAIL-MAIL
REPLY-MODE ---------------------+
REPLY-WINDOW-MODE ---------------+
MIDDLE-REPLY-MODE ----------------+-> NORMAL-REPLY
MIDDLE-REPLY-WINDOW-MODE ---------+ -> Reply, Reply All, Summary Reply text
FILTER-KEYWORDS-ALIST -> COM-ZMAIL-KEYWORDS
FILTER-MOVE-MAIL-FILE-ALIST -+
DEFAULT-MOVE-MAIL-FILE-NAME -+-> GET-DEFAULTED-MOVE-ZMAIL-BUFFER
-> Move/Summary Move dependents
A direct CVV choice performs its associated updates with *EXPLICIT-OPTION-UPDATE* true. This is why only the summary-template path asks whether to rewrite cached summary lines. The associations are not variable-cell watchers: programmatic assignment or special-menu mutation does not automatically run them. Reset, Defaults, and post-Edit refresh walk all associations explicitly.
Failure, abort, and recovery matrix
| Operation | Failure point | State that may already have changed | Strict C303 recovery |
|---|---|---|---|
| filter read | EOF or caught reader error | editor only | report unbalanced parentheses; edit and retry |
| filter evaluation | arbitrary error or wrong return shape | arbitrary effects; menu/function may exist | no rollback |
| filter compile | error or warning declined | menu, function, and saved expression may exist | no rollback; edit/retry |
| filter Sample | universe selection or survey failure | filter already installed/compiled | no rollback |
| universe macro validation | invalid source-visible expression | arbitrary earlier effects in a surrounding evaluated form, but no registration from this macro | correct form and retry |
| universe registration | failure after list append | name may exist without updated property | no rollback |
| universe expansion | undefined/cycle/pathname/(ALL)/nil child failure |
file visits and temporary buffers may exist | no rollback; repair definition |
| named-section selection | accessor/insertion failure after deletion starts | partially deleted/appended Profile text | manually repair or revert source buffer |
| option block regeneration | deletion/printer/editor failure | leading generated run may be absent or partial | repair/revert before save |
| Reset | init load or probe failure | defaults and partial init effects | no rollback |
| Edit reload | reader/evaluator failure | defaults plus partial edited-source effects | no rollback |
| compile | save, compiler, or load failure | source and/or compiled file may already differ | compile tick remains stale unless load completes |
Abort from Filter or Universe exits through the containing window-configuration cleanup, but does not undo a definition that was already evaluated. Leaving Profile restores the prior window configuration; it does not imply source save or world save.
Conformance suite
Tests MUST use disposable definitions, buffers, messages, Profile pathnames, and host objects, and MUST identify strict versus corrected behavior.
Filter tests
C303-FILT-READ-ONE: place two forms in the editor and prove completion reads only the first.C303-FILT-READ-ERROR: compare true EOF with a caught reader error and prove both reach the unbalanced-parentheses report.C303-FILT-WRONG-SHAPE: evaluate a harmless effectful non-filter form and prove its effect precedes rejection.C303-FILT-WARNING-ABORT: decline compiler warnings and prove the menu, property function, and saved expression are not rolled back.C303-FILT-EMPTY: define an empty-body filter and prove its result is the parsed keyword list, including false for no keywords and non-null for one keyword.C303-FILT-ALWAYS-PARSE: use a body independent of Status/Keywords and prove parsing and keyword retrieval still happen first.C303-FILT-KEYWORD-IDENTITY: compare same-print-name symbols from different packages and prove membership uses identity.C303-FILT-SEARCH-DISPATCH: cover ordinary, literal extended, FSM, FSM-expression, non-ART-16Barray, and non-array keys in full-message and header contexts.C303-FILT-CASE: prove literal subject/header and address-name/host comparison ignore alphabetic case.C303-FILT-ADDRESS: cover interval-present/absent FSM records, paired0x18/0x19partial keys, exact name, name@first-host, extra hosts, bang/percent strings, and empty handwritten keys.C303-FILT-DATE: test missing dates, threshold equality, both ends of On's half-open interval, a non-midnight anchor, and a retained relative date.C303-FILT-RECOVERY: recover an uncompiled, editor-compiled, and unrecoverable compiled filter; prove optional documentation is lost from the recovered form.C303-FILT-LATE-BIND: redefine a named child and prove an existing parent uses the new property function.
Universe and mapping tests
C303-UNI-GRAMMAR: exhaust strings, pathname, nil, Primary, Current, atomic All, defined/undefined atoms, arbitrary singleton symbols, each operator arity, and invalid nested Not operands against the exact validator table.C303-UNI-OCTETS: round-trip the three operator source bytes05,12, and13without Unicode substitution.C303-UNI-EMPTY-EDITOR: complete the untouched two-argument initial form and prove macro arity failure before registration.C303-UNI-MENU-ALL: select visible All, capture the generated(ALL), and prove it does not reach atomic-All expansion in the unpatched source profile.C303-UNI-PATHNAME: prove validator acceptance followed by evaluator failure.C303-UNI-EMPTY-SETS: prove empty Union is empty and direct empty Intersection unions the current buffer list with identity deduplication.C303-UNI-ORDER: prove Union's descending-size first-occurrence order and Intersection's ascending-size seed order, leaving equal-size ordering implementation-dependent.C303-UNI-NOT: prove disk-buffer-only domain, active-message-only scan, list order, and identity membership.C303-UNI-LATE-BIND: redefine a named child and prove the parent re-expands the new description on its next map.C303-UNI-UNDEFINED-CYCLE: distinguish undefined-to-nil failure from unguarded cyclic recursion.C303-MAP-REST: prove incrementalREAD-NEXT-MSGrequests after the initial active length and exact current/noncurrent start indices.C303-MAP-BEGINNING-DEFECT: pass a noncurrent buffer and prove the strict function traverses the current buffer backward.C303-MAP-LOADING: distinguish one-buffer/current-universe active-only mapping from loaded/all-buffer forced loading.
Profile and option tests
C303-OPT-DENOMINATOR: parse pinneddefs.lispwithout evaluating it and require exactly 69 active textual forms with table-identical names, types, and default forms; separately require one excluded site-alist mail-sending option.C303-OPT-RESTRICTIONS: require exactly four:NEVER, two:IF :GMSGS, and one:IF :COMSATrestriction and prove pruning changes visibility, not registration or serialization.C303-OPT-ORDER: load declarations into an empty alist and prove reverse-source order; redeclare one option and prove it moves to the front without resetting an already bound current value.C303-OPT-WRITE: cover equal/non-equal values, case-only string differences, number/Boolean direct emission, quoted values, and all:HOST-OR-NILbranches.C303-OPT-DOC-GRAPH: change every associated option through CVV and compare the exact graph above; change hidden associations through special menus and prove no immediate generic callback.C303-OPT-SUMMARY: accept and decline the one-time cached-summary rewrite question and compare labels, cached lines, and ticks.C303-PROFILE-LEADING-RUN: test no top-level form, a leading generated run, a later userLOGIN-SETQ, and user text interleaved inside the leading run.C303-PROFILE-SAVE-MATRIX: execute all Save menu/button modes and every prompt branch; compare buffer text, source file, compiled file, load call, and three relevant ticks.C303-PROFILE-RESET-PARTIAL: inject an init-load failure after defaults and prove partial state remains.C303-PROFILE-EDIT-PARTIAL: inject an error after an early edited-source effect and prove reset plus that effect remain while final tick synchronization does not.C303-PROFILE-DEFINITION-PARTIAL: remove one section, then fail recovery of an addition and prove the source rewrite is not transactional.C303-PROFILE-COMPILED-IDENTITY: cover missing, wrong-source, older, matching, and failed-reload compiled files against compile-tick state.
Runtime and screenshot oracle backlog
The existing ZMail runtime audit records the exact current blocker: System 303-0 displayed a Mail System Menu item, but ZWEI:ZMAIL-FRAME was absent and loading the maintained system stopped at the unsited AMS-BRIDGE-1 file-host path. Those captures do not show ZMail itself and were intentionally not promoted as application screenshots.
No Filter, Universe, or Profile screenshot can yet be published as evidence for this page. The required follow-up is to configure a disposable local file service inside the established CADR harness boundary, load ZMail without saving the world, use only synthetic messages and pathnames, and capture:
TODO-RUNTIME-C303-FILTER: the initial Filter form and its System/Header/Date panes;TODO-RUNTIME-C303-UNIVERSE: the Universe pane with its operator and All controls; andTODO-RUNTIME-C303-PROFILE: Profile's option chooser plus Filters/Universes/Save controls.
Each runtime test must record the full harness provenance required by repository policy and each selected image must pass the capture-specific rights review. Until then, exact labels/layouts that are not established by source remain TODO, and the source-visible (ALL) and reverse-map defects remain unconfirmed runtime oracles.
Nonclaims and implementation cautions
- The 69-row table is complete for one macro spelling in one pinned file, not for hardcopy, mail-file, site-alist, patch-only, or runtime-added options.
- A choose-variable-values descriptor identifies the source editor contract; exact rejection, coercion, and pixel behavior of every generic type remains an external TV dependency.
- Public source availability does not make the maintained restoration identical to a particular historical System 303 band.
- The source operator bytes establish serialized identity and UI mapping, not a modern Unicode glyph assignment.
- Named filters and universes are both late-bound in this profile, but filters resolve a function property per message whereas universes resolve and materialize a set per map. They are not interchangeable query objects.
- Executable Profile and filter source is a security boundary. A sandboxed data-only replacement is prudent, but is not source-compatible without an explicit profile.
- Nothing in Profile Save or Compile invokes Save World or creates a host-process checkpoint.
Sources and verification
- LM-3 maintained System source at Fossil check-in
4df393c68d7f083ce42d5c377039d26043cc18a9031ace28258dc97f4137eb91, files and spans listed in the artifact table; verified 2026-07-19. - MIT CADR ZMail dossier, especially the source/runtime boundary and
System 303-0harness record. - ZMail and mail-composition reimplementation specification, for the surrounding application contract and cross-system compatibility profiles.
- Screenshot publication rights review, which governs any future curated runtime capture.