<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sisudoc-spine/test/reference/abstraction/the_autonomous_contract.ralph_amissah.en.ssp, branch main</title>
<subtitle>SiSU Spine: document publishing and search (in D) 2015</subtitle>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/'/>
<entry>
<title>abstraction 2.1: a poem states its object range</title>
<updated>2026-10-01T03:14:23+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-30T20:18:59+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=993a3f655359f98dc26d3d3222e07792e2ccddf7'/>
<id>993a3f655359f98dc26d3d3222e07792e2ccddf7</id>
<content type='text'>
- A poem is a container of verse, and stores its range of verse ocn,
  - its verse are the citable units with ocn.

- A note in the last verse of a poem previously was not gathered into
  the endnotes section, this now is fixed

Format 2.0 -&gt; 2.1: the property is an addition, the poem is not a
citable object (but contans a range of objects), its verse are
(individual citable objects), and every reader checks the major version.
A 2.0 database reads as having no ranges.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- A poem is a container of verse, and stores its range of verse ocn,
  - its verse are the citable units with ocn.

- A note in the last verse of a poem previously was not gathered into
  the endnotes section, this now is fixed

Format 2.0 -&gt; 2.1: the property is an addition, the poem is not a
citable object (but contans a range of objects), its verse are
(individual citable objects), and every reader checks the major version.
A 2.0 database reads as having no ranges.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>abstraction: format 2.0, source.digests</title>
<updated>2026-09-22T18:23:53+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-21T14:52:39+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=e1c9056903c2478066d5da8934d704f4d1935da4'/>
<id>e1c9056903c2478066d5da8934d704f4d1935da4</id>
<content type='text'>
format 2.0, source.digest covers every markup file, the sha256 over one
line per markup file, "&lt;sha256&gt; &lt;filename&gt;", sorted by filename.

source.digest was the sha256 of the master file as read, before any
insert. This is right for a .sst, which is the whole document. For a
.ssm with inserts .ssi (containing the substantive part of a documents
text) this is close to meaningless.

Considered change of meaning (rather than an addition) and given the
major part of the format version with it: 1.1 becomes 2.0, in the .ssp
header line and in the database's schema.version row together.
A 1.x reader refuses a 2.0 artefact, which is what that check is for.

- Sorted, so the value does not depend on the order a filesystem hands
  back a directory.
- By filename (rather than by path), so it does not depend on where the
  pod sits, which is the property the pod rebuild comparison rests on:
  a pod unzipped elsewhere must still give the same abstraction.
  Within one language every markup file lives in one directory, so a
  filename identifies it.

Each line is checkable on its own against a digests.txt line or a files
row, which the single value was not. The whole is reproducible with
sha256sum and sort, and was verified that way for a one file document
and for a twenty file one.

An unreadable file is named in the digest rather than skipped. The parse
has failed elsewhere by then, and a digest that quietly left a file out
would claim the document is something it is not.

The reference abstractions are regenerated. Two lines change in each and
no others: the version, and the digest.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
format 2.0, source.digest covers every markup file, the sha256 over one
line per markup file, "&lt;sha256&gt; &lt;filename&gt;", sorted by filename.

source.digest was the sha256 of the master file as read, before any
insert. This is right for a .sst, which is the whole document. For a
.ssm with inserts .ssi (containing the substantive part of a documents
text) this is close to meaningless.

Considered change of meaning (rather than an addition) and given the
major part of the format version with it: 1.1 becomes 2.0, in the .ssp
header line and in the database's schema.version row together.
A 1.x reader refuses a 2.0 artefact, which is what that check is for.

- Sorted, so the value does not depend on the order a filesystem hands
  back a directory.
- By filename (rather than by path), so it does not depend on where the
  pod sits, which is the property the pod rebuild comparison rests on:
  a pod unzipped elsewhere must still give the same abstraction.
  Within one language every markup file lives in one directory, so a
  filename identifies it.

