nx_text_ingest.nx
buildroot/runtime/nx_text_ingest.nx
about
nx_text_ingest.nx -- text-medium ingester targeting media-agnostic schema.
Tier-1 ingester in the multi-media stack. Consumes a MediaItem of
type TEXT or HTML from a StoryDb's MediaPool and emits StoryBeats
+ StoryScenes + StoryChapters into the same StoryDb.
Supersedes nx_narrative_ingest.nx (kept in tree as deprecation
pointer until concurrent-agent wiring catches up). The two
differ in ONE thing: this one writes beats into the canonical
nx_storybeat.nx schema so the rest of the director pipeline
(nx_arc / nx_moment_resolve / nx_directors_note) consumes them
uniformly with image / gif / video / audio beats.
Scope: structural parse only. Marks paragraphs as NARRATION,
scene breaks as TRANSITION, headings as HEADING. Semantic
classification (DIALOGUE / ACTION / DESCRIPTION / INTERIORITY /
GESTURE) is the next layer (nx_text_beat_classify.nx).
Sources expected:
* URL via nishi-browser fetch -> nx_media_fetch.nx
* Manual paste via stdin -> nx_media_fetch.nx
* Filesystem path -> nx_media_fetch.nx
* Voice dictation -> nx_media_fetch.nx
* Batch directory walk -> nx_ingest_runner.nx (Tier 5)
genealogy_id: propp_morphology_1928 (narrative structural roots)
+ commonmark_2014 (heading / blank-line rules)
Composes with:
nx_storybeat.nx -- writes here
nx_storydb.nx -- container
nx_media_pool.nx -- reads source bytes via media_id
nx_media_sniff.nx -- caller already classified
nx_safety_envelope:
intended_use: "Parse text-medium MediaItem into structured
beats / scenes / chapters in the canonical
media-agnostic StoryBeat schema."
sil_target: SIL2
asil_target: QM
dependencies 4 imports · 7 importers
imports: nx_syscalls.nxnx_storybeat.nxnx_storydb.nxnx_media_pool.nx
imported by: nx_arc_anchor_test.nxnx_caption_emit_test.nxnx_content_guard_test.nxnx_ingest_cli.nxnx_scene_index_test.nxnx_term_extract_test.nxnx_text_ingest_test.nx
structs
| none |
consts
| 62 | const NX_TEXT_INGEST_OK: i64 = 0 |
| 63 | const NX_TEXT_INGEST_BAD_MEDIA_ID: i64 = -1 |
| 64 | const NX_TEXT_INGEST_EMPTY: i64 = -2 |
| 65 | const NX_TEXT_INGEST_NOT_TEXT: i64 = -3 |
| 66 | const NX_TEXT_INGEST_BUDGET_EXHAUSTED: i64 = -4 |
| 67 | const NX_TEXT_INGEST_BEATS_FULL: i64 = -5 |
| 74 | const NX_TEXT_INGEST_BUDGET_PAD: i64 = 16 |
functions
| 78 | func nx_text_load_u8(p: *u8, i: i64) -> i64 |
| 83 | func nx_text_is_ws(c: i64) -> i64 |
| 91 | func nx_text_is_horiz_ws(c: i64) -> i64 |
| 101 | func nx_text_is_scene_break(src: *u8, pos: i64, len: i64) -> i64 |
| 144 | func nx_text_is_heading(src: *u8, pos: i64, len: i64) -> i64 |
| 174 | func nx_text_skip_blank_lines(src: *u8, cur: *i64, len: i64) -> i64 |
| 221 | func nx_text_line_end(src: *u8, pos: i64, len: i64) -> i64 |
| 242 | func nx_text_classify_paragraph(src: *u8, start: i64, end: i64) -> i64 |
| 270 | func nx_text_ingest(db: *StoryDb, media_id: i64) -> i64 |