<feed xmlns='http://www.w3.org/2005/Atom'>
<title>sisudoc-spine, branch sisudoc-spine_v0.23.0</title>
<subtitle>SiSU Spine: document publishing and search (in D) 2015</subtitle>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/'/>
<entry>
<title>0.23.0</title>
<updated>2026-09-10T14:09:45+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-10T00:30:30+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=7db6602eaadaf69c2882528473bd8694592c1b2c'/>
<id>7db6602eaadaf69c2882528473bd8694592c1b2c</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>--serial default behaviour (--parallel an option)</title>
<updated>2026-09-10T14:02:23+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-09T20:50:25+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=e81fe1d362e430e81fd474569eb7b403db5f66d6'/>
<id>e81fe1d362e430e81fd474569eb7b403db5f66d6</id>
<content type='text'>
serial processing, it turns out, is significantly faster and more
efficient for tested use-cases, which came as a surprise. As the
parallelization option buys nothing, serial processing is set as
default. Parallel processing remains as an option (where
available, as before).

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
serial processing, it turns out, is significantly faster and more
efficient for tested use-cases, which came as a surprise. As the
parallelization option buys nothing, serial processing is set as
default. Parallel processing remains as an option (where
available, as before).

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>parallelise: show_abstraction &amp; ocda_db as the rest</title>
<updated>2026-09-10T00:26:47+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-09T20:34:15+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=359d88c5f4fcaa0f5cd505fa0ac2eb473648f1a6'/>
<id>359d88c5f4fcaa0f5cd505fa0ac2eb473648f1a6</id>
<content type='text'>
Fix issue with consistency (flags run serial &amp; parallel
inconsistenly).

Both write one file per document per language and share no
handle, so they belong on the list with html, epub, text and
sqlite_discrete.

The guard above the list still takes out --pod, --pod2,
--source and the shared sqlite db actions before it is reached, so
those stay serial as they were; checked.

However measurement tests show parallel turn out to result in a
processing slowdown, on the (35) sample markup documents, run on
multiple passes: run on 16 cores a slow down of about 20% for
eleven times the cpu!
  --text                           4.83-5.10 s wall   48-52 s user
  --text --serial                  3.94-4.05 s wall   4.2-4.4 s user

will make serial run the default.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fix issue with consistency (flags run serial &amp; parallel
inconsistenly).

Both write one file per document per language and share no
handle, so they belong on the list with html, epub, text and
sqlite_discrete.

The guard above the list still takes out --pod, --pod2,
--source and the shared sqlite db actions before it is reached, so
those stay serial as they were; checked.

However measurement tests show parallel turn out to result in a
processing slowdown, on the (35) sample markup documents, run on
multiple passes: run on 16 cores a slow down of about 20% for
eleven times the cpu!
  --text                           4.83-5.10 s wall   48-52 s user
  --text --serial                  3.94-4.05 s wall   4.2-4.4 s user

will make serial run the default.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>test: fix, a skipped check is not a pass</title>
<updated>2026-09-10T00:26:39+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-09T20:24:39+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=bc65ad14264e18aabe9711476e99500b4c4bcf76'/>
<id>bc65ad14264e18aabe9711476e99500b4c4bcf76</id>
<content type='text'>
fix of a couple of issues with tests.

test-search-cgi.sh reported PASS while printing "Schema version gate:
skipped, sqlite3 not on PATH", and the values it searches for were the
hardcoded fallbacks rather than values read out of the database it had
just built. Both halves need sqlite3, both are checks, and a run that
leaves them out still exits 0. The other three scripts re-run
themselves under nix shell "nixpkgs#sqlite"; this one now does the
same. sqlite3 is still not required: with neither sqlite3 nor nix the
test runs as before and says what it skipped.

test-abstraction-ssp.sh depends on --abstraction for its meaning, and
nothing in it said so. --show-abstraction does not appear in spine's
parallelise() list, so dropping that one flag turns the current run
serial, and the parallel-versus-serial comparison below it then
compares a serial run with itself - the guard gone, with nothing
failing to report it. That is how the multi-lingual write race survived.
A comment at the call now says not to drop it.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
fix of a couple of issues with tests.

test-search-cgi.sh reported PASS while printing "Schema version gate:
skipped, sqlite3 not on PATH", and the values it searches for were the
hardcoded fallbacks rather than values read out of the database it had
just built. Both halves need sqlite3, both are checks, and a run that
leaves them out still exits 0. The other three scripts re-run
themselves under nix shell "nixpkgs#sqlite"; this one now does the
same. sqlite3 is still not required: with neither sqlite3 nor nix the
test runs as before and says what it skipped.

test-abstraction-ssp.sh depends on --abstraction for its meaning, and
nothing in it said so. --show-abstraction does not appear in spine's
parallelise() list, so dropping that one flag turns the current run
serial, and the parallel-versus-serial comparison below it then
compares a serial run with itself - the guard gone, with nothing
failing to report it. That is how the multi-lingual write race survived.
A comment at the call now says not to drop it.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>ssp: abstraction directory cleared once</title>
<updated>2026-09-10T00:26:33+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-09T20:12:37+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=a87c7dbef6968f496168f6d2cfe249bb150e0e27'/>
<id>a87c7dbef6968f496168f6d2cfe249bb150e0e27</id>
<content type='text'>
abstraction directory cleared once, by whichever language is first