Each line is checkable on its own against a digests.txt line or a files
row, which the single value was not. The whole is reproducible with
sha256sum and sort, and was verified that way for a one file document
and for a twenty file one.

An unreadable file is named in the digest rather than skipped. The parse
has failed elsewhere by then, and a digest that quietly left a file out
would claim the document is something it is not.

The reference abstractions are regenerated. Two lines change in each and
no others: the version, and the digest.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>images alt text, and epub says what it is</title>
<updated>2026-09-14T16:18:51+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-14T01:56:43+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=eb5a9f3dab1d1848a1aa90c534a125c222327635'/>
<id>eb5a9f3dab1d1848a1aa90c534a125c222327635</id>
<content type='text'>
Four things, not visible in an error count:

- Images had no alt text, even where markup carried the text, and the
  field alt text is present, incorrectly used in code; fixed as the alt.

  { sm_tux.png 64x80 "Gnu/Linux - a better way" }image

  an image with nothing to say for itself gets alt=""

- Images with no dimensions were incorrectly written width="0"
  height="0", fixed

- Accessibility metadata, which EPUB Accessibility 1.1 requires:
  schema:accessMode, accessibilityFeature and accessibilityHazard, plus
  accessModeSufficient and accessibilitySummary, which epubcheck does
  not test for; used by
  - readers looking for a book it can use,
  - anyone distributing into the EU.
  Every value is derived from the document, not asserted: a document
  with no images says so, one whose images all carry alt text claims
  alternativeText and textual sufficiency, one where an image says
  nothing claims neither.
  Nothing claims WCAG conformance, which would be a claim about an
  evaluation that has not happened.

- DPUB-ARIA roles beside the structure spine already knew about.
  doc-toc, doc-endnotes, doc-bibliography, doc-glossary and doc-index on
  the sections, doc-noteref on a note reference and doc-footnote on the
  note it points at. "doc_endnotes" as a class name means something to a
  stylesheet and nothing to a reading system. Not doc-biblioentry: DPUB-
  ARIA 1.1 deprecated it. These are plain ARIA, so the html gets them
   too.

Also dealt with here:
- Spine makes certain sections such as endnotes, bookindex, ... and a
  heading that has a name for itself cannot share the same name, if it
  does the name is now disambiguated, disambiguated. (disambiguation
  similar to that used for a repeated anchor tag)

- Endnote anchors fixed to use "id" (being one unique tag in the
  document that is target of every reference to it)instead of obsolete
  form (they were &lt;a name="note_1"&gt;. "name" on an &lt;a&gt;).
  Book index markers keep "name": the same marker sits on every object
  an entry names, 296 times in one document, and those are markers of
  where a term occurs rather than distinct targets.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Four things, not visible in an error count:

- Images had no alt text, even where markup carried the text, and the
  field alt text is present, incorrectly used in code; fixed as the alt.

  { sm_tux.png 64x80 "Gnu/Linux - a better way" }image

  an image with nothing to say for itself gets alt=""

- Images with no dimensions were incorrectly written width="0"
  height="0", fixed

- Accessibility metadata, which EPUB Accessibility 1.1 requires:
  schema:accessMode, accessibilityFeature and accessibilityHazard, plus
  accessModeSufficient and accessibilitySummary, which epubcheck does
  not test for; used by
  - readers looking for a book it can use,
  - anyone distributing into the EU.
  Every value is derived from the document, not asserted: a document
  with no images says so, one whose images all carry alt text claims
  alternativeText and textual sufficiency, one where an image says
  nothing claims neither.
  Nothing claims WCAG conformance, which would be a claim about an
  evaluation that has not happened.

- DPUB-ARIA roles beside the structure spine already knew about.
  doc-toc, doc-endnotes, doc-bibliography, doc-glossary and doc-index on
  the sections, doc-noteref on a note reference and doc-footnote on the
  note it points at. "doc_endnotes" as a class name means something to a
  stylesheet and nothing to a reading system. Not doc-biblioentry: DPUB-
  ARIA 1.1 deprecated it. These are plain ARIA, so the html gets them
   too.

Also dealt with here:
- Spine makes certain sections such as endnotes, bookindex, ... and a
  heading that has a name for itself cannot share the same name, if it
  does the name is now disambiguated, disambiguated. (disambiguation
  similar to that used for a repeated anchor tag)

- Endnote anchors fixed to use "id" (being one unique tag in the
  document that is target of every reference to it)instead of obsolete
  form (they were &lt;a name="note_1"&gt;. "name" on an &lt;a&gt;).
  Book index markers keep "name": the same marker sits on every object
  an entry names, 296 times in one document, and those are markers of
  where a term occurs rather than distinct targets.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>ocda: heading cross reference linking</title>
<updated>2026-09-12T16:14:39+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-11T16:32:13+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=4e6774904ce811b074d8b3694b04dc5c1e8219e4'/>
<id>4e6774904ce811b074d8b3694b04dc5c1e8219e4</id>
<content type='text'>
The segment a cross reference to a heading lands on, gixed upstream in
ocda, where the field is created, rather than inferred by the loader.

A heading above level 4 opens no html segment of its own, so a link to
it has to land on the level 4 heading that follows. The build loop
cannot know that when it reads the heading, and says so in a comment of
its own: "for html segname need following lv4 not yet known". It
back-fills tag_assoc when the level 4 heading arrives (lv0to3_tags), and
the answer then lives only in that map.

tags.segment_lv4_is now holds it, resolved in a pass over the finished
head and body sections: walking backwards, the last level 4 heading seen
is the next one for everything above it, which is the same answer the
back-fill gives. Emitted in the .ssp only where it differs from
.segment_html_is, which is every heading at level 4 or below, so it is
sparse: 317 lines over the 35 document reference set, none removed.
Carried in the database as a column of its own, and read back by both
readers.

docHasFromAbstraction reads it instead of working it out. With that, and
on top of the two defect fixes, a document loaded from an artefact and
one parsed from markup agree:

  key sets       identical, all 35 documents
  values         3 entries differ of some 30,000, all of them
                 _the_title, where the abstraction supplies an epub
                 segment the parser leaves unset
  link targets   all 1,651 agree, against 89 differing before any
                 of this work and 1 after the defect fixes alone

Format stays v1.1. That version is new in this same run of work and
nothing outside spine has read it, so this belongs in it rather than in
a bump of its own.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The segment a cross reference to a heading lands on, gixed upstream in
ocda, where the field is created, rather than inferred by the loader.

A heading above level 4 opens no html segment of its own, so a link to
it has to land on the level 4 heading that follows. The build loop
cannot know that when it reads the heading, and says so in a comment of
its own: "for html segname need following lv4 not yet known". It
back-fills tag_assoc when the level 4 heading arrives (lv0to3_tags), and
the answer then lives only in that map.

tags.segment_lv4_is now holds it, resolved in a pass over the finished
head and body sections: walking backwards, the last level 4 heading seen
is the next one for everything above it, which is the same answer the
back-fill gives. Emitted in the .ssp only where it differs from
.segment_html_is, which is every heading at level 4 or below, so it is
sparse: 317 lines over the 35 document reference set, none removed.
Carried in the database as a column of its own, and read back by both
readers.

docHasFromAbstraction reads it instead of working it out. With that, and
on top of the two defect fixes, a document loaded from an artefact and
one parsed from markup agree:

  key sets       identical, all 35 documents
  values         3 entries differ of some 30,000, all of them
                 _the_title, where the abstraction supplies an epub
                 segment the parser leaves unset
  link targets   all 1,651 agree, against 89 differing before any
                 of this work and 1 after the defect fixes alone

