Skip to content

ADR-0011: Pivot to tdl-raw transformer architecture - #9

Merged
joestump-agent merged 2 commits into
mainfrom
claude/tg-export-mvp-review-ren319
Jul 10, 2026
Merged

ADR-0011: Pivot to tdl-raw transformer architecture#9
joestump-agent merged 2 commits into
mainfrom
claude/tg-export-mvp-review-ren319

Conversation

@joestump-agent

Copy link
Copy Markdown
Owner

Summary

This PR implements ADR-0011, pivoting tg-export from a live Telethon MTProto client to a stateless transformer that consumes tdl --raw exports. The tool no longer performs authentication, session management, or network I/O — it is now a pure offline JSON-to-JSON converter that reshapes tdl's gotd-flavoured output into the msgbrowse contract.

Key Changes

Removed (live client surface)

  • src/tg_export/export.py — the dialog walk, message iteration, and Telethon-coupled export orchestration
  • src/tg_export/auth.py — credential resolution, login, and session management
  • src/tg_export/media.py — media download and flood-wait handling
  • src/tg_export/reliability.py — flood-wait survival helpers
  • All M2–M6 test suites (test_auth.py, test_media.py, test_reliability.py, test_incremental.py, test_cli_export.py, test_export.py, test_fake_client.py, test_golden.py)
  • Golden fixture files (manifest, NDJSON, media payloads)

Added (transform pipeline)

  • src/tg_export/adapter.py — tdl-raw JSON → Telethon-shaped object reshaper; the single seam coupling tg-export to tdl's output
  • src/tg_export/transform.py — the new workhorse: loads tdl export, adapts each message, maps through the unchanged mapping module, validates, and writes NDJSON + manifest
  • src/tg_export/archive.py — salvaged from retired export.py; protocol-agnostic manifest assembly and per-chat index building
  • tests/test_transform.py — transform pipeline tests over in-memory tdl-raw documents (VERIFICATION GATE pending real tdl dump)

Modified (contract & CLI)

  • src/tg_export/cli.py — single transform command (no login, doctor, export, chats); reads tdl dump path, writes archive
  • src/tg_export/errors.py — removed auth/network-specific codes; added MalformedInputError for malformed tdl dumps
  • src/tg_export/__init__.py — updated docstring to reflect transformer role
  • README.md — repositioned as tdl consumer, not live exporter
  • CHANGELOG.md — v0.2.0 entry documenting the pivot
  • pyproject.toml — updated description
  • tests/conftest.py — removed FakeTelegramClient fixture; logging reset only
  • tests/synthetic.py — updated docstring; fixtures now feed the adapter/mapper directly
  • tests/test_schema.py — removed golden-file validation (golden fixtures deleted)
  • tests/test_packaging.py — version bumped to 0.2.0
  • ADRs: ADR-0002, ADR-0006, ADR-0009 marked superseded by ADR-0011; ADR-0001 amended with supersession note
  • Design docs updated with ADR-0011 supersession notices

Implementation Details

  • Adapter verification gates (ADR-0011): The adapter is a skeleton pending confirmation against a real tdl chat export --raw dump. Three gates are documented:

    1. Completeness: confirm tdl emits full MTProto Message/MessageService with reply_to, fwd_from, reactions, action, entities, media
    2. Entity maps: wire from_id peer resolution through the users[]/chats[] index
    3. Media metadata: confirm media objects carry size, mime_type, and file metadata
  • Byte-stability (ADR-0004): Inherited from jsonio module; no clock beyond manifest generated_at seam

  • Incrementality moved upstream: tdl's time-window

https://claude.ai/code/session_0157yR7hQK8qugYMhUK8j918

claude added 2 commits July 10, 2026 05:38
tg-export's v0.1.0 live Telethon exporter was built under a misread of the
paired msgbrowse decision (ADR-0022), which delegates Telegram to `tdl` — a Go
binary that logs in by importing an installed Telegram Desktop session (no
phone/code/2FA) and dumps messages including the raw MTProto struct via --raw.
The two tools are complementary tiers, not rivals: tdl is the one-click
session+dump tier; tg-export is the fidelity tier that transforms tdl's --raw
output into the curated schema_version:1 contract.

The fidelity core (mapping.py) was already a pure, offline transform over
Telethon-shaped objects — it never needed a live client. So this deletes the
live half and reuses the jewel.

Source:
- Delete auth.py, export.py (live walk), reliability.py, media.py (Telethon
  download); drop the telethon + platformdirs deps (only jsonschema remains).
- Add archive.py (contract writer/manifest, salvaged from export.py),
  adapter.py (the single tdl-raw -> Telethon-shape seam), transform.py
  (adapter -> mapping -> schema -> archive pipeline).
- cli.py collapses to one non-interactive command:
  `transform --input <tdl-export> --output <dir>`.
- errors.py: retire the auth/network sentinels; exit codes are OK / bad-arg /
  bad-input / runtime.

adapter.py is a verified skeleton: the pipeline runs end-to-end and every
emitted message + manifest validate against the shipped schema, but the exact
tdl --raw field names (and whether the dump carries the users[]/chats[] entity
map for offline sender-name resolution) are TODO(tdl-shape), pending a real
`tdl chat export --raw` dump. Senders degrade to stable id-only contacts when
unresolved (msgbrowse ADR-0003).

Records reconciled: add ADR-0011; mark ADR-0002/0006/0009 superseded; amend
ADR-0001; banner SPEC-0001 spec.md + design.md (contract/fidelity stay
authoritative, acquisition half retired).

Tests: drop the live-path suites; refactor synthetic.py/conftest.py off the
fake client; add test_transform.py. 51 pass, ruff clean, fully offline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0157yR7hQK8qugYMhUK8j918
…p dead live-path code

Review fixes for the ADR-0011 pivot:

- export_from_doc now requires account.id and validates chat type against the
  shipped manifest schema enum, so a structurally malformed tdl doc exits with
  the dedicated malformed-input code 5 up front instead of dying mid-transform
  (or post-write) as an unclassified runtime error (exit 1).
- Drop the unused 'out' parameter from adapter._resolve_sender.
- Remove code stranded by the pivot: jsonio.read_manifest / write_ndjson (only
  callers were the deleted live modules), errors.MalformedArgumentError and
  errors.exit_code_for (unreferenced), and the ndjson_writer append mode with
  its stale --since/M5 docs.
- Cover the transform CLI (happy path + exit-code mapping) and the two new
  malformed-input rejections in tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WLMXDUhjouS4DqszQ3VcyF
@joestump-agent
joestump-agent merged commit cab947c into main Jul 10, 2026
3 checks passed
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.

2 participants