Skip to content

feat(py): citation corpus, provenance marker, and turn reminders - #308

Draft
jat255 wants to merge 4 commits into
mainfrom
jat255/g9yd-agent-helpers
Draft

feat(py): citation corpus, provenance marker, and turn reminders#308
jat255 wants to merge 4 commits into
mainfrom
jat255/g9yd-agent-helpers

Conversation

@jat255

@jat255 jat255 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

The four agent helpers that no milestone owned, ahead of the Commons class that assembles them. Tracked as kata g9yd under M5, stacked on #306.

build_citation_corpus() collects the text an answer's citations are verified against: each measure's search_pool block, each source's dictionary prose and per-table entries, then the context layer's documents. The order is part of the contract, because matching returns the first entry holding the quote, so prose that is both a dictionary's and a document's keeps the dictionary's label. collect_appended_tags() reads back the tags tool results set, and provenance_aside() renders the marker for the outcomes that show one. The marker names no icon: that URL comes from the served asset bundle which arrives with the Python UI, the same reason citation_aside_html() already omits one.

The reminders travel as their own content type so a UI can leave them out. Python's restored-conversation reminder names Python and run_python where R's names R and run_r, so the shared fixture holds the wording once as a template plus each package's two substitutions rather than two copies of the sentence.

One deliberate difference from R: Python keys its data sources, so every dictionary has a name to be labelled with and R's unnamed "data dictionary" fallback has no counterpart here. R's own test for that label stays.

Nothing constructs any of this yet, which is planned. That wiring is kata pvrd, blocked until the prompt data and the tools land.

Python: 1028 tests pass, ruff and pyrefly clean. R: test-provenance.R, test-citations.R, test-turn-reminder.R and test-context-layer.R pass with no failures and no skips.

R-side changes

No R source changed. The R suite gains fixture runners and loses the hand-written tests those runners replace, so R behaviour is identical before and after.

test-provenance.R drives provenance_aside() from a new section of provenance.json, which pins which outcomes render a marker and that a rendered one carries its tag's label and body. The icon assertions stayed hand-written and moved into their own test, because the URL comes from this package's own html dependency and the Python renderer emits none until its UI ships one.

test-citations.R loses three hand-written corpus tests in favour of a runner over the new citation-corpus.json: six cases covering labels and kinds, entry order, the sources: line only multi-source agents see, and precedence when dictionary prose is also a document. The test for an unnamed source's generic label stays hand-written, since Python has no equivalent. Each case builds real measures through measure() and real sources through data_source(), so the runner enters through the same front door the agent will.

test-turn-reminder.R is new and is new coverage: turn-reminder.R had no tests of its own, only the agent-level assertions in test-commons.R, which are untouched. It pins claude_5_turn_reminder verbatim, the model ids that do and do not earn it, and restored_conversation_turn_reminder against the fixture's template rendered with R's values.

Blast radius is the test suite only.

@jat255 jat255 changed the title jat255/g9yd agent helpers feat(py): citation corpus, provenance marker, and turn reminders Sep 7, 2026
@jat255
jat255 force-pushed the jat255/g9yd-agent-helpers branch from 9fa1391 to cfd20c4 Compare September 7, 2026 17:12
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

Preview deployed to Connect (dogfood.team.pct.posit.it): https://dogfood.team.pct.posit.it/connect/#/apps/d7a36cae-8f27-448b-a478-61b81fbe3942/draft/368622

Deployed from commit f2d3745.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

Preview deployed to Connect (connect.staging.pct.posit.it): https://connect.staging.pct.posit.it/connect/#/apps/ad662e1b-5048-4acc-9ad7-f9478c92274e/draft/2681

Deployed from commit f2d3745.

@jat255 jat255 added r Affects the R implementation py Affects the Python implementation labels Sep 7, 2026
@jat255 jat255 added this to the py-M5: agent, tools, and prompt milestone Sep 7, 2026
@jat255
jat255 force-pushed the jat255/g9yd-agent-helpers branch from cfd20c4 to e10ca95 Compare September 7, 2026 19:42
@jat255
jat255 force-pushed the jat255/g9yd-agent-helpers branch from 2fbacc6 to f6f6665 Compare September 7, 2026 19:59
Base automatically changed from jat255/sevt-handle-store to main September 7, 2026 20:05
The four agent helpers that no milestone owned, ahead of the Commons class
that assembles them (kata g9yd, under M5).

build_citation_corpus() collects the text a citation can be verified
against: each measure's search_pool block, each source's dictionary prose
and per-table entries, then the context layer's documents. Order is the
contract, since matching returns the first entry holding the quote, so prose
that is both a dictionary's and a document's keeps the dictionary's label.
Python keys its sources, so every dictionary has a name to be labelled with
and R's unnamed "data dictionary" fallback has no counterpart here.

collect_appended_tags() reads back the tags tool results set, and
provenance_aside() renders the marker for the outcomes that show one. The
marker names no icon: that URL comes from the served asset bundle, as
citation_aside_html already records.

The reminders travel as their own content type, so a UI can leave them out.
The restored-conversation reminder names Python and run_python where R's
names R and run_r; the shared fixture holds the wording once and each
package renders it with its own two values.

Nothing constructs any of this yet, as planned: that wiring is kata pvrd.
The contract was hand-written in both suites: tags gather only from turns
at or after the index, content without a tag is skipped. A per-language
copy of a shared behavior drifts, so provenance.json gains a
collect_appended_tags section both suites run. The fixture's skip counts
the turns present when the exchange began, since from_index is 0-based in
Python and 1-based in R.

A tag value outside A, B, and C stays deliberately unpinned: Python drops
it at collection, R returns it, and derive_provenance_tag ignores anything
but A and B either way.
Every other public function in _citations.py was exported; the corpus
builder was the one omission. escape_attr gained a docstring when it
stopped being private.
turn-reminders.json had no bullet, and the provenance bullet now names
collect_appended_tags alongside the truth table.
@jat255
jat255 force-pushed the jat255/g9yd-agent-helpers branch from f6f6665 to f2d3745 Compare September 7, 2026 20:05
@jat255 jat255 added the needs-manual-review Agent-created work that needs a human review label Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-manual-review Agent-created work that needs a human review py Affects the Python implementation r Affects the R implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant