From 834af0ae43f63df2ecd7d6fe514aa404c52383ce Mon Sep 17 00:00:00 2001 From: John McChesney TenEyck Jr Date: Sat, 23 May 2026 22:25:58 +0100 Subject: [PATCH] Document v0.1 scope and integration stubs --- AGENTS.md | 1 + CHANGELOG.md | 39 ++++++++++++ README.md | 27 ++++++++- docs/integration/live-export.md | 38 ++++++++++++ docs/integration/live-mailplus-adapter.md | 72 +++++++++++++++++++++++ docs/versioning.md | 22 +++++++ src/mailplus_intelligence/__init__.py | 8 +++ tests/test_runtime.py | 6 +- 8 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 docs/integration/live-export.md create mode 100644 docs/integration/live-mailplus-adapter.md create mode 100644 docs/versioning.md diff --git a/AGENTS.md b/AGENTS.md index 96671ea..35edbc5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,3 +14,4 @@ - Treat `project.bootstrap.yaml` as the source of truth for repo governance, environments, CI policy, and home profile sync. - If OpenClaw local skills are available, use the `omt-bootstrap` skill for manifest-first bootstrap work instead of rediscovering the workflow. - Review `docs/bootstrap/onboarding.md` before first merge to confirm reviewers, runner labels, and environment gates match the project. +- The R1-R6 GitHub issues with the `release-v0.1` label drive the public v0.1.0 release. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7d53da0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,39 @@ +# Changelog + +All notable changes to MailPlus Intelligence are documented here. + +The format follows Keep a Changelog, and this project uses the versioning +policy in [docs/versioning.md](docs/versioning.md). + +## [Unreleased] + +- Prepare public-release polish, release workflow, and repo metadata before the + v0.1.0 visibility/tagging gate. + +## [0.1.0] - 2026-05-23 + +### Added + +- Canonical-store boundary and privacy/redaction rules for keeping MailPlus as + the raw-message archive. +- Metadata fixture corpus, SQLite schema bootstrap, and index/search helpers. +- Deterministic thread reconstruction with confidence evidence. +- Classification lanes, noise suppression policy, and fixture coverage. +- Deterministic semantic extraction, LLM cassette playback, and optional live + LLM extraction surface. +- Selected-message text cache policy, promotion queue, dry-run exporters, and + scheduler locks. +- CLI commands for search, thread inspection, queue review, dry-run export, + sync status, and doctor checks. +- Live adapter and raw-fetch interface stubs for future credential-gated Phase + 2 integration. + +### Changed + +- Public docs now call out fixture-mode support separately from live MailPlus + and production export work. + +### Security + +- Added fixture/privacy boundaries and fast validation gates sized for a public + repo before live MailPlus credential handling exists. diff --git a/README.md b/README.md index de5de9d..e2c4c49 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,25 @@ Those distilled outputs can then feed: - future entity/concept pages - reminders/tasks when explicitly approved +## What's in v0.1 + +### Working end-to-end + +v0.1 is a fixture-mode release. It supports metadata fixture sync, SQLite +schema bootstrap, deterministic thread reconstruction, lane classification, +noise suppression, deterministic semantic extraction, LLM extraction when the +optional `llm` extra and API key are configured, promotion queue review, +dry-run exporters, scheduler locks, CLI inspection, and `mpi doctor`. + +### Stubbed / not-yet-wired + +- Live MailPlus/IMAP ingestion is not connected yet. The public adapter shape + is documented in [the live MailPlus adapter guide](docs/integration/live-mailplus-adapter.md) + and tracked for Phase 2 in [issue #75](https://github.com/OMT-Global/mailplus-intelligence/issues/75). +- Production export to wiki, `memory/`, or reminders is dry-run only. The + future live export contract is documented in [the live export guide](docs/integration/live-export.md) + and tracked for Phase 2 in [issue #75](https://github.com/OMT-Global/mailplus-intelligence/issues/75). + ## What should not go into memory Avoid dumping: @@ -125,7 +144,10 @@ Phase 1 should support practical operator questions like: ## Roadmap status -The current roadmap is tracked in GitHub issues for this repository. +The v0.1 public-release blockers are tracked with the +[`release-v0.1` label](https://github.com/OMT-Global/mailplus-intelligence/issues?q=is%3Aissue+is%3Aopen+label%3Arelease-v0.1). +Phase 2 live integration work is tracked in +[issue #75](https://github.com/OMT-Global/mailplus-intelligence/issues/75). Primary epics include: @@ -138,6 +160,9 @@ Primary epics include: - memory/wiki promotion - phase-1 medium-architecture delivery +Release history is tracked in [CHANGELOG.md](CHANGELOG.md), and versioning +policy is documented in [docs/versioning.md](docs/versioning.md). + ## Agent execution - [Agent execution playbook](docs/agent-execution/playbook.md) diff --git a/docs/integration/live-export.md b/docs/integration/live-export.md new file mode 100644 index 0000000..0df1363 --- /dev/null +++ b/docs/integration/live-export.md @@ -0,0 +1,38 @@ +# Live Export Integration + +Production export to wiki pages, `memory/`, or reminders is v0.2 territory. +v0.1 only writes dry-run artifacts so reviewers can inspect candidate output +before anything durable changes. + +## Required Guarantees + +A live exporter must honor: + +- provenance: every durable write keeps source thread, message IDs, locators, + evidence references, confidence, and review status +- idempotency: rerunning the same approved candidate does not create duplicate + wiki, memory, or reminder entries +- rollback: every write records enough target metadata to undo or supersede it +- review boundary: only `approved` or `corrected` candidates may leave the + dry-run surface +- privacy boundary: raw message bodies and attachment payloads are never + exported into durable memory surfaces + +See [promotion review workflow](../promotion-review-workflow.md) for the +human-review states that gate live writes. + +## Target-Specific Notes + +Wiki and `memory/` exporters should prefer stable page or note identifiers over +title matching. Reminder exporters should store the source artifact ID in the +target metadata when the target system allows it. + +## Operator Flow + +1. Run extraction and review candidates in the promotion queue. +2. Approve or correct only the artifacts that should become durable memory. +3. Run the exporter in dry-run mode and inspect the manifest. +4. Run the live exporter with an explicit target and rollback path. + +Live export PRs are welcome once they include dry-run parity tests, rollback +evidence, and target-specific idempotency tests. diff --git a/docs/integration/live-mailplus-adapter.md b/docs/integration/live-mailplus-adapter.md new file mode 100644 index 0000000..9cda254 --- /dev/null +++ b/docs/integration/live-mailplus-adapter.md @@ -0,0 +1,72 @@ +# Live MailPlus Adapter Integration + +The live adapter is v0.2 territory. v0.1 ships the stable boundary and fixture +mode, but `_fetch_messages()` intentionally returns an empty batch until a real +MailPlus or IMAP client is wired in. + +## Expected Configuration + +`src/mailplus_intelligence/live_adapter.py` reads these environment variables: + +| Variable | Required | Purpose | +| --- | --- | --- | +| `MAILPLUS_HOST` | yes | MailPlus API or IMAP host | +| `MAILPLUS_USER` | yes | Mailbox identity | +| `MAILPLUS_TOKEN` | yes | OAuth token or app password | +| `MAILPLUS_MAILBOX` | no | Mailbox/folder root, default `INBOX` | +| `MAILPLUS_PAGE_SIZE` | no | Batch size, default `50` | + +Missing required values raise `LiveAdapterNotConfigured`; fixture-mode tests +should continue to treat that as a gated state, not a failure. + +## SyncBatch Shape + +Live ingestion must return the same `SyncBatch` shape as fixture ingestion: + +- `source_name`: stable source identifier such as `mailplus:` +- `cursor`: previous cursor supplied by the scheduler or checkpoint +- `next_cursor`: cursor for the next incremental sync +- `messages`: list of metadata-only message dictionaries + +Each message should include source account/mailbox/folder, stable UID, message +ID, references/in-reply-to headers when present, sender/recipients, subject, +sent date, labels/flags, locator fields, and attachment metadata. It must not +include raw message bodies. + +## Worked IMAP Stub + +```python +from mailplus_intelligence.live_adapter import LiveAdapterConfig +from mailplus_intelligence.sync import SyncBatch + + +def fetch_imap_metadata(config: LiveAdapterConfig, cursor: str = "") -> SyncBatch: + messages = [ + { + "fixture_id": "imap:123", + "message_id": "", + "subject": "Example subject", + "from": "sender@example.test", + "to": ["operator@example.test"], + "date": "2026-05-23T12:00:00Z", + "mailbox": config.user, + "folder": config.mailbox, + "locator": { + "export_id": "imap-demo", + "uid": "123", + "account": config.user, + }, + "attachments": [], + } + ] + return SyncBatch( + source_name=f"mailplus:{config.user}", + cursor=cursor, + next_cursor="123", + messages=messages, + ) +``` + +PRs are welcome for a real adapter once they preserve the metadata-only +boundary, fail closed on credential or locator drift, and include fixture-mode +tests that do not require live credentials. diff --git a/docs/versioning.md b/docs/versioning.md new file mode 100644 index 0000000..34ee6f0 --- /dev/null +++ b/docs/versioning.md @@ -0,0 +1,22 @@ +# Versioning + +MailPlus Intelligence uses semantic versioning after public release. + +## 0.x Policy + +While the project is in `0.x`, breaking changes can ship in minor releases +when they are documented in `CHANGELOG.md`. Patch releases should remain +backward compatible unless a security fix requires otherwise. + +## Source Of Truth + +The package version is declared in `pyproject.toml` and exposed at runtime as +`mailplus_intelligence.__version__` through `importlib.metadata`. Do not copy +the version into README examples or docs unless the surrounding text is release +history. + +## Release Notes + +Every release should update `CHANGELOG.md` with operator-facing changes, known +stubs, and any compatibility notes. Commit-level detail belongs in the GitHub +history, not the changelog. diff --git a/src/mailplus_intelligence/__init__.py b/src/mailplus_intelligence/__init__.py index bd802f3..5e03cce 100644 --- a/src/mailplus_intelligence/__init__.py +++ b/src/mailplus_intelligence/__init__.py @@ -1,16 +1,24 @@ """MailPlus Intelligence runtime foundations.""" +from importlib.metadata import PackageNotFoundError, version + from .fixtures import MetadataFixtureCorpus, load_metadata_fixture_corpus from .runtime import RuntimeProfile, default_runtime_profile from .schema import apply_all_migrations, apply_schema_v0, current_schema_version from .sqlite import connect_sqlite from .suppression import SUPPRESSION_FAMILIES, SuppressionDecision, classify_noise_suppression +try: + __version__ = version("mailplus-intelligence") +except PackageNotFoundError: + __version__ = "0.0.0+local" + __all__ = [ "MetadataFixtureCorpus", "RuntimeProfile", "SUPPRESSION_FAMILIES", "SuppressionDecision", + "__version__", "apply_all_migrations", "apply_schema_v0", "classify_noise_suppression", diff --git a/tests/test_runtime.py b/tests/test_runtime.py index b75b6a2..e19df66 100644 --- a/tests/test_runtime.py +++ b/tests/test_runtime.py @@ -4,7 +4,7 @@ import unittest from pathlib import Path -from mailplus_intelligence import connect_sqlite, default_runtime_profile +from mailplus_intelligence import __version__, connect_sqlite, default_runtime_profile class RuntimeBaselineTests(unittest.TestCase): @@ -16,6 +16,10 @@ def test_default_runtime_profile_is_python_sqlite_and_non_live(self) -> None: self.assertEqual(profile.storage_engine, "sqlite") self.assertFalse(profile.live_mailplus_access) + def test_package_version_is_exposed(self) -> None: + self.assertIsInstance(__version__, str) + self.assertGreater(len(__version__), 0) + def test_sqlite_connection_supports_index_style_round_trip(self) -> None: with tempfile.TemporaryDirectory() as tmpdir: database = Path(tmpdir) / "mailplus-intelligence.db"