nx_doc_annotate.nx
buildroot/runtime/nx_doc_annotate.nx
about
nx_doc_annotate.nx -- LEGAL RUNG D4: the sovereign annotation / markup overlay.
module: nishi-core.legal.doc_annotate
capability: LEGAL_DOC_ANNOTATE
The "sticky-notes / markup / feedback / lists" half of the DocuSign-better
document experience. A FORMAT-AGNOSTIC overlay: it never parses the document,
it anchors annotations to a {doc_id, version, page} so it sits ON TOP of any
format (PDF / DOCX / our own doc format) without depending on it. Each
annotation is a note, threaded comment, redline (strike + propose), highlight,
checklist item, or signature-field placement, carried through an
open -> resolved/accepted/rejected/done review lifecycle with author
attribution and a resolver audit.
The s-class safety invariant (the analog of D0/D5's never-void): once a
document's envelope is COMPLETED (signed), its overlay is IMMUTABLE -- you
cannot add or re-status an annotation on a signed agreement. The caller passes
`frozen` = (the doc's envelope is completed); add / resolve REFUSE when frozen.
Plus: review history is additive (Rule 13 -- rejected redlines are retained,
never deleted), annotations are pinned to the version they were made on (a
version bump does not silently move them), and a REQUIRED checklist gates the
envelope send (compose with D2: a portal checks nx_ann_checklist_complete
before nx_env_send).
Representation: caller-allocated flat i64 record arrays (mirrors nx_doc_vault /
nx_doc_envelope; no internal allocation). Pure logic core -> self-contained gate.
Composes (at the gate): nx_doc_envelope (D2 frozen=COMPLETED + checklist-gates-
send), nx_doc_vault (D1 versions). Distinct from nx_doc_envelope because: that
is the signing lifecycle; this is the in-document review/markup overlay around it.
license_tier: ORIGINAL
lineage_id: nishi_doc_annotate_d4
dependencies 1 imports · 8 importers
imports: nx_syscalls.nx
imported by: nx_doc_annotate_gate.nxnx_legal_portal.nxnx_legal_portal_boot.nxnx_legal_portal_boot_gate.nxnx_legal_portal_daemon.nxnx_legal_portal_gate.nxnx_legal_portal_live_gate.nxnx_legal_portal_post_gate.nx
structs
| none |
consts
| 36 | const AN_NOTE: i64 = 0 // sticky note |
| 37 | const AN_COMMENT: i64 = 1 // threaded comment (can have replies via NF_PARENT) |
| 38 | const AN_REDLINE: i64 = 2 // strike + propose replacement (accept/reject) |
| 39 | const AN_HIGHLIGHT: i64 = 3 |
| 40 | const AN_CHECK: i64 = 4 // checklist item (done via AS_DONE) |
| 41 | const AN_SIGFIELD: i64 = 5 // signature-field placement (which signer, which page) |
| 44 | const AS_OPEN: i64 = 0 |
| 45 | const AS_RESOLVED: i64 = 1 // comment resolved |
| 46 | const AS_ACCEPTED: i64 = 2 // redline adopted |
| 47 | const AS_REJECTED: i64 = 3 // redline declined (retained -- additive) |
| 48 | const AS_DONE: i64 = 4 // checklist item done / sigfield filled |
| 51 | const ANF_REQUIRED: i64 = 1 // a required checklist item (gates send) |
| 54 | const ANR_OK: i64 = 0 |
| 55 | const ANR_FROZEN: i64 = 1 // doc's envelope is COMPLETED -> overlay immutable |
| 56 | const ANR_NOT_FOUND: i64 = 2 |
| 57 | const ANR_FULL: i64 = 3 |
| 60 | const NF_ANN: i64 = 0 // annotation id |
| 61 | const NF_DOC: i64 = 1 // doc id |
| 62 | const NF_VER: i64 = 2 // document version this annotation is pinned to |
| 63 | const NF_TYPE: i64 = 3 |
| 64 | const NF_AUTHOR: i64 = 4 |
| 65 | const NF_PAGE: i64 = 5 // page anchor (format-agnostic; pixel x/y = display layer) |
| 66 | const NF_STATUS: i64 = 6 |
| 67 | const NF_PARENT: i64 = 7 // parent annotation id for threaded replies (0 = top-level) |
| 68 | const NF_FLAGS: i64 = 8 |
| 69 | const NF_TS: i64 = 9 |
| 70 | const NF_RESOLVER: i64 = 10 // who accepted/rejected/resolved (audit) |
| 71 | const NF_STRIDE: i64 = 11 |
functions
| 74 | func na_find(flat_an: *i64, na: i64, ann_id: i64) -> i64 |
| 84 | func na_put(flat_an: *i64, na: i64, ann_id: i64, doc_id: i64, ver: i64, |
| 104 | func nx_ann_add(flat_an: *i64, na: i64, cap: i64, frozen: i64, |
| 113 | func nx_ann_add_reply(flat_an: *i64, na: i64, cap: i64, frozen: i64, |
| 122 | func nx_ann_resolve(flat_an: *i64, na: i64, frozen: i64, ann_id: i64, |
| 134 | func nx_ann_status(flat_an: *i64, na: i64, ann_id: i64) -> i64 |
| 140 | func nx_ann_author(flat_an: *i64, na: i64, ann_id: i64) -> i64 |
| 147 | func nx_ann_count(flat_an: *i64, na: i64, doc_id: i64, ver: i64) -> i64 |
| 159 | func nx_ann_count_type(flat_an: *i64, na: i64, doc_id: i64, ver: i64, atype: i64) -> i64 called by 1: main |
| 175 | func nx_ann_checklist_remaining(flat_an: *i64, na: i64, doc_id: i64, ver: i64) -> i64 |
| 195 | func nx_ann_checklist_complete(flat_an: *i64, na: i64, doc_id: i64, ver: i64) -> i64 |
| 201 | func nx_ann_thread_replies(flat_an: *i64, na: i64, parent_id: i64) -> i64 called by 1: main |
| 211 | func nx_ann_type_name(t: i64) -> *u8 |