The .ssp writer clears stale files out of
pod/&lt;doc&gt;/media/abstraction/, and that one directory is shared by
every language of a document. The clearing is now done once per
directory per run, by whichever language reaches it first, with
the lock held across it. A language that finds the directory
already prepared has passed through that same lock before writing,
so the clearing it skipped had completed before its own write
began: no .ssp produced on a given run can be removed during it.

(removes possibility of a race condition on parallelisation)

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
abstraction directory cleared once, by whichever language is first

The .ssp writer clears stale files out of
pod/&lt;doc&gt;/media/abstraction/, and that one directory is shared by
every language of a document. The clearing is now done once per
directory per run, by whichever language reaches it first, with
the lock held across it. A language that finds the directory
already prepared has passed through that same lock before writing,
so the clearing it skipped had completed before its own write
began: no .ssp produced on a given run can be removed during it.

(removes possibility of a race condition on parallelisation)

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>sqlite: schema version, &amp; fail run on writes fail</title>
<updated>2026-09-10T00:26:27+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-09T16:05:55+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=12b1a42d654ac2bdde984a671b4b55ae595ae2fd'/>
<id>12b1a42d654ac2bdde984a671b4b55ae595ae2fd</id>
<content type='text'>
Spine now declares sqlite_db_schema_version and stamps it into the
database as PRAGMA user_version when the tables are created, in
both the shared and the discrete DDL blocks. On opening an
existing database it compares, and says once per run which version
it found and which it writes.

Failures are now tallied (shared, the output can run in parallel),
reported one line each on stderr naming the operation, and main
exits 1 without printing "run complete, ok".

Two tests under test/, both taking the spine binary as their first
argument and building their own database from data/pod unless
$SpinePOD says otherwise:
  test-search-db-schema.sh  names: every column the search form
    uses exists, and spine's declaration, the database's stamp
    and the search form's expectation all agree
  test-search-cgi.sh  behaviour: the real search binary answers
    real requests against a fresh database, no web server
    involved, the probe values read out of whichever database it
    is given

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Spine now declares sqlite_db_schema_version and stamps it into the
database as PRAGMA user_version when the tables are created, in
both the shared and the discrete DDL blocks. On opening an
existing database it compares, and says once per run which version
it found and which it writes.

Failures are now tallied (shared, the output can run in parallel),
reported one line each on stderr naming the operation, and main
exits 1 without printing "run complete, ok".

Two tests under test/, both taking the spine binary as their first
argument and building their own database from data/pod unless
$SpinePOD says otherwise:
  test-search-db-schema.sh  names: every column the search form
    uses exists, and spine's declaration, the database's stamp
    and the search form's expectation all agree
  test-search-cgi.sh  behaviour: the real search binary answers
    real requests against a fresh database, no web server
    involved, the probe values read out of whichever database it
    is given

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>html metadata: a link to the ocda.db</title>
<updated>2026-09-09T23:04:06+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-08T22:44:45+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=c6e822e3ce4b096163e0016e5735ef9c16e8997f'/>
<id>c6e822e3ce4b096163e0016e5735ef9c16e8997f</id>
<content type='text'>
The metadata page gains a line between the markup source and the
source digests.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The metadata page gains a line between the markup source and the
source digests.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>--ocda-db replaces --show-abstraction-db</title>
<updated>2026-09-09T23:03:54+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-08T21:30:00+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=557810df54fb5411c362528b459648611e8267ba'/>
<id>557810df54fb5411c362528b459648611e8267ba</id>
<content type='text'>
ocda (object centric document abstraction)

flag --ocda-db (or --abstraction-db)
replaces --show-abstraction-db

rename results in consequently large diff
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ocda (object centric document abstraction)

flag --ocda-db (or --abstraction-db)
replaces --show-abstraction-db

rename results in consequently large diff
</pre>
</div>
</content>
</entry>
<entry>
<title>output: the abstraction artefacts live with the pod</title>
<updated>2026-09-09T22:28:25+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-08T20:09:44+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=c16ada7749d842fa868b7b8b25a1ff17ffdf7b40'/>
<id>c16ada7749d842fa868b7b8b25a1ff17ffdf7b40</id>
<content type='text'>
pod/ holds all document source representations:
  pod/&lt;doc&gt;/                             source tree
  pod/&lt;doc&gt;/media/abstraction/&lt;uid&gt;.ssp  abstraction, as text
  pod/&lt;doc&gt;.zip                          tree, zipped, .ssp included
  pod/&lt;doc&gt;.digests.txt                  sha256s of what is in them
  pod/&lt;uid&gt;.ocda.db                      abstraction, as sqlite db

&lt;lang&gt;/abstraction/ is gone.
pod/&lt;doc&gt;/media/abstraction/&lt;uid&gt;.ssp preferred as having the
images (found within the pod tree) which .ssp needs to reproduce a
document but does not carry on its own.

