Files
gstack/test/fixtures/devex-handoff-v-call.json
T
Garry TanandOpenAI Codex 9f81911136 v1.86.0.0 feat: route outside reviews by harness (#2850)
* feat: add a restricted and supervised Claude Code runner

Preserve configured authentication and models while enforcing tool access, strict completion JSON, bounded output and process cleanup. Cover argv, failure handling, session metadata and Windows process containment.

* feat: route outside reviews by harness and migrate wrapper installs

Use Claude Code from Codex and Codex from other supported hosts, with shared invocation rendering, positive gate validation and per-phase provenance. Rename /claude to /claude-code, repair managed shared and copied installations safely, and generate native Kiro skills. Add installed-workflow, failure-injection and live cross-harness regression coverage.

* test: recognize CEO mode labels without terminal spacing

The paid workflow rendered SCOPEEXPANSION at option 4, but its driver required a literal space. Match the leading mode title without cursor-spacing artifacts and ignore adjacent preview text. Preserve missing-target failures and downstream posture assertions.

* test: isolate plan-count fixtures before starting review workflows

Seed the complete test plan in a private git repository before launching Claude, so a bare slash command cannot review the live workspace while a delayed fixture message remains queued. Preserve count thresholds, parsers and budgets. Add initial-context and installed-discovery tests, and retain startup/terminal diagnostics on failed evaluations.

* test: stabilize review fixtures and Claude eval startup

Preserve source boundaries in workflow judge inputs, isolate CEO mode plans, and wait for interactive trust input readiness. Keep startup failure evidence and retain existing models, budgets, and assertions.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test: classify collapsed review modes and isolate seeded findings

Keep review questions out of the setup count when terminal cursor positioning removes spaces. State existing webhook safeguards so the five-finding control measures its seeded defects without accidental extra security and concurrency gaps. Preserve question bands and the paired control.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test: isolate browser daemon state across free shards

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test: stabilize native review counting and interactive navigation

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore: prepare v1.82.0.0 release

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix: eliminate browser and process-cleanup test flakes

Pin every CI surface to Bun 1.4.0 to avoid extra-stdio finalizers closing
reused live sockets. Add an isolated GC/listener regression that fails on
Bun 1.3.13, and prevent coordinated rollback to an affected CI runtime.

Check renderer cleanup against the render's own staging directory so
concurrent renders cannot invalidate the assertion. Make the no-pgrep
process-tree walk tolerate disappearing /proc entries, and synchronize
its test fixture through child readiness and pipe EOF instead of sleeps.

Validation: 9,157 passed, 31 skipped, zero failures across 556 files with
retries disabled. Build, all-host generation freshness, and skill checks
passed. All three races have failing-before/passing-after regressions.

* fix: count completed native review questions in evals

* fix: drive review navigation from confirmed native choices

* fix: require complete section-loading eval reports

* test: isolate telemetry HTTP transport from local assertions

* fix: keep review input on the active native question

* test: let tunnel revocation daemon choose an available port

* test: allocate available ports for pairing and watchdog fixtures

* fix: stabilize planning eval navigation and phase reporting

* test: isolate installed runtime paths in planning evals

* test: stabilize review evidence and concurrent refresh fixtures

* fix: resolve design findings before editing the plan

* fix: honor and persist disabled outside plan reviews

* fix: preserve planning decisions and terminal evidence

Load installed host reviews at autoplan phase entry and wait for completed
reviewers and saved artifacts. Reuse approved remedies while preserving
individual finding decisions.

Drive interactive evals from the current terminal viewport, bind native
questions across scrolling, and require complete native report evidence.
Cover captured stale menus, permission lifecycles, setup classification,
and disabled-review tool availability with deterministic regressions.

Advance release metadata and the upgrade migration to the unclaimed
1.83.0.0 slot.

* fix: drive native review questions and preserve current plans

Use the native single-choice keyboard protocol and current terminal viewport,
with per-question navigation inside packets and completed-call coverage.
Keep permissions, multi-select menus, and Submit controls distinct.

Send Autoplan reviewers the amended implementation plan, keep its review record
separate, and supply retained application contracts in the chain fixture.
Clarify individual DevEx decisions and complete CEO fix options; use one active
plan destination for the section-loading report.

* fix: preserve complete plan-review decisions

* fix: recognize native plan dialogs and reviewer controls

* fix: preserve review decisions and phase completion

* fix: recognize completed reviews without losing findings

* fix: preserve review continuity and native eval completion

* test: fix native review completion and eval retry isolation

* test: handle native review menus and complete eval fixtures

* test: fix native review setup, completion, and isolation failures

* test: limit native skill discovery to runtime assets

* fix: bind Autoplan reviews to full ordered phase inputs

* test: fix planning eval routing, counting, and timeout handling

* chore: advance queued release to v1.84.0.0

* fix: preserve complete review inputs and planning decisions

* fix: reconcile review approvals and preserve phase obligations

* fix: preserve review obligations and unblock eval permissions

Carry recorded Autoplan requirements into blind phase inputs, require Eng
review approvals before exit, and exercise combined asynchronous flows in
CEO reviews. Correct native finding and handoff classification and unblock
repeated report edits using scoped request identities.

* fix: retain plan requirements and complete native review dialogs

* fix: complete native review prompts and retain plan references

* fix: preserve review inputs and classify native eval evidence

* fix: check competing completion orders in CEO reviews

* fix: recognize review decisions and require phase methodology

Require the current phase methodology before Autoplan snapshots. Correct
substantive decision, closed handoff, and cache-finding classification, and
honor the recommended implementation approach in native review dialogs.

Add captured-transcript regressions without changing review thresholds,
provider models, retries, or deadlines.

* test: bind native review decisions and close completed handoffs

* fix: complete review dialogs and verify methodology delivery

* fix: preserve review evidence and unblock native eval prompts

* fix: handle native review question completions

* fix: recognize native review narration and controls

* fix: count native review decisions and isolate eval fixtures

* test: verify seeded review coverage and current artifact permissions

* test: isolate model and brain-aware skill renders

* fix: repair native workflow evaluation and clarify review steps

* fix: stabilize workflow eval evidence and review guidance

* test: repair native workflow observation and fixture isolation

* fix: recognize completed workflow evidence and owned skill reads

* test: repair seeded workflow delivery and completion evidence

* test: recognize current review evidence across native forms

* test: handle native review variants and permission redraws

* fix: honor review preferences and recognize native eval evidence

* test: recognize completed review decisions and queued permissions

* test: match current review contracts and partial-line edits

* test: recognize completed workflow evidence and bounded human waits

* fix: preserve review entry gates and native eval interactions

* fix: recognize native workflow evidence and preserve review gates

* test: recognize current review evidence and preconfigure workflow fixtures

* test: recognize completed review findings and scoped artifact permissions

* fix: stabilize native workflow review and permission evidence

* fix: recognize current review evidence and scoped edit confirmations

Clarify Design and engineering review entry instructions and Design scoring.
Recognize required legacy coverage and public Autoplan completion recaps.
Bind the pending Edit confirmation to its exact file, ordered digest, and
one-request approval when a preceding command display remains visible.
Keep reviews within their existing size limits and preserve scope gates
when extracting workflow fixtures from either supported preamble header.

Keep failure outcomes, review thresholds, provider choices, and eval budgets.

* fix: recover review workflow progress and eval evidence

* fix: recognize valid review evidence and scope selection

* test: fix review evidence parsing and repeated artifact prompts

* test: recognize valid review decisions and pending native cards

* fix(plan-eng-review): keep final navigation consistent with approved tasks

* test: recognize valid review evidence and bind legacy diff requests

* fix: stabilize review eval evidence and harness repair guidance

* docs: update project documentation for v1.85.0.0

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test: fix Windows CI fixtures and credential scan

Rebase captured JSON values and filesystem evidence using the appropriate
path convention. Compile native fake CLIs on Windows and synchronize pipe
holder readiness, with cleanup retained when assertions fail.

Assemble synthetic credential fixtures at runtime so the added-line scan
keeps enforcing the same gate without flagging its own rejection controls.

Discover generated skills directly for the empty-find regression check,
avoiding a recursive scan through saved evaluation artifacts and dependencies.

* fix: preserve source renders on Windows

Compare canonical generator paths using native separators so an output
sidecar pointing at the source cannot overwrite its skill or metadata.
Keep the regression fixture isolated from the real checkout and expose
freshness diagnostics before asserting subprocess status.

Detach Windows drain-test pipe holders from the fake provider's automatic
child cleanup while preserving the enclosing runner job and its assertions.

* fix: clarify outside review fallback and CEO decisions

Render one applicable own-harness fallback path and retain native review,
disabled policy, and missing-coverage semantics. Align report field names
and mode labels, and make the existing per-cut scope approval explicit.

Regenerate skill outputs and keep the workflow judge's model, thresholds,
and retry policy unchanged.

* chore: move release to free version slot (v1.86.0.0)

PR #2852 now claims v1.85.0.0. Align the release metadata and
rename migration so upgrades from that version still receive it.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix: include engineering review prerequisites and restore branch context

* fix: recognize coverage diagrams and clarify design review instructions

* fix: preserve file identities and join Windows test processes

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
2026-09-14 14:32:45 -07:00

264 lines
59 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"provenance": {
"case": "plan-devex-review-1788943403633-FSfAvi",
"job": "job-5",
"counts": {
"step0Count": 1,
"reviewCount": 6,
"administrativeCount": 0
},
"snapshotAt": "2026-09-09T09:01:31.848146+00:00",
"capture": {
"skill": "plan-devex-review",
"runId": "ship-source-v-full-paid-20260909-0842-5",
"cwd": "/tmp/gstack-paid-shard-lKjqbT/tmp/gstack-plan-count-3smIbM",
"claudeConfigDir": "/tmp/gstack-paid-shard-lKjqbT/tmp/gstack-hermetic-1359653-H2oSMa/with-skills/.claude",
"at": "2026-09-09T09:01:29.761Z"
},
"expected": "/tmp/gstack-paid-shard-lKjqbT/tmp/gstack-e2e-plan-devex-sooUkU/gstack-test-plan-devex.md",
"reportMtimeNs": 1788944050786486636,
"reportMtimeMs": 1788944050786.4866,
"reportSha256": "87f90cb0de522af7d93ab6a02766cbc14eaf2ea88026d7e582121810bc0a0552",
"reportBytes": 18106,
"nativeLastAt": "2026-09-09T08:55:16.460Z",
"latestAnswer": "2026-09-09T08:54:52.410Z"
},
"calls": [
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01JnxC1rSGBPjA11DC1brqEi",
"questions": [
{
"question": "D1 — Empathy narrative: does this match the EvalKit getting-started reality?\n\nHere's what I traced from README.md and the docs. The persona: Python ML engineer who just heard about EvalKit and wants to verify it works locally before integrating it into their team's CI pipeline.\n\n> T+0:00 — I open the README. \"Install with python -m pip install evalkit==2.0.0b1, set EVALKIT_API_KEY, then follow the quickstart's command: python examples/first_eval.py.\" Three steps. Looks easy.\n>\n> T+1:00 — pip install succeeds. I set the key. I run the README's quickstart command: python examples/first_eval.py. I get an error. The file doesn't exist — it's not in the installed package and there's no examples/ directory anywhere.\n>\n> T+2:00 — I dig into the README more carefully and find python -m evalkit.demo mentioned as an alternative. I try that.\n>\n> T+2:30 — The demo starts. It prints: \"Waiting for CI check: 0s elapsed of 300s\". 300 seconds. Five minutes. I'm on my laptop doing a local trial. No one told me a remote CI check was part of the deal.\n>\n> T+7:30 — The CI check finishes. I see the demo scores. The output looks good. But I've just spent seven and a half minutes on a \"quick start\" that started with a missing-file error and a five-minute surprise wait.\n\nDoes this match reality? Where am I wrong? <gstack-qid:devex-review-empathy-narrative>",
"header": "Empathy narrative",
"multiSelect": false,
"options": [
{
"label": "Accurate — proceed",
"description": "The narrative is correct. Proceed with this understanding for the full DX review. (recommended)"
},
{
"label": "Partly wrong — let me correct it",
"description": "Some details are off; I'll clarify before we continue."
},
{
"label": "Wrong path — the actual flow is different",
"description": "The real getting-started path differs significantly from what was traced."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D1 — Empathy narrative: does this match the EvalKit getting-started reality?\n\nHere's what I traced from README.md and the docs. The persona: Python ML engineer who just heard about EvalKit and wants to verify it works locally before integrating it into their team's CI pipeline.\n\n> T+0:00 — I open the README. \"Install with python -m pip install evalkit==2.0.0b1, set EVALKIT_API_KEY, then follow the quickstart's command: python examples/first_eval.py.\" Three steps. Looks easy.\n>\n> T+1:00 — pip install succeeds. I set the key. I run the README's quickstart command: python examples/first_eval.py. I get an error. The file doesn't exist — it's not in the installed package and there's no examples/ directory anywhere.\n>\n> T+2:00 — I dig into the README more carefully and find python -m evalkit.demo mentioned as an alternative. I try that.\n>\n> T+2:30 — The demo starts. It prints: \"Waiting for CI check: 0s elapsed of 300s\". 300 seconds. Five minutes. I'm on my laptop doing a local trial. No one told me a remote CI check was part of the deal.\n>\n> T+7:30 — The CI check finishes. I see the demo scores. The output looks good. But I've just spent seven and a half minutes on a \"quick start\" that started with a missing-file error and a five-minute surprise wait.\n\nDoes this match reality? Where am I wrong? <gstack-qid:devex-review-empathy-narrative>": "Accurate — proceed"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-09-09T08:47:18.023Z"
},
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01Gmf9CxoFcxNkVP8E1KTo3z",
"questions": [
{
"question": "D2 — Journey stage INSTALL: the quickstart file in the README doesn't exist in the package\n\nREADME.md says: \"follow the quickstart's command: python examples/first_eval.py\". docs/package-contents.txt confirms that `examples/first_eval.py` is absent from both the published package and the release examples archive. The Python ML engineer hits a file-not-found error as their very first action after install.\n\nThis violates DX First Principle #1 (Zero friction at T0): the README-documented command fails immediately.\n\nStakes if we skip: every developer who follows the README's own quickstart instruction hits an error before they ever see a real evaluation result. This is the definition of a broken first impression.\n\nRecommendation: A — update the README to use `python -m evalkit.demo` as the primary quickstart command, because the demo module is the one that actually works and ships with the package.\n\nCompleteness: A=9/10, B=6/10, C=5/10\n\nPros / cons:\n\nA) Update README to use `python -m evalkit.demo` (recommended)\n ✅ Removes the broken command from the documented happy path; works out of the box\n ✅ Aligns README with the terminal demo delivery vehicle that was already chosen\n ❌ Loses the examples/first_eval.py pattern if some users prefer a file they can edit\n\nB) Add examples/first_eval.py to the published package\n ✅ Preserves the quickstart file as an editable starting point for users\n ❌ Requires building and shipping the file; doesn't fix the TTHW problem independently\n\nC) Keep both paths, note in README that the examples archive is optional\n ✅ Gives users two entry points\n ❌ Two paths creates \"choose your own adventure\" confusion at the worst possible moment\n\nNet: A is a one-line README fix that removes a broken command. B and C require more work and don't deliver a cleaner first experience. <gstack-qid:devex-review-missing-quickstart-file>",
"header": "Missing file",
"multiSelect": false,
"options": [
{
"label": "A — Update README to use python -m evalkit.demo (recommended)",
"description": "Remove the broken examples/first_eval.py command from the README; make python -m evalkit.demo the documented quickstart."
},
{
"label": "B — Add examples/first_eval.py to the package",
"description": "Ship the quickstart file so the README command works."
},
{
"label": "C — Keep both, add a note",
"description": "Document that examples archive is optional and python -m evalkit.demo is the fallback."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D2 — Journey stage INSTALL: the quickstart file in the README doesn't exist in the package\n\nREADME.md says: \"follow the quickstart's command: python examples/first_eval.py\". docs/package-contents.txt confirms that `examples/first_eval.py` is absent from both the published package and the release examples archive. The Python ML engineer hits a file-not-found error as their very first action after install.\n\nThis violates DX First Principle #1 (Zero friction at T0): the README-documented command fails immediately.\n\nStakes if we skip: every developer who follows the README's own quickstart instruction hits an error before they ever see a real evaluation result. This is the definition of a broken first impression.\n\nRecommendation: A — update the README to use `python -m evalkit.demo` as the primary quickstart command, because the demo module is the one that actually works and ships with the package.\n\nCompleteness: A=9/10, B=6/10, C=5/10\n\nPros / cons:\n\nA) Update README to use `python -m evalkit.demo` (recommended)\n ✅ Removes the broken command from the documented happy path; works out of the box\n ✅ Aligns README with the terminal demo delivery vehicle that was already chosen\n ❌ Loses the examples/first_eval.py pattern if some users prefer a file they can edit\n\nB) Add examples/first_eval.py to the published package\n ✅ Preserves the quickstart file as an editable starting point for users\n ❌ Requires building and shipping the file; doesn't fix the TTHW problem independently\n\nC) Keep both paths, note in README that the examples archive is optional\n ✅ Gives users two entry points\n ❌ Two paths creates \"choose your own adventure\" confusion at the worst possible moment\n\nNet: A is a one-line README fix that removes a broken command. B and C require more work and don't deliver a cleaner first experience. <gstack-qid:devex-review-missing-quickstart-file>": "A — Update README to use python -m evalkit.demo (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-09-09T08:47:36.065Z"
},
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01EuBhqX9BL3eUHWuB3zPp8U",
"questions": [
{
"question": "D3 — Journey stage HELLO WORLD: the mandatory 5-minute CI gate makes the <2-minute TTHW target unreachable\n\ndocs/benchmarks.md sets the agreed target at under 2 minutes. docs/current-contracts.md says the beta plan retains a mandatory 5-minute remote CI wait on every developer's first local evaluation, with no skip flag and no offline path. Those two things cannot both be true.\n\nWith the CI gate: pip install (~60s) + set key (~10s) + run demo + 300s wait = ~6 minutes. This is where the benchmark's 6-minute measurement came from.\nWithout the CI gate: pip install + set key + run demo + see scores = roughly 90 seconds. Under 2 minutes. Target achieved.\n\nThis violates DX First Principle #1 (Zero friction at T0) and the Incremental Steps principle: the developer cannot get ANY local result before a 5-minute mandatory remote round-trip. The empathy narrative shows they don't expect this and aren't warned before it starts.\n\nStakes if we skip: the plan ships with a stated TTHW target it is architecturally incapable of hitting. The benchmark study becomes misleading. The Python ML engineer who wanted a local result before CI finds that even the local demo requires CI.\n\nRecommendation: A — add a skip flag (e.g., EVALKIT_SKIP_CI_CHECK=1 or --skip-ci-check) for local/demo runs, because this preserves the production safety gate for real CI while enabling the <2-minute demo path.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Add a local-run skip flag (EVALKIT_SKIP_CI_CHECK or --no-ci-check) (recommended)\n ✅ Unlocks the <2-minute demo path; the production CI gate still runs in real pipelines\n ✅ Aligns with DX principle #4 (Decide for me, let me override): gate ON by default in prod, OFF for local trial\n ❌ Requires documenting the flag clearly so developers know when to use it safely\n\nB) Retain gate, update TTHW target to be 6 minutes and document the CI wait upfront\n ✅ No code change; the existing behavior is fully documented\n ❌ Abandons the agreed under-2-minute target; places EvalKit in the \"Needs Work\" TTHW tier with measurably lower adoption\n\nC) Keep gate, add a progress bar and estimated time to the wait message\n ✅ Developer knows what is happening and how long it will take; reduces abandonment from surprise\n ❌ Does not change the TTHW — the wait is still 5 minutes; TTHW target still unreachable\n\nNet: A is the only option that makes both the target AND the production gate achievable. B and C accept a broken TTHW target. <gstack-qid:devex-review-ci-gate-tthw>",
"header": "CI gate vs TTHW",
"multiSelect": false,
"options": [
{
"label": "A — Add a local skip flag for demo/local runs (recommended)",
"description": "Add EVALKIT_SKIP_CI_CHECK=1 or --no-ci-check so the <2-minute target is reachable while the production gate is preserved."
},
{
"label": "B — Retain gate, update the TTHW target to 6 minutes",
"description": "Accept the 5-minute gate as a hard requirement and document it prominently; drop the under-2-minute target."
},
{
"label": "C — Retain gate, improve the wait UX with better messaging",
"description": "Add a progress bar and explicit estimated time to the CI wait output; TTHW target is still unachievable."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D3 — Journey stage HELLO WORLD: the mandatory 5-minute CI gate makes the <2-minute TTHW target unreachable\n\ndocs/benchmarks.md sets the agreed target at under 2 minutes. docs/current-contracts.md says the beta plan retains a mandatory 5-minute remote CI wait on every developer's first local evaluation, with no skip flag and no offline path. Those two things cannot both be true.\n\nWith the CI gate: pip install (~60s) + set key (~10s) + run demo + 300s wait = ~6 minutes. This is where the benchmark's 6-minute measurement came from.\nWithout the CI gate: pip install + set key + run demo + see scores = roughly 90 seconds. Under 2 minutes. Target achieved.\n\nThis violates DX First Principle #1 (Zero friction at T0) and the Incremental Steps principle: the developer cannot get ANY local result before a 5-minute mandatory remote round-trip. The empathy narrative shows they don't expect this and aren't warned before it starts.\n\nStakes if we skip: the plan ships with a stated TTHW target it is architecturally incapable of hitting. The benchmark study becomes misleading. The Python ML engineer who wanted a local result before CI finds that even the local demo requires CI.\n\nRecommendation: A — add a skip flag (e.g., EVALKIT_SKIP_CI_CHECK=1 or --skip-ci-check) for local/demo runs, because this preserves the production safety gate for real CI while enabling the <2-minute demo path.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Add a local-run skip flag (EVALKIT_SKIP_CI_CHECK or --no-ci-check) (recommended)\n ✅ Unlocks the <2-minute demo path; the production CI gate still runs in real pipelines\n ✅ Aligns with DX principle #4 (Decide for me, let me override): gate ON by default in prod, OFF for local trial\n ❌ Requires documenting the flag clearly so developers know when to use it safely\n\nB) Retain gate, update TTHW target to be 6 minutes and document the CI wait upfront\n ✅ No code change; the existing behavior is fully documented\n ❌ Abandons the agreed under-2-minute target; places EvalKit in the \"Needs Work\" TTHW tier with measurably lower adoption\n\nC) Keep gate, add a progress bar and estimated time to the wait message\n ✅ Developer knows what is happening and how long it will take; reduces abandonment from surprise\n ❌ Does not change the TTHW — the wait is still 5 minutes; TTHW target still unreachable\n\nNet: A is the only option that makes both the target AND the production gate achievable. B and C accept a broken TTHW target. <gstack-qid:devex-review-ci-gate-tthw>": "A — Add a local skip flag for demo/local runs (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-09-09T08:48:00.122Z"
},
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01CHXDuT2cvL6KJ3EiPPoR1o",
"questions": [
{
"question": "D4 — Pass 3 (Error Messages): AuthError(\"request failed\") is a dead end\n\ndocs/api.md documents: \"For an invalid API key, the SDK raises AuthError('request failed'). There is no authentication error code, explanation of the cause, or instruction for replacing the key. The plan retains this message.\"\n\nWhat the Python ML engineer sees when they set the wrong key or forget to export it:\n AuthError: request failed\n\nWhat they need:\n AuthError: Authentication failed — your EVALKIT_API_KEY is invalid or expired.\n Set a valid key: export EVALKIT_API_KEY=<your-key>\n Get your key at: https://evalkit.example.com/dashboard/api-keys\n\nThe Hall of Fame formula: problem + cause + fix + where to learn more. The current message scores 1/4: it names the error class but omits cause, fix, and docs link. A developer hitting this for the first time will search their shell, re-read the README, and wonder if the SDK is broken.\n\nThis violates DX First Principle #5 (Fight uncertainty): every error must identify problem, cause, and fix. Auth errors are the most common first-run failure for any API SDK.\n\nStakes if we skip: developers who mistype their key or use a test key abandon the SDK in minute 3 with no path forward. Support tickets spike on \"why does it say request failed?\"\n\nRecommendation: A — update the error message to include cause + fix + link, because the cost is one string change and the impact is turning a dead end into a resolved issue.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Update AuthError message: cause + fix instruction + API key URL (recommended)\n ✅ Developer knows exactly what went wrong and what to do next; no support ticket needed\n ✅ One-line change to the SDK; consistent with how all other errors already work per current-contracts.md\n ❌ Requires publishing a new SDK version if the message is in compiled code\n\nB) Retain current message, add a troubleshooting section to the docs\n ✅ No SDK code change required\n ❌ Developer must leave the terminal, find the docs, and navigate to troubleshooting — context-switch cost of 10-20 minutes\n\nNet: A costs one string edit. B costs the developer 10 minutes of confusion every time. <gstack-qid:devex-review-auth-error-message>",
"header": "Auth error message",
"multiSelect": false,
"options": [
{
"label": "A — Fix the error message: cause + fix + link (recommended)",
"description": "Update AuthError to include what failed, why, and how to fix it (set a valid key, link to dashboard)."
},
{
"label": "B — Keep message, add troubleshooting docs",
"description": "Document the auth error in a separate troubleshooting page; don't change the SDK error text."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D4 — Pass 3 (Error Messages): AuthError(\"request failed\") is a dead end\n\ndocs/api.md documents: \"For an invalid API key, the SDK raises AuthError('request failed'). There is no authentication error code, explanation of the cause, or instruction for replacing the key. The plan retains this message.\"\n\nWhat the Python ML engineer sees when they set the wrong key or forget to export it:\n AuthError: request failed\n\nWhat they need:\n AuthError: Authentication failed — your EVALKIT_API_KEY is invalid or expired.\n Set a valid key: export EVALKIT_API_KEY=<your-key>\n Get your key at: https://evalkit.example.com/dashboard/api-keys\n\nThe Hall of Fame formula: problem + cause + fix + where to learn more. The current message scores 1/4: it names the error class but omits cause, fix, and docs link. A developer hitting this for the first time will search their shell, re-read the README, and wonder if the SDK is broken.\n\nThis violates DX First Principle #5 (Fight uncertainty): every error must identify problem, cause, and fix. Auth errors are the most common first-run failure for any API SDK.\n\nStakes if we skip: developers who mistype their key or use a test key abandon the SDK in minute 3 with no path forward. Support tickets spike on \"why does it say request failed?\"\n\nRecommendation: A — update the error message to include cause + fix + link, because the cost is one string change and the impact is turning a dead end into a resolved issue.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Update AuthError message: cause + fix instruction + API key URL (recommended)\n ✅ Developer knows exactly what went wrong and what to do next; no support ticket needed\n ✅ One-line change to the SDK; consistent with how all other errors already work per current-contracts.md\n ❌ Requires publishing a new SDK version if the message is in compiled code\n\nB) Retain current message, add a troubleshooting section to the docs\n ✅ No SDK code change required\n ❌ Developer must leave the terminal, find the docs, and navigate to troubleshooting — context-switch cost of 10-20 minutes\n\nNet: A costs one string edit. B costs the developer 10 minutes of confusion every time. <gstack-qid:devex-review-auth-error-message>": "A — Fix the error message: cause + fix + link (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-09-09T08:48:18.156Z"
},
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01M5ZDfykARvFKmYD8inotgx",
"questions": [
{
"question": "D5 — Pass 2 (API Design): run_eval and run_batch take the same arguments in reversed order\n\ndocs/api.md documents:\n run_eval(dataset, evaluator)\n run_batch(evaluator, dataset)\n\nBoth argument names describe the same concepts. The reversed positional order is documented as \"intentional\" and neither function requires keyword arguments.\n\nA Python ML engineer who learns run_eval(dataset, evaluator) and then picks up run_batch will silently pass the arguments in the wrong order. There is no TypeError — both arguments are valid Python objects. The call succeeds, the results are wrong, and the developer spends 30 minutes debugging why their batch evaluations are nonsense.\n\nThis violates DX First Principle #4 (Decide for me) and the Hall of Fame anti-pattern \"God endpoint / inconsistent naming\": identical concepts should follow identical calling conventions. The Stripe API is the gold standard for consistency — you never have to wonder if it's customer, charge or charge, customer.\n\nStakes if we skip: silent bugs in production. Developers who use both functions will be bitten exactly once, file a confusing bug report, and lose trust in the SDK.\n\nRecommendation: A — standardize to (dataset, evaluator) order in both functions, because dataset is the primary noun in evaluation and should always come first.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Standardize to run_eval(dataset, evaluator) / run_batch(dataset, evaluator) (recommended)\n ✅ Consistent calling convention; developers who learn one API use the other correctly by muscle memory\n ✅ Eliminates the silent-wrong-order bug before it hits any user\n ❌ Breaking change to run_batch — requires changelog entry and migration note\n\nB) Require keyword arguments on both functions\n ✅ Positional ambiguity is gone; callers must name their args\n ❌ Adding keyword-only enforcement is also a breaking change; heavier than swapping order\n\nC) Keep current order, add a type annotation or runtime check that warns on likely-wrong-order calls\n ✅ No API change\n ❌ Heuristic check is fragile; if both args are the same type, it can't detect the swap\n\nNet: A is a surgical fix that costs one v2 changelog line. The alternative is leaving a silent bug that will confuse every developer who uses both functions. <gstack-qid:devex-review-api-arg-order>",
"header": "API argument order",
"multiSelect": false,
"options": [
{
"label": "A — Standardize both functions to (dataset, evaluator) (recommended)",
"description": "Align run_batch to match run_eval's argument order; add a migration note to the changelog."
},
{
"label": "B — Require keyword arguments on both functions",
"description": "Make both functions keyword-only so callers must explicitly name dataset= and evaluator=."
},
{
"label": "C — Keep current order, add a runtime order-check hint",
"description": "Leave the order as-is; add a best-effort runtime warning if arguments appear to be swapped."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D5 — Pass 2 (API Design): run_eval and run_batch take the same arguments in reversed order\n\ndocs/api.md documents:\n run_eval(dataset, evaluator)\n run_batch(evaluator, dataset)\n\nBoth argument names describe the same concepts. The reversed positional order is documented as \"intentional\" and neither function requires keyword arguments.\n\nA Python ML engineer who learns run_eval(dataset, evaluator) and then picks up run_batch will silently pass the arguments in the wrong order. There is no TypeError — both arguments are valid Python objects. The call succeeds, the results are wrong, and the developer spends 30 minutes debugging why their batch evaluations are nonsense.\n\nThis violates DX First Principle #4 (Decide for me) and the Hall of Fame anti-pattern \"God endpoint / inconsistent naming\": identical concepts should follow identical calling conventions. The Stripe API is the gold standard for consistency — you never have to wonder if it's customer, charge or charge, customer.\n\nStakes if we skip: silent bugs in production. Developers who use both functions will be bitten exactly once, file a confusing bug report, and lose trust in the SDK.\n\nRecommendation: A — standardize to (dataset, evaluator) order in both functions, because dataset is the primary noun in evaluation and should always come first.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Standardize to run_eval(dataset, evaluator) / run_batch(dataset, evaluator) (recommended)\n ✅ Consistent calling convention; developers who learn one API use the other correctly by muscle memory\n ✅ Eliminates the silent-wrong-order bug before it hits any user\n ❌ Breaking change to run_batch — requires changelog entry and migration note\n\nB) Require keyword arguments on both functions\n ✅ Positional ambiguity is gone; callers must name their args\n ❌ Adding keyword-only enforcement is also a breaking change; heavier than swapping order\n\nC) Keep current order, add a type annotation or runtime check that warns on likely-wrong-order calls\n ✅ No API change\n ❌ Heuristic check is fragile; if both args are the same type, it can't detect the swap\n\nNet: A is a surgical fix that costs one v2 changelog line. The alternative is leaving a silent bug that will confuse every developer who uses both functions. <gstack-qid:devex-review-api-arg-order>": "A — Standardize both functions to (dataset, evaluator) (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-09-09T08:48:38.205Z"
},
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01SSgCUdRxsxooMpvM5yrsvg",
"questions": [
{
"question": "D6 — Pass 5 (Upgrade Path): v1→v2 removes Client.evaluate() with no warning, no guide, no codemod\n\ndocs/api.md documents: \"Version 1 exposes Client.evaluate(). Version 2 replaces it with Client.run() and removes the old name immediately. No compatibility alias, deprecation warning, migration guide, or codemod is provided.\"\n\nThe Python ML engineer who is already using EvalKit v1 in their team's pipeline runs pip install --upgrade evalkit and gets:\n AttributeError: 'Client' object has no attribute 'evaluate'\n\nNo warning before the upgrade. No changelog entry pointing to the rename. No migration guide. Their production pipeline breaks. They have to grep their entire codebase for .evaluate( and manually replace each call with .run( — while a broken CI job waits.\n\nThis violates DX First Principle #7 (Speed is a feature) and DX Characteristic #2 (Credible): developers need to trust that upgrades won't silently break their work. TypeScript's gold standard is \"never breaks JS\" — or if it must break, a codemod does the migration automatically.\n\nStakes if we skip: every v1 user has their pipeline broken on upgrade with no recovery path except reading the source code. This is the kind of experience that causes teams to pin SDK versions forever and never upgrade again.\n\nRecommendation: A — add a compatibility alias with a DeprecationWarning and a migration note in the changelog, because it costs one alias and one warning line and prevents every v1 user from hitting a production crash.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Add Client.evaluate() as a DeprecationWarning alias + changelog migration note (recommended)\n ✅ v1 code continues to work with a clear console warning; upgrade is non-breaking\n ✅ Changelog note + warning together tell the developer exactly what to change and where\n ❌ Old name stays in the codebase until the next major version; minor code debt\n\nB) Add a migration guide to docs with find-replace instructions\n ✅ No SDK code change\n ❌ Developers must find the guide AFTER their pipeline breaks; no warning before or during the failure\n\nC) Keep hard break, add an informative error message when evaluate() is called\n ✅ Developer gets an error that names the replacement method instead of \"has no attribute\"\n ❌ Still a breaking change that crashes the pipeline; just slightly less confusing\n\nNet: A keeps every v1 user unbroken while they migrate. B and C still break production pipelines on upgrade. <gstack-qid:devex-review-v1-v2-migration>",
"header": "v1→v2 upgrade",
"multiSelect": false,
"options": [
{
"label": "A — Compatibility alias + DeprecationWarning + changelog note (recommended)",
"description": "Keep Client.evaluate() working with a deprecation warning that names Client.run() as the replacement."
},
{
"label": "B — Keep hard break, add a migration guide to docs",
"description": "Document the rename in a migration guide; accept that v1 code breaks on upgrade."
},
{
"label": "C — Keep hard break, add an informative AttributeError message",
"description": "Raise a helpful error naming Client.run() when Client.evaluate() is called on v2."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D6 — Pass 5 (Upgrade Path): v1→v2 removes Client.evaluate() with no warning, no guide, no codemod\n\ndocs/api.md documents: \"Version 1 exposes Client.evaluate(). Version 2 replaces it with Client.run() and removes the old name immediately. No compatibility alias, deprecation warning, migration guide, or codemod is provided.\"\n\nThe Python ML engineer who is already using EvalKit v1 in their team's pipeline runs pip install --upgrade evalkit and gets:\n AttributeError: 'Client' object has no attribute 'evaluate'\n\nNo warning before the upgrade. No changelog entry pointing to the rename. No migration guide. Their production pipeline breaks. They have to grep their entire codebase for .evaluate( and manually replace each call with .run( — while a broken CI job waits.\n\nThis violates DX First Principle #7 (Speed is a feature) and DX Characteristic #2 (Credible): developers need to trust that upgrades won't silently break their work. TypeScript's gold standard is \"never breaks JS\" — or if it must break, a codemod does the migration automatically.\n\nStakes if we skip: every v1 user has their pipeline broken on upgrade with no recovery path except reading the source code. This is the kind of experience that causes teams to pin SDK versions forever and never upgrade again.\n\nRecommendation: A — add a compatibility alias with a DeprecationWarning and a migration note in the changelog, because it costs one alias and one warning line and prevents every v1 user from hitting a production crash.\n\nNote: options differ in kind, not coverage — no completeness score.\n\nPros / cons:\n\nA) Add Client.evaluate() as a DeprecationWarning alias + changelog migration note (recommended)\n ✅ v1 code continues to work with a clear console warning; upgrade is non-breaking\n ✅ Changelog note + warning together tell the developer exactly what to change and where\n ❌ Old name stays in the codebase until the next major version; minor code debt\n\nB) Add a migration guide to docs with find-replace instructions\n ✅ No SDK code change\n ❌ Developers must find the guide AFTER their pipeline breaks; no warning before or during the failure\n\nC) Keep hard break, add an informative error message when evaluate() is called\n ✅ Developer gets an error that names the replacement method instead of \"has no attribute\"\n ❌ Still a breaking change that crashes the pipeline; just slightly less confusing\n\nNet: A keeps every v1 user unbroken while they migrate. B and C still break production pipelines on upgrade. <gstack-qid:devex-review-v1-v2-migration>": "A — Compatibility alias + DeprecationWarning + changelog note (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-09-09T08:49:00.269Z"
},
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01YHt7J77ttf2hrQMzWJgNF3",
"questions": [
{
"question": "D7 — Next steps: five P1 DX tasks are ready to implement\n\nThe DX review found and resolved five P1 issues. All decisions were made (D2D6). The implementation tasks (T1T5) are waiting. The plan also needs an Eng Review before shipping.\n\nWhat would you like to do next? <gstack-qid:devex-review-next-steps>",
"header": "Next steps",
"multiSelect": false,
"options": [
{
"label": "Run /plan-eng-review next (recommended)",
"description": "DX fixes touch evalkit/client.py (auth error, arg order, deprecation alias, CI skip flag) and README. Eng review validates the implementation approach for those changes."
},
{
"label": "Start implementing T1T5 now",
"description": "The tasks are well-defined. Jump straight to implementation and run /plan-eng-review after."
},
{
"label": "Run /devex-review after shipping",
"description": "Implement the tasks and then run /devex-review on the live SDK to verify TTHW actually hits the <2-minute target."
},
{
"label": "Done for now — I'll handle next steps manually",
"description": "Save the plan and review report; return to it when ready."
}
]
}
],
"answered": true,
"failed": false,
"answers": {
"D7 — Next steps: five P1 DX tasks are ready to implement\n\nThe DX review found and resolved five P1 issues. All decisions were made (D2D6). The implementation tasks (T1T5) are waiting. The plan also needs an Eng Review before shipping.\n\nWhat would you like to do next? <gstack-qid:devex-review-next-steps>": "Run /plan-eng-review next (recommended)"
},
"unansweredQuestionIndices": [],
"answeredAt": "2026-09-09T08:54:52.410Z"
}
],
"planReadyRequests": [
{
"sessionId": "7b6785b1-1548-4f03-9fab-54328db9502d",
"toolUseId": "toolu_01DToVaamKTeSzUkS17jPPns",
"timestamp": "2026-09-09T08:55:18.781Z",
"failed": false,
"source": "pre_tool_use"
}
],
"reportContent": "# DX Plan Review: EvalKit SDK 2.0.0b1 Beta Release Polish\n\n## Context\n\nEvalKit is a Python SDK for ML engineers evaluating LLM responses. This review was\nrequested to apply DX POLISH to the beta release — improving every developer-facing\ntouchpoint within the existing release scope. The plan identified five specific contracts\nto review: the first-run CI requirement, public function signatures, authentication error,\npackaged quickstart, and v1-to-v2 client upgrade. Four of the five had material DX gaps;\nall were resolved through interactive review.\n\n---\n\n## Pre-Settled Decisions (from README.md + docs/benchmarks.md)\n\nThese were confirmed before the review began and are not re-litigated here.\n\n- **Persona:** Python ML engineer. Uses terminal. Wants a local result before connecting to CI.\n- **Mode:** DX POLISH — improve existing touchpoints within beta release scope; no expansion.\n- **TTHW target:** under 2 minutes (established benchmark study target).\n- **Competitive benchmark:** peers at 24 min; EvalKit currently at 6 min. Target: Champion tier.\n- **Magical moment delivery:** copy-paste terminal command — `python -m evalkit.demo`.\n\n---\n\n## TARGET DEVELOPER PERSONA\n\n```\nWho: Python ML engineer evaluating LLM responses\nContext: Wants to verify the SDK locally before integrating into their team's CI pipeline\nTolerance: 510 minutes max before abandoning; expects pip-native tooling, no surprises\nExpects: pip install, export key, run command, see scores — no Docker, no remote calls\n```\n\n---\n\n## Developer Empathy Narrative\n\n*First-person trace of the actual documented getting-started path — confirmed accurate by user.*\n\n> T+0:00 — I open README.md. First heading: \"EvalKit SDK.\" Description: Python SDK for ML\n> engineers. This looks like me. I find \"Getting started\": three steps — install, set key,\n> run quickstart. Looks fast.\n>\n> T+1:00 — `pip install evalkit==2.0.0b1` succeeds. I set EVALKIT_API_KEY in my shell. I run\n> the README's quickstart: `python examples/first_eval.py`. I get an error: the file doesn't\n> exist. It's not in the installed package. No examples/ directory anywhere.\n>\n> T+2:00 — I re-read the README more carefully and find `python -m evalkit.demo` mentioned as\n> the demo. I try that instead.\n>\n> T+2:30 — The demo starts. It prints: \"Waiting for CI check: 0s elapsed of 300s\". 300 seconds.\n> Five minutes. I'm on my laptop trying a local trial. I wasn't warned a remote CI check was\n> part of the deal.\n>\n> T+7:30 — The CI check passes. I see demo scores. The output format is exactly right. But seven\n> and a half minutes, one file-not-found error, and a surprise five-minute wall to get here.\n\n---\n\n## Competitive DX Benchmark\n\n```\nCOMPETITIVE DX BENCHMARK\n=========================\nTool | TTHW | Notable DX Choice | Source\nPeer SDK A | 2 min | Clean local first run | docs/benchmarks.md\nPeer SDK B | 4 min | — | docs/benchmarks.md\nPeer SDK C | 3 min | — | docs/benchmarks.md\nEvalKit | 6 min | 5-min mandatory CI gate | docs/benchmarks.md (measured)\nEvalKit* | ~90 sec | With EVALKIT_SKIP_CI_CHECK | post-review target\n```\n\nTarget tier: **Champion (< 2 minutes)** — achievable with the skip flag added in D3.\n\n---\n\n## Magical Moment Specification\n\n**Chosen delivery vehicle:** Copy-paste terminal command — `python -m evalkit.demo`\n\nThe demo evaluates bundled sample responses and prints real per-example scores plus an\naggregate score. No hosted playground needed. No install beyond the package itself.\nExpected output:\n\n```\nexample 1: score=0.80\nexample 2: score=1.00\noverall: score=0.90\n```\n\n**Requirement from this review:** The demo must be reachable in under 2 minutes. This\nrequires the EVALKIT_SKIP_CI_CHECK flag (D3) to exist and be documented in the README.\n\n---\n\n## Developer Journey Map (post-review)\n\n```\nSTAGE | DEVELOPER DOES | FRICTION POINTS | STATUS\n----------------|----------------------------------------|----------------------------|--------\n1. Discover | Opens README; reads description | None | OK\n2. Install | pip install evalkit==2.0.0b1 | None (one command) | OK\n3. Hello World | export EVALKIT_API_KEY + run demo | Quickstart file missing; | FIXED (D2, D3)\n | | CI gate blocks TTHW target |\n4. Real Usage | run_eval / run_batch in own pipeline | Reversed arg order silent | FIXED (D5)\n | | bug between the two funcs |\n5. Debug | Invalid API key path | AuthError(\"request failed\")| FIXED (D4)\n | | gives no cause or fix |\n6. Upgrade | pip install --upgrade evalkit | v1 Client.evaluate() crash | FIXED (D6)\n | | with no warning or guide |\n```\n\n---\n\n## First-Time Developer Confusion Report\n\n```\nFIRST-TIME DEVELOPER REPORT\n============================\nPersona: Python ML engineer; pip-native; no Docker; wants local result first\nAttempting: EvalKit getting started\n\nCONFUSION LOG:\nT+1:00 Runs README quickstart: python examples/first_eval.py → FileNotFoundError.\n Nothing in the README explains this. Digs back through README for an alternative.\nT+2:30 Finds python -m evalkit.demo. Runs it. Sees \"Waiting for CI check: 300s.\"\n Was not expecting remote round-trip for a local demo. Considers Ctrl-C.\nT+7:30 Succeeds. Output is clear and useful. Trust partially restored.\n\nITEMS ADDRESSED:\n✅ #1 Missing file → README updated to use python -m evalkit.demo (D2)\n✅ #2 CI gate surprise → EVALKIT_SKIP_CI_CHECK flag added; README documents it (D3)\n```\n\n---\n\n## DX Findings & Decisions\n\n### D2 — Missing quickstart file (P1 — blocks T0)\n\n**Finding:** README.md documents `python examples/first_eval.py` as the quickstart. That\nfile is absent from the published package and the release examples archive (confirmed in\n`docs/package-contents.txt`). Every developer who follows the README's own instructions\nhits a FileNotFoundError as their first action after install.\n\n**Decision: A** — Update README to use `python -m evalkit.demo` as the primary quickstart\ncommand. The demo module ships with the package and produces the expected output.\n\n**Plan change:** README.md quickstart section — replace `python examples/first_eval.py`\nwith `python -m evalkit.demo`.\n\n---\n\n### D3 — CI gate makes <2-minute TTHW impossible (P1 — blocks TTHW target)\n\n**Finding:** `docs/current-contracts.md` documents a mandatory 5-minute remote CI check on\nevery developer's first local evaluation. No skip flag. No offline path. The plan retains\nthis gate. `docs/benchmarks.md` sets the agreed TTHW target at under 2 minutes. With the\nCI gate: ~6 minutes. Without it: ~90 seconds. These two requirements cannot coexist without\nan escape hatch.\n\n**Decision: A** — Add a local-run skip flag so developers can reach the demo in under 2\nminutes while the production CI gate remains active for real pipelines.\n\n**Plan change:** Add `EVALKIT_SKIP_CI_CHECK=1` environment variable (and optionally\n`--no-ci-check` CLI flag) to bypass the first-run CI gate. Document in README alongside the\ndemo command. Production usage: gate remains on by default. Local/demo usage: flag explicitly\ndisables it.\n\n---\n\n### D4 — AuthError(\"request failed\") is a dead end (P1 — breaks first-run for wrong-key users)\n\n**Finding:** `docs/api.md`: \"For an invalid API key, the SDK raises `AuthError('request\nfailed')`. There is no authentication error code, explanation of the cause, or instruction\nfor replacing the key.\" Auth errors are the most common first-run failure for any API SDK.\nThe current message scores 1/4 on the Hall of Fame formula (problem only; no cause, no fix,\nno docs link).\n\n**Decision: A** — Update the error message to include cause, fix instruction, and docs link.\n\n**Plan change:** `evalkit/client.py` auth error path — update message to:\n```\nAuthError: Authentication failed — your EVALKIT_API_KEY is invalid or expired.\nSet a valid key: export EVALKIT_API_KEY=<your-key>\nGet your key at: https://evalkit.example.com/dashboard/api-keys\n```\n\n---\n\n### D5 — run_eval / run_batch have reversed argument order (P1 — silent bug)\n\n**Finding:** `docs/api.md` documents `run_eval(dataset, evaluator)` and\n`run_batch(evaluator, dataset)`. Same argument names, reversed positional order, no\nkeyword-argument requirement. A developer who learns one function and then uses the other\npasses arguments in the wrong order. No TypeError — both are valid Python objects. Results\nare silently wrong. 30-minute debugging sessions follow.\n\n**Decision: A** — Standardize both functions to `(dataset, evaluator)`. Dataset is the\nprimary noun; it should always come first.\n\n**Plan change:** `evalkit/client.py` or equivalent — swap `run_batch`'s argument order to\n`run_batch(dataset, evaluator)`. Add changelog entry noting the signature alignment.\n\n---\n\n### D6 — v1→v2 removes Client.evaluate() with no warning or migration path (P1 — breaks v1 users)\n\n**Finding:** `docs/api.md`: \"Version 1 exposes `Client.evaluate()`. Version 2 replaces it\nwith `Client.run()` and removes the old name immediately. No compatibility alias,\ndeprecation warning, migration guide, or codemod is provided.\" Every v1 user running\n`pip install --upgrade evalkit` gets an immediate `AttributeError` with no recovery path\nexcept reading source code.\n\n**Decision: A** — Add `Client.evaluate()` as a `DeprecationWarning` alias pointing to\n`Client.run()`, plus a migration note in the changelog.\n\n**Plan change:**\n- `evalkit/client.py` — add: `def evaluate(self, *args, **kwargs): warnings.warn(\"Client.evaluate() is deprecated; use Client.run() instead\", DeprecationWarning, stacklevel=2); return self.run(*args, **kwargs)`\n- Changelog — add migration note: \"`Client.evaluate()` renamed to `Client.run()`; old name raises DeprecationWarning and will be removed in v3.\"\n\n---\n\n## NOT In Scope\n\nThe following DX improvements were considered and explicitly deferred per the \"DX POLISH,\nexisting release scope\" mandate in the plan.\n\n- **Interactive playground / sandbox** — no new hosted service in this release (current-contracts.md)\n- **Additional language bindings** — Python only; no new bindings proposed (current-contracts.md)\n- **Community program / channels** — no new community program proposed (current-contracts.md)\n- **Codemod for run_batch argument flip** — manual migration is sufficient for beta; codemod appropriate for GA\n\n---\n\n## What Already Exists (reuse baseline)\n\nPer `docs/current-contracts.md`, the following are working and should not be changed:\n\n- Type annotations, offline sample data, mock transport — all exist and work\n- Noninteractive CI mode — exists\n- API reference, support contact, changelog, contributor guide — all exist\n- Telemetry is opt-in\n- All non-AuthError errors already include: cause, relevant argument/file, actionable fix, secret redaction\n- API timeouts, cancellation, rate limits, retries bounded and documented\n- Evaluation IDs prevent duplicate submitted jobs\n- Python 3.10+, macOS, Linux, Windows without Docker — all supported\n- Timing instrumentation and post-beta feedback survey — both exist\n\n---\n\n## DX Scorecard\n\n```\n+====================================================================+\n| DX PLAN REVIEW — SCORECARD |\n+====================================================================+\n| Dimension | Score | Prior | Trend |\n|----------------------|--------|--------|--------|\n| Getting Started | 8/10 | 2/10 | +6 ↑ |\n| API/CLI/SDK | 8/10 | 4/10 | +4 ↑ |\n| Error Messages | 8/10 | 4/10 | +4 ↑ |\n| Documentation | 7/10 | 5/10 | +2 ↑ |\n| Upgrade Path | 8/10 | 1/10 | +7 ↑ |\n| Dev Environment | 8/10 | 8/10 | 0 → |\n| Community | 6/10 | 6/10 | 0 → |\n| DX Measurement | 8/10 | 8/10 | 0 → |\n+--------------------------------------------------------------------+\n| TTHW | ~90sec | 6min | -4.5m ↑|\n| Competitive Rank | Champion (< 2 min, post-fix) |\n| Magical Moment | designed via copy-paste terminal command |\n| Product Type | Library/SDK |\n| Mode | DX POLISH |\n| Overall DX | 8/10 | 3/10 | +5 ↑ |\n+====================================================================+\n| DX PRINCIPLE COVERAGE |\n| Zero Friction | covered (D2 + D3 fixes) |\n| Learn by Doing | covered (demo ships bundled sample data) |\n| Fight Uncertainty | covered (D4 auth error fix) |\n| Opinionated + Escape Hatches | covered (D3 skip flag) |\n| Code in Context | covered (demo shows real scores) |\n| Magical Moments | covered (python -m evalkit.demo) |\n+====================================================================+\n```\n\n---\n\n## DX Implementation Checklist\n\n```\nDX IMPLEMENTATION CHECKLIST\n============================\n[x] Installation is one command (pip install evalkit==2.0.0b1)\n[ ] README quickstart uses python -m evalkit.demo, not examples/first_eval.py\n[ ] EVALKIT_SKIP_CI_CHECK=1 flag added and documented in README\n[ ] Time to hello world < 2 minutes (with skip flag)\n[ ] First run produces meaningful output (demo scores)\n[ ] Magical moment delivered via python -m evalkit.demo\n[ ] AuthError message includes: cause + fix instruction + API key URL\n[ ] run_eval and run_batch both use (dataset, evaluator) order\n[ ] Client.evaluate() DeprecationWarning alias added in evalkit/client.py\n[ ] Changelog migration note for Client.evaluate() → Client.run()\n[ ] Changelog entry for run_batch argument order change\n[x] Every other error message has: problem + cause + fix (already done per contracts)\n[x] Type annotations included\n[x] Works in CI/CD without special configuration (noninteractive CI mode exists)\n[x] Changelog exists and is maintained\n[x] Community contact exists (support contact in docs)\n[x] Timing instrumentation exists\n```\n\n---\n\n## Implementation Tasks\n\nSynthesized from this review's findings. Each task derives from a specific finding above.\nRun with Claude Code or Codex; checkbox as you ship.\n\n- [ ] **T1 (P1, human: ~30min / CC: ~5min)** — README — Fix quickstart command\n - Surfaced by: D2 — `examples/first_eval.py` absent from published package\n - Files: `README.md`\n - Verify: `python -m evalkit.demo` runs cleanly from a fresh install; no FileNotFoundError\n\n- [ ] **T2 (P1, human: ~1h / CC: ~10min)** — SDK + README — Add EVALKIT_SKIP_CI_CHECK flag\n - Surfaced by: D3 — CI gate makes <2-minute TTHW impossible\n - Files: `evalkit/client.py` (or CI gate implementation), `README.md`\n - Verify: `EVALKIT_SKIP_CI_CHECK=1 python -m evalkit.demo` completes in under 2 minutes\n\n- [ ] **T3 (P1, human: ~30min / CC: ~5min)** — SDK — Fix AuthError message\n - Surfaced by: D4 — `AuthError(\"request failed\")` has no cause or fix\n - Files: `evalkit/client.py`\n - Verify: Trigger auth error with bad key; confirm message includes cause + export instruction + key URL\n\n- [ ] **T4 (P1, human: ~30min / CC: ~5min)** — SDK + Changelog — Align run_batch argument order\n - Surfaced by: D5 — `run_batch(evaluator, dataset)` is reversed vs `run_eval(dataset, evaluator)`\n - Files: `evalkit/client.py`, changelog\n - Verify: `run_batch(my_dataset, my_evaluator)` and `run_eval(my_dataset, my_evaluator)` both work correctly\n\n- [ ] **T5 (P1, human: ~30min / CC: ~5min)** — SDK + Changelog — Add Client.evaluate() deprecation alias\n - Surfaced by: D6 — v1→v2 removes `Client.evaluate()` with no warning or migration guide\n - Files: `evalkit/client.py`, changelog\n - Verify: `client.evaluate(...)` emits `DeprecationWarning` and returns same result as `client.run(...)`\n\n---\n\n## Review Readiness Dashboard\n\n```\n+====================================================================+\n| REVIEW READINESS DASHBOARD |\n+====================================================================+\n| Review | Runs | Last Run | Status | Required |\n|-----------------|------|---------------------|-----------|----------|\n| DX Review | 1 | 2026-09-09 08:49 | ISSUES | YES |\n| Eng Review | 0 | — | — | YES |\n| CEO Review | 0 | — | — | no |\n| Design Review | 0 | — | — | no |\n| Outside Voice | 1 | 2026-09-09 08:49 | DISABLED | no |\n+--------------------------------------------------------------------+\n| VERDICT: NOT CLEARED — Eng Review required before shipping |\n+====================================================================+\n```\n\n---\n\n## GSTACK REVIEW REPORT\n\n| Review | Trigger | Why | Runs | Status | Findings |\n|--------|---------|-----|------|--------|----------|\n| CEO Review | `/plan-ceo-review` | Scope & strategy | 0 | — | — |\n| Outside Review | disabled | Independent 2nd opinion | 1 | DISABLED | codex_reviews=disabled |\n| Eng Review | `/plan-eng-review` | Architecture & tests (required) | 0 | — | — |\n| Design Review | `/plan-design-review` | UI/UX gaps | 0 | — | — |\n| DX Review | `/plan-devex-review` | Developer experience gaps | 1 | ISSUES OPEN | score: 3/10 → 8/10, TTHW: 6min → ~90sec |\n\n**OUTSIDE COVERAGE:** codex-plan-review disabled (codex_reviews=disabled). No outside voice ran. Re-enable: `gstack-config set codex_reviews enabled`.\n\n**VERDICT:** DX Review completed. Eng Review required before shipping.\n\nNO UNRESOLVED DECISIONS\n",
"screen": " +====================================================================+\n\n ---\n\n GSTACK REVIEW REPORT\n\n ┌────────────┬─────────────────────┬────────────────────────┬──────┬───────────┬─────────────────────────────────┐\n │ Review │ Trigger │ Why │ Runs │ Status │ Findings │\n ├────────────┼─────────────────────┼────────────────────────┼──────┼───────────┼─────────────────────────────────┤\n │ CEO Review │ /plan-ceo-review │ Scope & strategy │ 0 │ — │ — │\n ├────────────┼─────────────────────┼────────────────────────┼──────┼───────────┼─────────────────────────────────┤\n │ Outside │ disabled │ Independent 2nd │ 1 │ DISABLED │ codex_reviews=disabled │\n │ Review │ │ opinion │ │ │ │\n ├────────────┼─────────────────────┼────────────────────────┼──────┼───────────┼─────────────────────────────────┤\n │ Eng Review │ /plan-eng-review │ Architecture & tests │ 0 │ — │ — │\n │ │ │ (required) │ │ │ │\n ├────────────┼─────────────────────┼────────────────────────┼──────┼───────────┼─────────────────────────────────┤\n │ Design │ /plan-design-review │ UI/UX gaps │ 0 │ — │ — │\n │ Review │ │ │ │ │ │\n ├────────────┼─────────────────────┼────────────────────────┼──────┼───────────┼─────────────────────────────────┤\n │ DX Review │ /plan-devex-review │ Developer experience │ 1 │ ISSUES │ score: 3/10 → 8/10, TTHW: 6min │\n │ │ │ gaps │ │ OPEN │ → ~90sec │\n └────────────┴─────────────────────┴────────────────────────┴──────┴───────────┴─────────────────────────────────┘\n\n OUTSIDE COVERAGE: codex-plan-review disabled (codex_reviews=disabled). No outside voice ran. Re-enable: gstack-config\n set codex_reviews enabled.\n\n VERDICT: DX Review completed. Eng Review required before shipping.\n\n NO UNRESOLVED DECISIONS\n╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌\n\n────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n Claude has written up a plan and is ready to execute. Would you like to proceed?\n\n 1. Yes, and use auto mode\n 2. Yes, manually approve edits\n 3. Tell Claude what to change\n shift+tab to approve with this feedback\n"
}