feat(telemetry): per-stage form events joinable on a deterministic form_id — 0.8.0 - #59
Merged
Merged
Conversation
…rm_id — 0.8.0 Chair-approved 2026-08-24 (route "measure first"): the log had only form_surface and a bare form_submitted, so per-stage latency was not computable. This adds the lifecycle: - FormSchema.form_id: explicit "form_id" definition key wins (validated token), else a deterministic content hash — render and collect re-parse the same dict, so both land on the same id with nothing threaded through the agent. - form_build (source: dict|template:<name> — the V7 adoption signal), form_rendered (duration_ms, html_bytes), form_submitted(form_id), and form_id on form_surface records. - stage_latency(): per-stage p50/p95 read-back (render cost + first-render→first-submission wait per form_id) with the same skip-don't-raise read contract as surface_mix. - Shared _append write path; log_submission stays zero-arg-compatible for pre-0.8 callers (attune-ai <= 14.1.0). Version 0.8.0 across pyproject + plugin + marketplace manifests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ivation (codex cross-review findings 1-3)
silversurfer562
added a commit
to Smart-AI-Memory/attune-ai
that referenced
this pull request
Aug 24, 2026
…atency joins Chair-approved 2026-08-24 (route "measure first"). attune-forms 0.8.0 (Smart-AI-Memory/attune-forms#59) adds per-stage form events joinable on a deterministic FormSchema.form_id; this is the attune-ai half: - _maybe_keyboard_hint takes the validated form and passes its form_id to log_submission, with a TypeError fallback so the handler keeps working on attune-forms 0.7.x (zero-arg signature, no form_id attribute) — no dependency floor bump needed. - tests/unit/telemetry/test_form_events.py: stage-event tests through the attune.telemetry.form_events alias, skipif-guarded on the installed attune-forms capability (skip on 0.7.x, run on >= 0.8.0; verified green in BOTH modes locally). - test_select_form_surface.py: the three routing-decision tests now filter form_surface events instead of counting raw lines — with 0.8.0 the same log interleaves form_build/form_rendered stage events, and the raw count would break on the upgrade (the emptiness/count-assertion drift class from lessons). - elicit skill Step 0: fix the stale template-store path (src/attune/elicitation/templates/ never existed here — templates live in the attune_forms package) and name the new adoption signal (template:<name> vs dict cast sources); mirrors + help reference re-projected. Full suite: 25189 passed, 259 skipped, 6 xfailed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
silversurfer562
added a commit
to Smart-AI-Memory/attune-ai
that referenced
this pull request
Aug 24, 2026
…atency joins (#2278) Chair-approved 2026-08-24 (route "measure first"). attune-forms 0.8.0 (Smart-AI-Memory/attune-forms#59) adds per-stage form events joinable on a deterministic FormSchema.form_id; this is the attune-ai half: - _maybe_keyboard_hint takes the validated form and passes its form_id to log_submission, with a TypeError fallback so the handler keeps working on attune-forms 0.7.x (zero-arg signature, no form_id attribute) — no dependency floor bump needed. - tests/unit/telemetry/test_form_events.py: stage-event tests through the attune.telemetry.form_events alias, skipif-guarded on the installed attune-forms capability (skip on 0.7.x, run on >= 0.8.0; verified green in BOTH modes locally). - test_select_form_surface.py: the three routing-decision tests now filter form_surface events instead of counting raw lines — with 0.8.0 the same log interleaves form_build/form_rendered stage events, and the raw count would break on the upgrade (the emptiness/count-assertion drift class from lessons). - elicit skill Step 0: fix the stale template-store path (src/attune/elicitation/templates/ never existed here — templates live in the attune_forms package) and name the new adoption signal (template:<name> vs dict cast sources); mirrors + help reference re-projected. Full suite: 25189 passed, 259 skipped, 6 xfailed. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chair-approved 2026-08-24 (route "1 — measure first"). The live log had only two event kinds —
form_surfaceand a payload-lessform_submitted— so per-stage latency was not computable.What's here
FormSchema.form_id— telemetry join key. An explicit top-level"form_id"definition key wins (validated[A-Za-z0-9._-]token); otherwiseform_from_dictderives a deterministic content hash, so the render call and the collect call — which each re-parse the same dict — land on the same id without the agent threading anything.form_build— every successful cast;sourceis"dict"or"template:<name>", which doubles as the V7 template-adoption signal.form_rendered— fromform_to_widget_html; carriesduration_ms+html_bytes.form_submitted— now carriesform_id(MCP collect handler passes it; zero-arg call stays valid for attune-ai ≤ 14.1.0).form_surfacerecords also carryform_id.stage_latency()— p50/p95 read-back: render cost fromduration_ms, user-facing wait as firstform_rendered→ firstform_submittedper id, plus counts and the cast-source mix._appendwrite path (was triplicated), never-raises contract kept.Receipts
pytest tests -q), including 22 new tests: determinism, explicit/invalidform_id, template-source tagging, the full dict→widget→collect round-trip joining on one id,stage_latencypercentiles/malformed-line/stale-submission cases, consent gates, zero-arg compat.form_events.py96%,bridge.py98%,widget.py100%.test_version_sync.pygreen).Companion attune-ai PR (passes
form_idat its collect site, compat-shimmed for 0.7.0) follows.🤖 Generated with Claude Code