Format stays v1.1. That version is new in this same run of work and
nothing outside spine has read it, so this belongs in it rather than in
a bump of its own.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>ocda: the abstraction carries the document metadata output reads</title>
<updated>2026-09-12T16:14:39+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-11T14:23:25+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=b6b2ff06054edb20c880aff26b8b02d8f093fcc2'/>
<id>b6b2ff06054edb20c880aff26b8b02d8f093fcc2</id>
<content type='text'>
.ssp format v0.1 -&gt; v1.1, and the .ocda.db with it: they are two
serialisations of one format and now move together.

The gap this closes, measured against the writers' read set: of the 59
conf_make_meta fields outputs/io_out/ reads, 29 were in neither
artefact. Five are conf.* and stay out, being site and run scoped (urls,
papersize, the search db filename): the same abstraction published to
two sites must take each site's. Of the rest, three are never assigned
anywhere (title_short, publisher, original_publisher; read only by
sqlite.d, always empty) and one is a copy of a field already carried
(title_sub = title_subtitle), so 17 properties actually had to travel
and now do:

  make      breaks, footer, home_button_text
  meta      title.edition, date.added_to_site, language.document_char,
            original.{title,source,language,language_char},
            rights.copyright_{text,translation,illustrations,
            photographs,cover,audio,video}

make splits by when it acts, which is worth keeping in mind: these three
are read in outputs/io_out/ and must travel, while italics, bold,
emphasis, substitute and headings are read at parse time and their
effect is already in the objects.

New @source block, and source.* rows in the database, so a reader can
say which markup an abstraction came from rather than working from
stale content in silence:

  language    the document's own
  languages   the pod's list, which is what the inter-language links
              in html need and neither artefact carried
  digest      sha256 of the .sst; equals its digests.txt entry

The database adds source.ssp_digest, the sha256 of the .ssp it was built
from, since a file cannot hold its own hash. So the chain
.sst -&gt; .ssp -&gt; .ocda.db is checkable end to end.

The database's metadata table is now filled from the header blocks the
.ssp gives back, not from a second list read off doc_matters. One list,
in ssp.d: a property added there arrives in the database with nothing
else changed, and one that is not in the .ssp cannot be in the database
at all. That was the last place the two could drift; the objects stopped
being able to on 2026-09-07.

Version is checked on load. The major part must match, a newer minor is
accepted (a minor bump only adds properties, and an unknown property
line is ignored). A v0.1 artefact is now refused with a message saying
to regenerate it, rather than loading half populated.

test-abstraction-db.sh now compares the two artefacts' header blocks
property by property, 36 per document on the wealth of networks, where
it previously only checked that a schema.version row existed. Verified
non-vacuous: dropping one property is reported.

Reference regenerated, and the whole diff is this change and nothing
else: 320 lines added, 35 removed over 35 files, being 35 format lines
changed, 35 @source blocks (4 lines each), 35 language.document_char, 35
home_button_text (it has a default), 18 breaks, 16 footer,
4 date.added_to_site, 1 title.edition, 1 original.source.

Existing outputs unaffected.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
.ssp format v0.1 -&gt; v1.1, and the .ocda.db with it: they are two
serialisations of one format and now move together.

The gap this closes, measured against the writers' read set: of the 59
conf_make_meta fields outputs/io_out/ reads, 29 were in neither
artefact. Five are conf.* and stay out, being site and run scoped (urls,
papersize, the search db filename): the same abstraction published to
two sites must take each site's. Of the rest, three are never assigned
anywhere (title_short, publisher, original_publisher; read only by
sqlite.d, always empty) and one is a copy of a field already carried
(title_sub = title_subtitle), so 17 properties actually had to travel
and now do:

  make      breaks, footer, home_button_text
  meta      title.edition, date.added_to_site, language.document_char,
            original.{title,source,language,language_char},
            rights.copyright_{text,translation,illustrations,
            photographs,cover,audio,video}

make splits by when it acts, which is worth keeping in mind: these three
are read in outputs/io_out/ and must travel, while italics, bold,
emphasis, substitute and headings are read at parse time and their
effect is already in the objects.

