Page metrics (ink / blankness / hue)¶
Deterministic Pillow-only visual metrics over each page’s active render PNG. Separate from text Analyse modules (analysis-document.md) and from visual declutter (source-asset.md declutter provenance).
Identity¶
formatmust be"transcribe.page-metrics"schema_versionmust be1for this contractUnsupported
schema_version→ refuse (no silent upgrade)
Ownership and layout¶
Path |
Role |
|---|---|
|
Current published notebook metrics (optional until first write) |
Creating
page_metrics/on first write is not a project-layout migration; absence remains conformant.Authoritative outputs are project-local under
page_metrics/— never workspace archive SQLite.Cores/algorithm functions are pure over image bytes; the service owns filesystem I/O and publish.
Published document schema (v1)¶
Field |
Type |
Required |
Notes |
|---|---|---|---|
|
string |
yes |
|
|
number |
yes |
|
|
string |
yes |
Must equal |
|
string |
yes |
Frozen algorithm id (e.g. |
|
string |
yes |
Hex SHA-256 of identity payload (below) |
|
string |
yes |
|
|
string |
yes |
ISO-8601 UTC timestamp |
|
object |
yes |
Notebook aggregates (may be empty when insufficient) |
|
array |
yes |
Ordered per-page rows (project page order) |
Per-page row¶
Field |
Type |
Required |
Notes |
|---|---|---|---|
|
string |
yes |
Project-stable page id |
|
string |
yes |
Active render id used |
|
string |
yes |
|
|
number |
yes |
0–100; fraction of pixels classified as ink |
|
number |
yes |
|
|
string |
yes |
Dominant label: |
|
number | null |
no |
Peak hue in degrees when chromatic; else |
|
string |
yes |
Coarse paper hint: |
|
number |
yes |
Analysed pixel width (after optional downsample) |
|
number |
yes |
Analysed pixel height |
|
number |
yes |
Pixels considered |
|
number |
yes |
Ink-classified pixels |
Rollup object¶
Field |
Type |
Notes |
|---|---|---|
|
number |
Rows in |
|
number | null |
Arithmetic mean; |
|
number | null |
Median; |
|
number | null |
|
|
object |
Map label → count of pages with that dominant |
Cache identity¶
Hex SHA-256 of canonical JSON:
{
"algorithm_version": "<string>",
"project_id": "<id>",
"pages": [
{ "page_id": "<id>", "render_sha256": "<hex>" },
...
]
}
pagesfollows project page order among measurable pages (resolvable active render).The notebook’s explicit
cover_page_id(when set) is omitted from identity,pages, and rollups — covers are not treated as ink/paper content. Unsetcover_page_iddoes not imply first-page exclusion (display/Open may still fall back to the first page).Pages whose active render file is missing are omitted from identity and from
pages(service may warn); identity still reflects only successfully measured pages.Changing algorithm version, page set (including cover designation), order, or any active render SHA invalidates the published artifact.
Outcomes¶
Situation |
|
|---|---|
At least one non-cover page measured |
|
Project has no pages / no measurable renders / only the explicit cover is measurable |
|
Atomicity¶
Publish via
write_json_atomictopage_metrics/published.json.Do not hold long compute under
mutation_lock; short lock only if coordinating with other RMW writers (optional for this lane).Stale published file (identity mismatch) must not be treated as fresh — recompute and replace.
Non-goals¶
Not an Analyse text module; not part of presets or
AnalysisDocument.Not OCR preprocess or declutter; does not rewrite page pixels.
No OpenCV / ML segmentation in v1.