feat(core): add portable document ingestion contracts - #1178
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5810e4dca
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
e5810e4 to
5a0ad61
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a0ad615fe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
5a0ad61 to
cbd903c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cbd903c254
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
cbd903c to
fca36b5
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fca36b555a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
fca36b5 to
fa57ffe
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fa57ffe030
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
fa57ffe to
bc13b3d
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc13b3d444
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: phernandez <paul@basicmachines.co>
bc13b3d to
61d7b0d
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61d7b0dd55
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61d7b0dd55
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Signed-off-by: phernandez <paul@basicmachines.co>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 87b60bde48
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| def assemble_document_markdown(document: DocumentMarkdownV1) -> str: | ||
| """Serialize a validated document note into deterministic canonical Markdown.""" | ||
| return _assemble_markdown(document.frontmatter, document.body) |
There was a problem hiding this comment.
Suppress graph semantics for raw extractions
When extracted PDF text contains a line such as - [result] ..., a hashtag, or a wiki link, this serialization emits it as ordinary note content with no stage-specific semantic opt-out, and EntityParser consequently indexes it as an observation or relation. The new test_raw_note_uses_normal_graph_semantics confirms this behavior, so arbitrary raw source text can pollute the knowledge graph before it passes through the bounded enrichment fields; raw-stage documents should remain searchable while semantic parsing is disabled.
AGENTS.md reference: AGENTS.md:L357-L362
Useful? React with 👍 / 👎.
|
Following this contract with interest — the One question before #135 has been open since June 2025 asking for this at the note level — section and observation anchors, so a quote can cite its source precisely. Its first example was a That blocker looks smaller now than it did then. Compared to last year, observations now carry their own permalinks — #1178 is where it becomes load-bearing. I don't have the standing to say what fits your architecture, so I asked Claude to sketch options merely as suggestions. Flagging that explicitly — these are prompts, not recommendations, and I'd defer to your read on all of them of coures:
My own thoughts--once parsed, can it store a page number and line number per page? That nested structure could potentially support direct quote architecture? EDIT (claude helped me understand the constraints better): Related thought — if a span could carry the source checksum alongside its location, a citation becomes verifiable rather than just locatable: you could confirm a quote still matches the document it came from, and detect drift if the source is ever re-extracted. Given how much this contract already checksums, that might be closer to free than it sounds. - Claude Entirely possible this belongs after v1 ships, or that one of these cuts against something I can't see from outside. Mostly I wanted to raise it while the contract is still open rather than after it isn't. |
Why
Hosted document ingestion needs one portable Basic Memory contract for generated Markdown, provenance, deterministic identity, and safe semantic parsing. Without that boundary, Core and Cloud would disagree about what a raw extraction note means, how retries converge, and which fields an enrichment agent may control.
This PR is the Core contract used by basic-memory-cloud#1650, implements the parser-neutral portion of #1006, and deliberately leaves historical revision indexing to #1177.
Specification
Scope
Core must provide strict, provider-neutral contracts for:
type: document;type: document_ingestion_run;Behavioral contract
source,extraction,ingestion, anddocumentmetadata is strict, nested, extra-forbidden, and serializable through either the YAMLschemaalias or the Pythonschema_reffield name.bm_parse_semantics: false; Core preserves body content for search while suppressing observation/relation parsing only for an explicit scalarfalse.Non-goals
Acceptance Criteria
documentanddocument_ingestion_runhave strict versioned Pydantic contracts.What Changed
src/basic_memory/schemas/document.py.src/basic_memory/schemas/__init__.py.document_ingestionnote-object source support.EntityParserto honor the raw semantic opt-out safely without dropping body content.Implementation Details
Testing
Automated
just fast-check: passed Ruff fix/check, formatting, andtytype checking.uv run pytest -q tests/schemas/test_document.py tests/markdown tests/test_runtime.py::TestRuntimeContracts::test_note_object_metadata_parses_safe_values_only: 128 passed;src/basic_memory/schemas/document.pyreached 100% statement coverage.uv run pytest -q --no-cov tests/cli/test_cli_exit.py::test_bm_cli_import_does_not_load_heavy_stack: 1 passed.61d7b0dd55313076a081bad823eb69796d4b8426: unit, SQLite integration, Postgres integration, semantic, Milvus, static, CodeQL, DCO, and CLA jobs passed or were skipped as designed.git diff --check: passed.Manual
Risks / Follow-ups
unknown_key, so this description does not claim GitHub Verified status.