New @source block, and source.* rows in the database, so a reader can
say which markup an abstraction came from rather than working from
stale content in silence:

  language    the document's own
  languages   the pod's list, which is what the inter-language links
              in html need and neither artefact carried
  digest      sha256 of the .sst; equals its digests.txt entry

The database adds source.ssp_digest, the sha256 of the .ssp it was built
from, since a file cannot hold its own hash. So the chain
.sst -&gt; .ssp -&gt; .ocda.db is checkable end to end.

The database's metadata table is now filled from the header blocks the
.ssp gives back, not from a second list read off doc_matters. One list,
in ssp.d: a property added there arrives in the database with nothing
else changed, and one that is not in the .ssp cannot be in the database
at all. That was the last place the two could drift; the objects stopped
being able to on 2026-09-07.

Version is checked on load. The major part must match, a newer minor is
accepted (a minor bump only adds properties, and an unknown property
line is ignored). A v0.1 artefact is now refused with a message saying
to regenerate it, rather than loading half populated.

test-abstraction-db.sh now compares the two artefacts' header blocks
property by property, 36 per document on the wealth of networks, where
it previously only checked that a schema.version row existed. Verified
non-vacuous: dropping one property is reported.

Reference regenerated, and the whole diff is this change and nothing
else: 320 lines added, 35 removed over 35 files, being 35 format lines
changed, 35 @source blocks (4 lines each), 35 language.document_char, 35
home_button_text (it has a default), 18 breaks, 16 footer,
4 date.added_to_site, 1 title.edition, 1 original.source.

Existing outputs unaffected.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>ocda: .ssp should have all sections of abstraction</title>
<updated>2026-09-12T16:14:39+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-11T12:20:27+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=a341bb94c66807ab666d16810ee5f50a56844a59'/>
<id>a341bb94c66807ab666d16810ee5f50a56844a59</id>
<content type='text'>
The abstraction has nine sections and includes "tail". Both artefact
writers hardcoded a list of eight, so "tail" was silently dropped.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The abstraction has nine sections and includes "tail". Both artefact
writers hardcoded a list of eight, so "tail" was silently dropped.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>.ssp: three additional fields the writers read</title>
<updated>2026-09-09T21:24:26+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-07T14:44:19+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=0bf89ffb9bee8f31715f7492097ce63536869add'/>
<id>0bf89ffb9bee8f31715f7492097ce63536869add</id>
<content type='text'>
With these the .ssp carries every field the output writers read.
The two that were missing were both read by the sqlite search
writer, and one of them is needed by anything that wants to know
where an object sits in a segmented output:

- .segment_html_is / .segment_epub_is
  (tags.html_segment_anchor_tag_is, epub_segment_anchor_tag_is),
  the segment an object *belongs to*, as against .segment
  (in_segment_html), which is the segment a heading *opens* and is
  set on headings only: 32 of 36 headings and 0 of 109 paragraphs
  in the autonomous contract. Without them a reader cannot tell
  which segment a paragraph is in.
- .identifier for non-heading objects, the "a"~N series given to
  objects whose number is suppressed. A heading already carried it
  on its declaration line; every other object now carries it as a
  property, on the same condition, that it differs from the ocn.

The same two segment fields are added to the abstraction db
(segment_html_is, segment_epub_is) and to the cross-check test, so the
two serialisations stay level.

.ssp reference regenerated

output run (--text --latex --epub --html --curate) byte identical
to before the change, as it must be since no output writer reads
either artefact.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
With these the .ssp carries every field the output writers read.
The two that were missing were both read by the sqlite search
writer, and one of them is needed by anything that wants to know
where an object sits in a segmented output:

- .segment_html_is / .segment_epub_is
  (tags.html_segment_anchor_tag_is, epub_segment_anchor_tag_is),
  the segment an object *belongs to*, as against .segment
  (in_segment_html), which is the segment a heading *opens* and is
  set on headings only: 32 of 36 headings and 0 of 109 paragraphs
  in the autonomous contract. Without them a reader cannot tell
  which segment a paragraph is in.
