Notebook eligibility

Compatibility policy name: notebook_eligibility_v1

This is the only permitted stand-in for TranscriptX insight_eligibility in the core set. Ports must not invent per-module eligibility stubs, softeners, or silent bypasses. Modules that TX gated with insight_eligibility either:

  1. Invoke this policy (required list below), or

  2. Are explicitly ungated in this contract (documented deliberate choice), or

  3. Use a named notebook-native substitute recorded here or in the pin row’s semantic_delta (e.g. moments salience fork — not an eligibility stub)

Used with analysis-document.md. Contributes to cache identity via analysis-run-storage.md. Outcomes: analysis-result.md.

Identity

Field

Value

policy_id

notebook_eligibility_v1

policy_version

1

Purpose

Decide which analysis units are eligible for modules that must not run on empty, excluded, or trivially non-content units.

Deterministic inputs

Input

Notes

Candidate units[]

From the adapter’s pre-eligibility unit list (same id/text/order/date/source_ref rules as analysis-document)

Per-page include flag

Page excluded from analysis ⇒ units for that page_id are ineligible (reason: excluded)

Effective texts

Already reflected in unit text (edited vs raw per page-result)

No randomness. No I/O. No Speakers. No wall-clock.

Deterministic outputs

{
  "policy_id": "notebook_eligibility_v1",
  "policy_version": "1",
  "eligible_unit_ids": ["...", "..."],  // sorted ascending
  "decisions": [
    {
      "unit_id": "...",
      "eligible": true | false,
      "reason": "ok" | "excluded" | "empty_or_whitespace" | "too_short"
    },
    ...
  ]
}

decisions sorted by unit_id ascending. eligible_unit_ids is exactly the set of decisions with eligible: true, sorted.

Rules (policy_version 1)

Evaluate each unit in isolation:

Reason

Condition

Eligible

excluded

Backing page marked excluded from analysis

no

empty_or_whitespace

unit.text empty or only Unicode whitespace

no

too_short

After whitespace-trim, character length < 3

no

ok

otherwise

yes

If no units are eligible → modules that require this policy conclude outcome: skipped_not_applicable (see analysis-result edge-case table).

Modules that must invoke this policy

These modules must call notebook_eligibility_v1 and build their AnalysisDocument.units from the eligible set only (or equivalently filter before fingerprinting the document they persist):

  • keyphrases

  • topic_modeling

  • bertopic

  • highlights

  • insights

Explicit core resolutions (no ad-hoc stubs)

Module / path

Policy

keyphrases, topic_modeling, bertopic, highlights, insights

Required: notebook_eligibility_v1

wordclouds (base)

Ungated relative to TX insight eligibility — runs on document text / units after blank+excluded omission

wordclouds + keyphrase enrichment

Optional parent keyphrases only when that parent is a compatible published success; otherwise baseline token cloud (analysis-run-storage.md)

moments

Not an eligibility bypass — notebook-native salience fork (no TX momentum); does not call notebook_eligibility_v1 unless a future contract version adds it

stats, lexical_diversity, understandability, ner, sentiment, entity_sentiment, epistemic_markers, semantic_similarity, topic_shift, emotion family, affect_tension, LLM suite

Ungated by this policy in the core set (blank/excluded pages still omitted by the adapter per analysis-document)

Compatibility tests (required)

Implementation must include tests that:

  1. Each required module invokes notebook_eligibility_v1 (not a private filter)

  2. Empty / whitespace / too-short / excluded units are dropped with the named reasons

  3. Zero eligible units → skipped_not_applicable, not empty success

  4. wordclouds without keyphrases still succeeds on baseline path

  5. No module ships an inline “softened insight_eligibility” stub

Cache identity contribution

When a module uses this policy, analysis-run-storage cache identity must include:

  • eligibility_policy_id = notebook_eligibility_v1

  • eligibility_policy_version = 1

  • eligibility_fingerprint = lowercase hex SHA-256 of compact UTF-8 JSON with sorted keys of the outputs object above (policy_id, policy_version, eligible_unit_ids, decisions)

Non-goals

  • Full TranscriptX insight_eligibility / genre gating (later disposition rows)

  • Per-module private eligibility heuristics for the modules listed as required above

  • Treating “bypass” as an implementation free-for-all