fix(experiments): hypothesis skill semantic validity + JSON output mode (EXPT-4644) - #134
Merged
hsadhvani merged 1 commit intoJul 29, 2026
Conversation
Skill eval results
Only suites whose source actually changed since their last recorded score were re-run. Soft-failing while we stabilise the baseline. |
hsadhvani
force-pushed
the
harsh/expt-4644-hypothesis-semantic-validity
branch
from
July 28, 2026 22:46
71c5603 to
8c6daf4
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 8c6daf4. Configure here.
hsadhvani
force-pushed
the
harsh/expt-4644-hypothesis-semantic-validity
branch
from
July 28, 2026 23:57
8c6daf4 to
747caee
Compare
hsadhvani
marked this pull request as ready for review
July 29, 2026 17:26
hsadhvani
merged commit Jul 29, 2026
849ee1e
into
feat/experiment-hypothesis-builder
2 checks passed
ericoh-ld
added a commit
that referenced
this pull request
Aug 3, 2026
…#141) * fix(experiments): unblock hypothesis-builder validate and eval checks Two independent breakages on this branch turned 4 checks red. Neither came from #139 — it only touched SKILL.md, which is what diff-changed-skills.js uses to decide the suite must re-run, so it surfaced both. validate: SKILL.md declared name: launchdarkly-experiment-hypothesis-assistant while the directory is ...-builder, and validate_skills.py requires the two to match. Landed in 7e486ab (v0.3.0). Everything else in the repo already said -builder (_manifest.js, the evals/<suite> dir, the provider's skill_slug, the eval:hypothesis-builder script), so the frontmatter was the lone outlier. Renamed it, plus the handoffFrom value where the skill names itself — the only other occurrence in the repo, with no consumer matching the literal. This also realigns the eval's forced invocation: the provider invokes /<skill_slug> = /launchdarkly-experiment-hypothesis-builder, which did not match the name the skill declared. Evaluate suite: all 5 tests errored in 0s with "Template render error [Line 190, Column 90] expected variable end" — none reached an API call. The suite registered SKILL.md as promptfoo's prompt, promptfoo renders prompts through nunjucks, and SKILL.md documents its own hole syntax ({{measurement:...}}, {{component:hint}}) in the output-contract examples. Nunjucks reads `measurement` as a variable, hits the `:`, and throws. Landed in 849ee1e (#134), whose CI never ran these checks. Replaced the prompt with a suite-local function prompt that returns SKILL.md wrapped in {% raw %}. A function prompt does not skip nunjucks — renderPrompt assigns the return value to basePrompt and still calls renderString on it — and promptfoo's own autoWrapRawIfPartialNunjucks only fires on unclosed tags, so closed-but-invalid {{measurement:...}} sails through. Wrapping supplies the {% raw %} that helper would have added; renderString then returns the file byte-for-byte, so results.json still shows the exact skill text and SKILL.md on disk keeps its hole syntax byte-identical to the o11y contract. Kept suite-local rather than in evals/shared/, which is a GLOBAL_TRIGGERS entry and would force all 7 suites to re-run. Verified: validate_skills.py passes 46/46; nunjucks reproduces the exact Line 190 Column 90 failure on the bare file and renders the wrapped prompt byte-identically; npm test 70/70; one live suite test passes in 1m2s (was 5 errors in 0s). Aggregate scores and Evaluate gate need no separate fix — both were cascades of the errored suite. * update comments * fix evals to match new skill
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.

Summary
Fixes over-lenient grading where a structurally-valid but nonsense hypothesis ("If apple pie, then elephant, because purple") scored 3/3 "Looks strong" on the Fast path (EXPT-4644; the Agent/Sonnet path already rejected it). Adds a semantic-validity rule: a slot counts only if its content is genuinely that component, and the change / measurement / rationale must be causally connected; If/then/because filled with non-sequiturs routes to
junk.Also adds a structured output mode: when the caller requests JSON only (the experiment builder's headless entry point), the skill emits the machine contract (
schema_version/route/components/hypothesis-with-holes /measurements), matching the o11yexperiment-hypothesisskill. The conversational flow and handoff payload are unchanged. This is the shared, portable structured section so the o11y skill can pull from this one later.Targets
feat/experiment-hypothesis-builder(stacks on the in-progress skill).Note: the skill validator currently fails on a pre-existing
namevs directory mismatch (...-assistantvs...-builder), unrelated to this change.Testing approaches
Feature flags
Note
Low Risk
Prompt-only skill documentation with no runtime or auth changes; main risk is inconsistent LLM grading until validated by existing o11y contract tests.
Overview
Fixes over-lenient grading where grammatically correct If/then/because text could score 3/3 despite nonsense. A new semantic validity rule says Change / Measurement / Rationale slots count only when the content is genuinely that component and causally linked; non-sequiturs are treated as absent and routed to junk instead of “Looks strong.”
Adds structured output mode for headless callers (experiment builder): when JSON-only is requested, the skill must return a single object (
schema_version,route,components,hypothesiswith{{component:hint}}holes,measurements) matching the o11yexperiment-hypothesiscontract. Conversational flow and the existing handoff payload are unchanged.Reviewed by Cursor Bugbot for commit 747caee. Bugbot is set up for automated code reviews on this repo. Configure here.