Skip to content

Make Govbot a DAG - #73

Draft
sartaj wants to merge 1 commit into
mainfrom
make-govbot-a-dag
Draft

Make Govbot a DAG#73
sartaj wants to merge 1 commit into
mainfrom
make-govbot-a-dag

Conversation

@sartaj

@sartaj sartaj commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Reshapes govbot around a data-driven DAG. A govbot.yml manifest declares datasets, transforms, publishers, and named pipelines; govbot run walks a pipeline by spawning each stage as a subprocess over the stream protocol (newline-JSON, stable id, typed kind).

The built-in tagger is decoupled into an ordinary transform node:

govbot source --select docs | govbot classify | govbot apply

Swapping the classifier is a one-line manifest command change, no code change. This is the first slice of decoupling the "Govbot 2" mega-PR (#35); the fastclass switch itself is deferred indefinitely and becomes a future manifest edit.

What's here

  • Manifest / schema — additive Manifest (uniform Transform { command, reads, writes } — no classify-specific fields), Publisher map, pipelines. Legacy repos:/tags: still parse; unknown keys ignored. DAG JSON schema. 4 new unit tests.
  • govbot classify — the built-in ONNX tagger as a stream transform; scores the docs projection text (TagMatcher::match_text); offline-first (keyword fallback, never downloads mid-run).
  • govbot apply — the classification sink; same .tag.json format.
  • govbot run — data-driven runner: source | classify | apply, then publishers. Bare govbot runs the DAG when govbot.yml exists, wizard/init otherwise.
  • source --select docs — emits {id, text, kind:"docs", sources}.
  • RenameClone/Logs/Build → Pull/Source/Publish (old names kept as aliases); removed the deprecated tag command (split into classify+apply).
  • Scaffoldgovbot init writes a DAG manifest.
  • Migrationsaction.yml and justfile moved to the DAG.

Notes for review

  • Publishers currently emit via the existing build logic (minimal wiring per plan); a per-publisher module split + Bluesky is a follow-up PR.
  • The diff includes a crate-wide cargo fmt normalization pass (CI doesn't gate on fmt and main wasn't fmt-clean). Happy to split it into its own commit if preferred.

Verification

cd actions/govbot && cargo test20 tests pass. Verified end-to-end on the wy mock: govbot run produces .tag.json files + feed.xml, and swapping the classify transform's command requires zero code change.

🤖 Generated with Claude Code

https://claude.ai/code/session_014MAr5v6uw35YENW4HCCxyQ

Reshape govbot around a data-driven DAG: a govbot.yml manifest declares
datasets, transforms, publishers, and named pipelines, and `govbot run`
walks a pipeline by spawning each stage as a subprocess over the stream
protocol (newline-JSON, stable `id`, typed `kind`).

The built-in tagger is decoupled into an ordinary transform node:
`govbot source --select docs | govbot classify | govbot apply`. Swapping
the classifier (e.g. to `fastclass classify -`) is a one-line manifest
`command` change — no code change. classify scores the `docs` projection's
text via new `TagMatcher::match_text` / `match_tags_keywords_text` and is
offline-first (keyword fallback, never downloads mid-pipeline). apply is
the classification sink; both produce the same `.tag.json` format.

Details:
- config.rs: additive `Manifest` (uniform `Transform { command, reads,
  writes }` — no classify-specific fields; `Publisher` map; `pipelines`).
  Legacy `repos:`/`tags:` still parse; unknown keys ignored. 4 unit tests.
- schemas/govbot.schema.json: DAG schema (datasets/transforms/publish/
  pipelines); `required` relaxed for back-compat.
- main.rs: `source --select docs` projection; new `classify`/`apply`/`run`
  commands; subcommand rename Clone/Logs/Build -> Pull/Source/Publish with
  old names kept as aliases; removed the deprecated `tag` command (split
  into classify+apply). Bare `govbot` runs the DAG when govbot.yml exists,
  wizard/init otherwise.
- pipeline.rs: data-driven runner (linear walk of a DAG-capable manifest).
- wizard.rs: `govbot init` scaffolds a DAG manifest (datasets + classify
  transform + default pipeline).
- publish.rs: `get_repos_from_config` reads `datasets:` then `repos:`.
- action.yml/justfile: migrated to the DAG (source|classify|apply, publish).

Publisher stages currently emit via the existing `build` logic (minimal
wiring); a per-publisher module split is a follow-up. Includes a crate
`cargo fmt` normalization pass.

20 tests pass; verified end-to-end on the wy mock (`govbot run` produces
tag files + feed.xml).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MAr5v6uw35YENW4HCCxyQ
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