Skip to content

fix(cli): quick mode runs ad-hoc instead of minting a quick-<timestamp> benchmark per invocation; ambiguity-safe -n name reuse - #476

Open
goyamegh wants to merge 2 commits into
opensearch-project:mainfrom
goyamegh:goyamegh/quickmode-dedup
Open

fix(cli): quick mode runs ad-hoc instead of minting a quick-<timestamp> benchmark per invocation; ambiguity-safe -n name reuse#476
goyamegh wants to merge 2 commits into
opensearch-project:mainfrom
goyamegh:goyamegh/quickmode-dedup

Conversation

@goyamegh

@goyamegh goyamegh commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Description

Re-running the bare agent-health benchmark command (quick mode) created a fresh quick-${Date.now()} Benchmark doc on every invocation, growing the benchmarks list unbounded — runs are per-invocation, benchmarks are not. This was the remaining un-landed piece of the benchmark-dedup work: #437 shipped the content-addressed images + doctor, but the quick-mode CLI change itself was inadvertently dropped from that PR during a branch repair (the 0.6.0 changelog listed it in error — corrected here with an erratum note).

Changes

  1. Quick mode → ad-hoc evaluation run. Bare benchmark (no -n/-f, no server running) now routes through the existing unified evaluation-runs API as an ad-hoc run over all stored test cases. Zero Benchmark docs created; the run appears on Evaluations → Runs with the standard "promote to benchmark" affordance. Legacy server lifecycle preserved (starts its own server, stops it afterwards — teardown remains ownership-gated in createServerCleanup, it only ever stops a process it spawned).
  2. findBenchmark name reuse, ambiguity-safe. Resolution is now: exact id → exact name → unique trimmed/case-insensitive match, so -n "my bench " reuses My Bench instead of minting a duplicate. A new findBenchmarkDetailed distinguishes not found from ambiguous: when 2+ benchmarks collide case-insensitively (Foo + FOO), the -n flows error listing the collisions — the CLI neither guesses nor creates a third near-duplicate under the colliding name.

Behavior changes (intentional): quick mode no longer leaves a quick-* benchmark behind (use run promotion instead); -n with a case/whitespace variant of exactly one existing benchmark now reuses it instead of creating a new one.

Testing

  • Unit: quick-mode action pins the new contract (ad-hoc POST with test-case-ids sources, no createBenchmark call); findBenchmark/findBenchmarkDetailed matrix (exact-over-fuzzy, unique fuzzy reuse, ambiguous → surfaced collisions). Full unit suite: 5,705 passed.
  • Integration (live server): two identical ad-hoc runs leave benchmark entities unchanged — runs carry no benchmarkId, no benchmark references the seeded test case, no new quick-* benchmark appears.
  • Manual e2e: bare benchmark -a demo twice → 0 Benchmark docs, 2 ad-hoc runs (server stamps both with the same image digest, confirming the dedup convergence shipped in feat: content-addressed benchmark images, benchmark doctor, and quick-mode dedup — shared, comparable benchmarks via CLI #437).

An adversarial model review (gpt-5.4) was run on the diff; its findings (ambiguity-created duplicates in the create-if-missing -n path, teardown ownership) were addressed in this revision — ambiguity is now a hard error, and teardown was verified ownership-gated.

Check List

  • New functionality includes testing
  • New functionality has been documented (CHANGELOG + erratum)
  • Commits are signed per the DCO using --signoff

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

PR Code Analyzer ❗

AI-powered 'Code-Diff-Analyzer' found issues on commit c312d82.

PathLineSeverityDescription
package-lock.json3highPackage identity changed from '@goyamegh/agent-health' to '@opensearch-project/agent-health' in both the root 'name' and the packages[''] entry. This is a package registry namespace transfer that must be verified by maintainers — namespace hijacking is a known supply chain attack vector, and the legitimacy of the new scope ownership cannot be confirmed from the diff alone.

The table above displays the top 10 most important findings.

Total: 1 | Critical: 0 | High: 1 | Medium: 0 | Low: 0


Pull Requests Author(s): Please update your Pull Request according to the report above.

Repository Maintainer(s): You can bypass diff analyzer by adding label skip-diff-analyzer after reviewing the changes carefully, then re-run failed actions. To re-enable the analyzer, remove the label, then re-run all actions.


⚠️ Note: The Code-Diff-Analyzer helps protect against potentially harmful code patterns. Please ensure you have thoroughly reviewed the changes beforehand.

Thanks.

…arks; harden findBenchmark name reuse

Phase 1 of benchmark dedup: stop the two CLI paths that grew the benchmarks
list on every invocation of the same command.

- Quick mode (bare 'benchmark' with no server running) previously created a
  fresh 'quick-$(Date.now())' Benchmark doc per run. It now delegates to the
  unified evaluation-runs API as an ad-hoc run over all stored test cases
  (sources: test-case-ids), creating zero Benchmark docs. Server lifecycle
  preserved via forceStopServer (teardown remains ownership-gated in
  createServerCleanup: only a process this invocation spawned is stopped).
- findBenchmark resolves: exact id > exact name > UNIQUE trimmed/
  case-insensitive match, so a case/whitespace variant reuses the existing
  benchmark instead of minting a duplicate. findBenchmarkDetailed
  distinguishes not-found from AMBIGUOUS: when 2+ benchmarks collide
  case-insensitively, the -n flows error listing the collisions — the CLI
  neither guesses nor creates a third near-duplicate (adversarial-review
  finding, addressed).

Tests: unit (quick-mode action pins ad-hoc contract + no createBenchmark;
findBenchmark/Detailed matrix incl. ambiguity), integration (two identical
ad-hoc runs leave benchmark entities unchanged).

Signed-off-by: goyamegh <goyamegh@amazon.com>
…lock.json

origin/main's package-lock.json carries name '@goyamegh/agent-health' — a
fork-side package rename (used for fork npm publishing) that leaked upstream
via the opensearch-project#437 branch repair. package.json correctly says
'@opensearch-project/agent-health'; regenerating the lockfile restores the
authoritative scope. No dependency changes.

Signed-off-by: goyamegh <goyamegh@amazon.com>
@goyamegh
goyamegh force-pushed the goyamegh/quickmode-dedup branch from d25c026 to c312d82 Compare September 3, 2026 19:50
@goyamegh

goyamegh commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

Re: Code-Diff-Analyzer high finding on package-lock.json — the finding is inverted; this change restores the authoritative scope.

origin/main's package-lock.json currently carries "name": "@goyamegh/agent-health" — a fork-side package rename (used only for fork npm publishing) that leaked upstream via the #437 branch repair. package.json on origin/main correctly says @opensearch-project/agent-health, so the lockfile has been inconsistent with the manifest since #437 merged. Regenerating the lockfile restores the organization-controlled @opensearch-project scope; there are no dependency changes (3 insertions / 3 deletions, name fields only — split into its own commit for easy review).

In other words: the analyzer is right that scope changes matter, but the hijack-shaped state is the one currently on main, and this PR fixes it.

@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.01%. Comparing base (9e33e19) to head (c312d82).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #476      +/-   ##
==========================================
- Coverage   69.04%   69.01%   -0.03%     
==========================================
  Files         393      393              
  Lines       32217    32217              
  Branches     9527     9527              
==========================================
- Hits        22243    22234       -9     
- Misses       7796     7812      +16     
+ Partials     2178     2171       -7     
Flag Coverage Δ
e2e 45.90% <ø> (-0.06%) ⬇️
integration 44.95% <ø> (ø)
unit 76.80% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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