The .ocda.db sits carries the images as well and (like the
pod.zip) can be used to reproduce a document directly.

digests.txt now covers the database as well as the zip, the source
and the .ssp; (as does the metadata html page).

Two ordering issues addressed:
- the pod builder clean-slates pod/&lt;doc&gt;/ before regenerating it,
  and the .ssp is now written before that runs. The clean slate
  now leaves media/abstraction/ alone, and the .ssp writer clears
  that directory itself on the first language of a run, so a .ssp
  for a language the document no longer is removed and cannot be
  bundled.
- for a multi-language document the .ssp files accumulate one
  language at a time and are bundled on the last, which is why the
  directory cannot simply be emptied by whichever (language) gets
  there first.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
pod/ holds all document source representations:
  pod/&lt;doc&gt;/                             source tree
  pod/&lt;doc&gt;/media/abstraction/&lt;uid&gt;.ssp  abstraction, as text
  pod/&lt;doc&gt;.zip                          tree, zipped, .ssp included
  pod/&lt;doc&gt;.digests.txt                  sha256s of what is in them
  pod/&lt;uid&gt;.ocda.db                      abstraction, as sqlite db

&lt;lang&gt;/abstraction/ is gone.
pod/&lt;doc&gt;/media/abstraction/&lt;uid&gt;.ssp preferred as having the
images (found within the pod tree) which .ssp needs to reproduce a
document but does not carry on its own.

The .ocda.db sits carries the images as well and (like the
pod.zip) can be used to reproduce a document directly.

digests.txt now covers the database as well as the zip, the source
and the .ssp; (as does the metadata html page).

Two ordering issues addressed:
- the pod builder clean-slates pod/&lt;doc&gt;/ before regenerating it,
  and the .ssp is now written before that runs. The clean slate
  now leaves media/abstraction/ alone, and the .ssp writer clears
  that directory itself on the first language of a run, so a .ssp
  for a language the document no longer is removed and cannot be
  bundled.
- for a multi-language document the .ssp files accumulate one
  language at a time and are bundled on the last, which is why the
  directory cannot simply be emptied by whichever (language) gets
  there first.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
<entry>
<title>ocda loader: one way in whatever the source</title>
<updated>2026-09-09T22:22:47+00:00</updated>
<author>
<name>Ralph Amissah</name>
<email>ralph.amissah@gmail.com</email>
</author>
<published>2026-09-08T17:52:43+00:00</published>
<link rel='alternate' type='text/html' href='https://amissah.org/projects/sisudoc-spine/commit/?id=c7049608de7d163137521495665753ae7070be08'/>
<id>c7049608de7d163137521495665753ae7070be08</id>
<content type='text'>
sisudoc.ocda.abstraction.load names the five things a document can
be read from, tells them apart, and loads the two that are
self-describing artefacts:

  .sst / .ssm  + images   the markup source
  pod (dir)    + images   the same, bundled
  pod .zip                the same, zipped
  .ssp         + images   the abstraction, as text
  .ocda.db                the abstraction, sqlite, images inside

abstractionSourceOf(path) is the detection, by name and for a
directory by whether it holds pod.manifest. abstractionLoad(path)
returns a LoadedAbstraction: the source kind, whether it was
loaded, why not when it was not, and the document itself.

The three source forms are deliberately not loaded here. Reading
them is the parser's job (sisudoc.ocda.meta.metadoc
spineAbstraction) and it needs the manifest, environment and
configuration that spine.d assembles, none of which belongs in a
loader. What this gives that case is the dispatch and a plain
statement of where it is handled, rather than a silent empty
result.

  spine --abstraction-source=&lt;path&gt;

says what a path is and, for an artefact, loads it and reports
what came back: the document, title and author, header block
sizes, object counts and the objects in each section. Exit 0 when
an abstraction was loaded, 1 when not.

(assisted by Claude-Code)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
sisudoc.ocda.abstraction.load names the five things a document can
be read from, tells them apart, and loads the two that are
self-describing artefacts:

  .sst / .ssm  + images   the markup source
  pod (dir)    + images   the same, bundled
  pod .zip                the same, zipped
  .ssp         + images   the abstraction, as text
  .ocda.db                the abstraction, sqlite, images inside

abstractionSourceOf(path) is the detection, by name and for a
directory by whether it holds pod.manifest. abstractionLoad(path)
returns a LoadedAbstraction: the source kind, whether it was
loaded, why not when it was not, and the document itself.

The three source forms are deliberately not loaded here. Reading
them is the parser's job (sisudoc.ocda.meta.metadoc
spineAbstraction) and it needs the manifest, environment and
configuration that spine.d assembles, none of which belongs in a
loader. What this gives that case is the dispatch and a plain
statement of where it is handled, rather than a silent empty
result.

  spine --abstraction-source=&lt;path&gt;

says what a path is and, for an artefact, loads it and reports
what came back: the document, title and author, header block
sizes, object counts and the objects in each section. Exit 0 when
an abstraction was loaded, 1 when not.

(assisted by Claude-Code)
</pre>
</div>
</content>
</entry>
</feed>