- .identifier for non-heading objects, the "a"~N series given to
  objects whose number is suppressed. A heading already carried it
  on its declaration line; every other object now carries it as a
  property, on the same condition, that it differs from the ocn.

The same two segment fields are added to the abstraction db
(segment_html_is, segment_epub_is) and to the cross-check test, so the
two serialisations stay level.

.ssp reference regenerated

output run (--text --latex --epub --html --curate) byte identical
to before the change, as it must be since no output writer reads
either artefact.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>test-abstraction-ssp re-generated</title>
<updated>2026-09-03T19:25:55+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-03T16:44:01+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=569d38694b10e3de1dc493f5b5ac08f99164b1a0'/>
<id>569d38694b10e3de1dc493f5b5ac08f99164b1a0</id>
<content type='text'>
Several structure fields (now) computed in ocda do not yet have a
consumer outside the `.ssp` writer (which shares ocda fields in a
PEG parsable .ssp file). Their addition is to facilitate future
output processing: each representing document structure
information that document output generators of various formats,
such as html, epub, latex, sql and any DOM based / tree-graph
(node based hierarchical) representations, previously had to, or
would have to, work out for themselves based on what ocda offered
(without them).

Computing them (upstream) in ocda once and sharing them (and
providing the .ssp), means that:

- future output formats can start from prepared structure rather
  than deriving it;

- existing generators can be simplified to consume them instead
  of re-deriving;

- a (dlang) generator could in principle be populated either from
  ocda directly or from a `.ssp` file;

- `.ssp` being PEG parsable puts the same prepared structure in
  reach of implementations in other languages.

`test/test-abstraction-ssp.sh` the `.ssp` reference regression
test is used to catch regression in ocda including these as yet
unused fields, which otherwise would remain unseen until used by
other output-format consumers. This also is the reason issues now
made easily visible and are being addressed (without issue to
existing output generators).

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Several structure fields (now) computed in ocda do not yet have a
consumer outside the `.ssp` writer (which shares ocda fields in a
PEG parsable .ssp file). Their addition is to facilitate future
output processing: each representing document structure
information that document output generators of various formats,
such as html, epub, latex, sql and any DOM based / tree-graph
(node based hierarchical) representations, previously had to, or
would have to, work out for themselves based on what ocda offered
(without them).

Computing them (upstream) in ocda once and sharing them (and
providing the .ssp), means that:

- future output formats can start from prepared structure rather
  than deriving it;

- existing generators can be simplified to consume them instead
  of re-deriving;

- a (dlang) generator could in principle be populated either from
  ocda directly or from a `.ssp` file;

- `.ssp` being PEG parsable puts the same prepared structure in
  reach of implementations in other languages.

`test/test-abstraction-ssp.sh` the `.ssp` reference regression
test is used to catch regression in ocda including these as yet
unused fields, which otherwise would remain unseen until used by
other output-format consumers. This also is the reason issues now
made easily visible and are being addressed (without issue to
existing output generators).

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>test-abstraction-ssp re-generated, abstraction fix</title>
<updated>2026-08-30T17:36:43+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-08-30T17:33:19+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=446d4dc64ffb667fee562880437508ab22765d54'/>
<id>446d4dc64ffb667fee562880437508ab22765d54</id>
<content type='text'>
test-abstraction-ssp re-generated: document abstraction (ocda)
document structure representation fixes (verify)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
test-abstraction-ssp re-generated: document abstraction (ocda)
document structure representation fixes (verify)
</pre>
</div>
</content>
</entry>
<entry>
<title>test build .ssp requires --abstraction to be run</title>
<updated>2026-08-29T00:15:35+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-08-28T19:30:45+00:00</published>
<link rel='alternate' type='text/html' href='https://sisudoc.org/projects/sisudoc-spine/commit/?id=bf4c8f3d12cbe388998a4a975ee380b57e2178da'/>
<id>bf4c8f3d12cbe388998a4a975ee380b57e2178da</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
