Skip to content

fix(review-telemetry): record the run's models and skills version - #193

Open
ultimatile wants to merge 1 commit into
mainfrom
fix/telemetry-model-and-version
Open

fix(review-telemetry): record the run's models and skills version#193
ultimatile wants to merge 1 commit into
mainfrom
fix/telemetry-model-and-version

Conversation

@ultimatile

Copy link
Copy Markdown
Owner

Summary

review-telemetry records which gate surfaced which finding, but nothing about the model that produced it. No field distinguishes two runs whose gates ran under different models, so a per-gate comparison across the log pools them without saying so.

Schema 4 names the model and skills state each run ran under.

Changes

Records carry schema: 4 with three run-level fields — skills_version, fixer_model, fixer_effort — and one per-gate field, gates[].reviewer_model.

Each new field names the state the run ran under rather than the state at record time. Where the recording session cannot vouch that the two agree — the model changed mid-run, the skills tree moved after the gates read it, the record is written from a later session — the field falls to the path the record already has for a value nobody can attest: ask the user, and failing that write null and name the reason in gaps.

gates[].reviewer_model is always written and takes one of three values, first branch that applies: "unobservable" when some iteration ran under a reviewer that exposes its model to nobody; null when some iteration's model is not known; otherwise every iteration's model, deduplicated and joined by +, so a gate split across two models stays out of either model's bucket rather than crediting one. Absence carries no meaning, which keeps a forgotten field from reading as a positive claim about the model.

The schema note now tells a reader to gate any query over the four fields on select(.schema >= 4), alongside the same instruction for the fields earlier bumps added. No aggregation one-liner for them joins the existing ones under Reading the log: the skill defines the record, and the queries are the analyst's.

Impact

Records written before this change stay readable: the four fields are additions, and no existing aggregation one-liner reads any of them.

An analysis session reading reviewer_model finds it on every gate object, so a bare field read needs no presence test.

Verification

git describe --tags --always --dirty, run through the path skills_version names, returned 2026.8.5-1-gc2f48c4 — the <tag>-<count>-g<sha> form the record-shape example carries. $CLAUDE_EFFORT, the variable fixer_effort names, expanded to high.

The record-shape example parses: extracting the fenced block and piping it to jq -e . exited 0. mdformat --number --compact-tables --check exited 0 on skills/review-telemetry/SKILL.md.

Notes

skills_version is produced by a git command against the skill's own directory, so it resolves only where that directory is a checkout of this repository. Under the claude plugin install route the README documents, that directory is not a checkout, the command fails, and the field records null with the reason named in gaps.

The log answered "which gate finds what" but not "under which model",
so a run recorded before a model change and one recorded after were indistinguishable once aggregated.

Schema 4 adds three run-level fields — `skills_version`, `fixer_model`, `fixer_effort` — and one per-gate field, `gates[].reviewer_model`.
Each names the state the run ran under rather than the state at record time.
Where the recording session cannot vouch that the two agree, the existing "ask the user, else `null` plus a `gaps` entry" contract carries it, so no branch guards against the divergence.

`reviewer_model` is always written and takes one of three values, first branch that applies:
`"unobservable"` when some iteration ran under a reviewer that exposes its model to nobody,
`null` when some iteration's model is not known,
and otherwise every iteration's model deduplicated and joined by `+`, so a gate split across models stays out of either model's bucket.
Absence carries no meaning, which keeps a forgotten field from reading as a positive claim about the model.

Queries reading any of the four gate on `select(.schema >= 4)`.
No aggregation one-liner accompanies them: the skill defines the schema, and the queries are the analyst's.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the review-telemetry skill’s JSONL record schema to capture the model/effort context each run and gate executed under, enabling accurate comparisons across telemetry collected under different model or skills states.

Changes:

  • Bump the telemetry record schema from 3 → 4 and add run-level fields: skills_version, fixer_model, fixer_effort.
  • Add per-gate gates[].reviewer_model with normalization rules and update the schema-gating note accordingly.
  • Bump plugin marketplace version to 2026.8.6.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
skills/review-telemetry/SKILL.md Extends telemetry schema and documentation to record run/gate model context and normalization rules.
.claude-plugin/marketplace.json Version bump reflecting the skill behavior/schema update.
Suppressed comments (1)

skills/review-telemetry/SKILL.md:99

  • This says gates[].reviewer_model is “always written”, but that’s only true starting with schema 4. Adding the schema qualifier here prevents confusion when reading older records (where the field is absent).
- `gates[].reviewer_model` is always written, and takes the first branch that applies. **`"unobservable"`** — some iteration ran under a reviewer that exposes its model to nobody, `copilot-pr` being the case that reaches it. **`null`** — otherwise some iteration's model is not known. **A string** — otherwise: every iteration's model, deduplicated and joined by `+` in lexicographic order, so a split gate writes one token and stays out of either model's bucket rather than crediting one, and a gate that ran wholly under `fixer_model` repeats that value. Whatever the branch, `gaps` names every iteration whose model was knowable and went uncaptured.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

```

Schema 1 records lack `topic_opened_by`; gate every query reading that field with `select(.schema >= 2)`. Schema ≤2 records lack `injected_at_gate`; gate every query reading that field with `select(.schema >= 3)`.
Schema 1 records lack `topic_opened_by`; gate every query reading that field with `select(.schema >= 2)`. Schema ≤2 records lack `injected_at_gate`; gate every query reading that field with `select(.schema >= 3)`. Schema ≤3 records lack `skills_version`, `fixer_model`, `fixer_effort`, and `reviewer_model`; gate every query reading any of them with `select(.schema >= 4)`.
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