Skip to content

#57 docs: a dispatch-essence change is notice, not coordination - #60

Merged
gregoryfoster merged 3 commits into
mainfrom
57-dispatch-essence-notice
Oct 21, 2026
Merged

gregoryfoster merged 3 commits into
mainfrom
57-dispatch-essence-notice

Conversation

@gregoryfoster

Copy link
Copy Markdown
Contributor

Refs #57 (the Watcher notice below is still to post, with approval).

Plan: docs/plans/2026-10-21-57-dispatch-essence-notice.md.

What changes

  • The contract loses resolve_dispatch_essence at all four rule sites: AGENTS.md (the contract list only), docs/DEPLOYMENT.md "Bumping co-core" step 4, spec D5, and spec §5's bump list. The contract is now the content.process / content.derived models and canonical_text semantics.
  • §5 says why, once. The issuer resolves on its own pin, and Processor never re-resolves. So a change is notice, carrying the either-order reasoning and the moved digests. It becomes coordination again only if Processor starts resolving essences itself.
  • Spec amendment 2026-10-21. Take co-core's XML and feed extractors in step with Watcher, and re-run parity with a feed fixture #29's coordination on watcher#366 was more than the rule needed; JSON: take co-core's JsonExtractor (cannobserv#354) and add a jsonpath parity fixture #37's notice was what it needed. The 2026-10-12 and 2026-10-20 entries, and §5's per-bump notes, are unchanged.
  • Unchanged: notice on every processor_version move; EXTRACTOR_BY_ESSENCE.

The guard test (tests/test_pin.py)

test_processor_never_resolves_a_dispatch_essence walks every src/processor/**/*.py AST. It fails on an import of, or a Name / Attribute use of, resolve_dispatch_essence or extension_media_type, and its message points back to §5. It checks code, not text, so a docstring may quote them. test_the_guard_catches_code_not_text holds the walker to that: it catches four code forms and passes a docstring, a comment and extractor_for_essence.

Red, on a scratch copy of src/ + tests/ with from co_core.pure.extract import resolve_dispatch_essence planted in processors/extract.py:

E       AssertionError: Processor resolves a dispatch essence itself: {'src/processor/processors/extract.py': ['line 16: resolve_dispatch_essence']}. A change to essence resolution is then a contract change, coordinated with Watcher, not notice: restore it to the contract (spec §5, D5; AGENTS.md; DEPLOYMENT.md step 4; processor#57).
FAILED tests/test_pin.py::test_processor_never_resolves_a_dispatch_essence - ...
1 failed, 18 deselected in 0.50s

Green here: tests/test_pin.py 19 passed; the full suite 696 passed, 14 skipped (environmental: no .env in the worktree, /etc/processor unreadable as exedev); ruff clean.

Premise checked on co-core 0.38.0: extractor_for_essence and extraction_overrides_for_essence, which Processor does call, don't call either resolver.

Known limit: a string-keyed lookup (getattr(m, "resolve_dispatch_essence")) isn't caught. That would be deliberate evasion, not drift.

No deploy: nothing under src/, deploy/, scripts/deploy.sh, pyproject.toml or uv.lock changes.

Draft: the Watcher notice (CannObserv/watcher#368, after the merge, needs approval)

Notice from Processor: #57 narrows D5's coordination rule. No action is needed from Watcher.

  • A change to essence resolution is now notice, not coordination. resolve_dispatch_essence and extension_media_type leave D5's contract, which is now the content.process / content.derived models and canonical_text semantics. Watcher resolves the essence on its own pin. Processor dispatches whatever essence arrives and never re-resolves it. So either adoption order is safe:
    • an old Watcher keeps sending the essence it sent, which reaches the same extractor as before;
    • a new Watcher's essence reaches the old extractor on an old Processor, and the new one on a new Processor.
  • Every bump still gives notice here, with the new processor_version and the moved digests. A dispatch change for an essence Watcher sends today shows up in those digests.
  • A test keeps the premise true. tests/test_pin.py fails if anything under src/processor/ imports or uses either function. If Processor ever resolves essences itself, the test fails, and the coordination rule comes back with it.
  • This is what JSON: take co-core's JsonExtractor (cannobserv#354) and add a jsonpath parity fixture #37's notice above already did. Take co-core's XML and feed extractors in step with Watcher, and re-run parity with a feed fixture #29's coordination on #366 was more than the rule needed. Spec: D5 and §5, amended 2026-10-21 ().

🤖 Generated with Claude Code

gregoryfoster and others added 3 commits October 21, 2026 18:59
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e to it is notice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant