Skip to content
zit Erratum: draft-fossil-artifact-format-01 §4.7.8
Login

Erratum: draft-fossil-artifact-format-01 §4.7.8

Document draft-fossil-artifact-format-01
Section 4.7.8, J Card (an absent value and a present empty value)
Type Technical (whether a reader keeps the two forms apart is left open)
Status Applied in draft-fossil-artifact-format-01 (2026-10-16)
Reported 2026-10-16
Submitter Dan Mestas
Found via A reader working from the draft text alone; confirmed by reading Fossil's source

1. Summary

§4.7.8 says an absent J value "defaults to the empty string, not null", and §4.2 makes a present empty final token decode to the empty string too. The draft does not say whether a reader may still record the two forms differently, for example as "unset" and "set to empty". Fossil does not: both reach ticket processing as the same empty string. Fossil also writes the present empty form itself, so a reader meets it in real repositories.

2. The text in error

Page 24 (§4.7.8):

The value is escape-decoded; the field name is stored verbatim, including any leading +. An absent value defaults to the empty string, not null.

3. What Fossil implements

manifest_parse() in src/manifest.c, case 'J':

zName = next_token(&x,0);
zValue = next_token(&x,0);
if( zName==0 ) SYNTAX("name missing from J-card");
if( zValue==0 ) zValue = "";
defossilize(zValue);

A present empty token returns a pointer to an empty string, and an absent one is replaced by ""; nothing records which it was. ticket_insert() in src/tkt.c then writes the value into the ticket tables the same way for both.

When a ticket field is changed to the empty string, submitTicketCmd() in src/tkt.c writes

blob_appendf(&tktchng, "J %s %#F\n", aField[i].zName, nValue, zValue);

with nValue 0, which is J, SP, the field name, SP, LF: the present empty form.

4. Corrected text

Replace the sentence "An absent value defaults to the empty string, not null." with:

An absent value and a present empty one (J, SP, fieldname, SP, LF) both decode to the empty string, not null, and a reader MUST NOT distinguish them; Fossil writes the present empty form when a ticket field is set to the empty string.

5. Observable consequence of the uncorrected text

A reader that keeps the forms apart can treat J name as "leave the field alone" and J name as "clear it", or the reverse, and build ticket state that differs from Fossil's for the same artifacts.

6. Implementations

zit's J card parser returns the same empty value for both forms. No change is needed.