Repository navigation
Conversation
The eval now runs evals/snae-build, a Harbor task inspired from lightcone-evals' port of this repository's eval, in one workflow: prepare (the engine wheel built from the checkout into the task image, the agent-skills bundles), an oracle gate, claude-code and codex legs with the skills installed through Harbor's --skill, and a report. The instruction is now the one line a user would type, so how to drive lc and astra has to come from the skills and the CLIs' help. The report gates on reward, breakage and mean agent steps against the median of the leg's last main runs, and always ships a trace analysis that names where the steps went and which change most plausibly caused it. agent-skills reuses the workflow through workflow_call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9FLtiiMxVhhkvZjd9SQp4
|
All 7 failures are in The runner's interpreter is now CPython 3.13.17. That is the No open PR fixes it. The fix is the #248 shape: bump Generated by Claude Code |
✅ Evalstack:
claude-codeConfusion & pain points
What changed vs mainNo baseline trace is available, so no comparison is possible. This PR adds the Harbor eval harness itself ( Evidence (deterministic)Evidence — claude-codeTool calls by phase (mean per trial):
Skills loaded: yes Failed or erroring tool calls (2):
Commands run more than once:
Verifier output: Run: https://github.com/LightconeResearch/lightcone-cli/actions/runs/39736199038 |
The tasks stay in LightconeResearch/lightcone-evals, in Harbor format. prepare fetches the requested set (a comma-separated `tasks` input, a folder meaning every task in it, at `tasks_ref`) and rewrites each task's `ARG LIGHTCONE_COMMIT=` line to the lightcone-cli commit under test — the contract lightcone-bench already uses — so no wheel is built and the same workflow serves agent-skills and lightcone-evals as callers. The report groups by leg and task, so steps, history and the gate are per task, and the analyst is handed the task's own instruction. lightcone-evals is private, so a REPO_READ_TOKEN secret is required. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9FLtiiMxVhhkvZjd9SQp4
|
Since d27a8a5 the eval fetches its tasks from Fix: add a repository secret Making lightcone-evals public would remove the need for the token. Nothing in this PR can supply the token, so I'll re-run once it's in place. Generated by Claude Code |
This fixes the `test_container_smoke.py` failures that every branch now hits. #255 shows them, for example. ## What broke GitHub's runner Python moved to **CPython 3.13.17**. `lc init` writes the running interpreter's exact patch to `.python-version`, and the image installs that interpreter with its pinned uv. uv 0.12.23 has no download for 3.13.17, so every image build stops at: ``` RUN UV_PYTHON_INSTALL_DIR=/opt/python uv python install 3.13.17 error: No download found for request: cpython-3.13.17-linux-x86_64-gnu ``` `main` was last green on Oct 15, before the runner moved. ## The fix `image.UV_IMAGE` moves to `ghcr.io/astral-sh/uv:0.13.5`, pinned by its manifest-list digest. This is the same change as #248. - **Why 0.13.5:** it is the first uv release with a 3.13.17 download. I checked `uv python list 3.13.17 --all-versions` against 0.12.24 and 0.13.4, and neither has one. - **Digest:** fetched from ghcr's manifest endpoint for the tag. The same query for `0.12.23` returns the digest currently in `image.py`. - **0.13.0 breaking changes:** none of them touch what the image uses uv for. The image installs a pinned interpreter and runs `uv sync`. The default-Python change does not apply, because the version is always explicit. ## Consequence The uv pin is part of the image identity document, so containerized outputs read `behind` after this, as with any uv bump. Direct-mode projects do not move. ## Tests - `test_image.py`, `test_container.py` and `test_identity.py` pass (96). - `ruff` and `mypy` are clean. - The container smoke suite can't build images in my sandbox, which has no network access for builds, so this PR's CI is its real run. --- _Generated by [Claude Code](https://claude.ai/code/session_01Y9FLtiiMxVhhkvZjd9SQp4)_ Co-authored-by: Claude <noreply@anthropic.com>
Which agent-skills version should the eval install?This is open for discussion; nothing in the PR changes because of it yet. Today: What "published" means for agent-skills
Today The weakness of following
|
| Skills used by lightcone-cli runs | For | Against | |
|---|---|---|---|
A. main (current) |
Newest agent-skills commit | Matches a fresh install | Skill changes move the lightcone-cli baseline, and the PR gets blamed |
| B. Last release | The commit that set the current plugin version |
Matches what existing users run; skill changes reach the eval only when released | Needs agent-skills to tag releases (e.g. lightcone-v0.0.6 in the release PR), or the workflow to search history for the bump |
| C. The baseline's commit | The agent-skills commit the latest successful lightcone-cli main run used, read from its eval-results |
PR and baseline always run identical skills, so a difference is the lightcone-cli change; small, all in this repo | Skill updates reach lightcone-cli PRs only after the next lightcone-cli main run |
None of these affect an agent-skills PR, which always runs its own head.
Proposal
C for PR runs, with main runs choosing the skills. Under the proposal, main runs use agent-skills main today. Once agent-skills tags each plugin release, they would use the latest release tag (B), so the baseline tracks what users have rather than unreleased edits.
The step history should also start fresh, or be marked, whenever the skills commit changes between main runs. Otherwise a release that legitimately changes step counts either fails PRs or gets absorbed slowly by the median.
The lightcone-cli side is the prepare step plus a few lines in eval_report.py. The tagging would live in agent-skills' release process.
Generated by Claude Code
The report script loses its heuristics: the phase classifier, the failure regex (it flagged every `sandbox:` header line as a failure), repeated-command counts and the per-task grouping. The trace analyst reads the digest and is handed only the exact facts: reward, steps, harness exceptions and the verifier's output. The step gate waits for three main runs and needs both 25% and three steps over the median, so one noisy trial cannot fail a PR. An oracle failure is now reported as one, rather than as every leg skipped. The workflow runs one task, drops lightcone-evals as a caller and the attempts/tolerance/tasks inputs, and fetches history only for the repository under test. The cost column goes: under OAuth it is an API price nobody pays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9FLtiiMxVhhkvZjd9SQp4
prepare copied eval_report.py and the analysis prompt out of the lightcone-cli checkout at stack_ref, while the workflow ran from the ref its caller pinned — so a stack_ref older than the script broke the run, and agent-skills could get a script that did not match its workflow. eval.yml is now one self-contained file. The numbers and the gate are jq over each trial's result.json and ATIF trajectory, as the original eval did. The trace digest is gone: the analyst reads the raw trajectories (this run's and main's) itself, with Read and Grep only, and the prompt is inline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9FLtiiMxVhhkvZjd9SQp4
|
@EiffL for the agent-skill question above I would go with option C which ensures that a PR eval check is doing its job by comparing results with what's on Do you agree ? |
| # agent-skills reuses it, with its own PR as the side under test: | ||
| # | ||
| # jobs: | ||
| # eval: | ||
| # uses: LightconeResearch/lightcone-cli/.github/workflows/eval.yml@main | ||
| # secrets: inherit |
There was a problem hiding this comment.
This is what it allows now that everything has been folded in a single workflow.
Callers choose their harness legs as a JSON list of Harbor agents, each naming the secret it needs and optional extra variables; lightcone-cli runs one claude-code leg by default. require_skills fails a leg that never loaded a skill, for agent-skills' checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9FLtiiMxVhhkvZjd9SQp4
Acknowledgements
This PR is built on lightcone-bench and brings its core into this repository:
@dkn16 (Kangning) designed and built lightcone-bench, and this workflow takes several pieces from it:
ARG LIGHTCONE_COMMIT=contract for pinning the stack under test;main;The Harbor task we run,
lightcone-cli/snae-buildin lightcone-evals, is also his port of this repository's earlier eval.@cailmdaley (Cail) contributed the trajectory metrics (lightcone-bench#1): agent steps, tool calls, tokens, cost and wall time, read from Harbor's ATIF trajectory. The agent-step count this workflow gates on is his metric.
The difference from the bench is packaging: everything lives in one workflow file that runs inside the repository under test, with no cross-repo dispatch, watcher scripts or bot commits.
What
eval.ymlruns the eval on Harbor as one self-contained workflow file. agent-skills reuses the same file throughworkflow_call; see LightconeResearch/agent-skills#56.prepare:
legsinput.lightcone-cli/snae-buildfrom lightcone-evals (attasks_ref).ARG LIGHTCONE_COMMIT=to the lightcone-cli commit under test.The prompt is the one line a user would type, so how to drive
lcandastrahas to come from the skills and--help.oracle requires the task's scripted solution to score 1.0. No LLM is involved.
agents runs each leg of
legs, a JSON list of{name, agent, model, secret, env?}:agentis any Harbor agent (claude-code, codex, opencode, …).secretnames the secret the leg needs, exported under its own name.envadds extra variables.Here the default is one claude-code leg on
claude-sonnet-5-5. Skills are installed through Harbor's--skill, and a leg whose secret is missing is skipped with a notice.report:
result.jsonand ATIF trajectory withjq: reward, exception, agent steps, and whether a skill was loaded.require_skills: true, a leg that never loaded a skill.main, also fails when a leg's agent steps are more than 25% and at least 3 steps over the median of its lastmainruns, once three are on record. The history and the trajectories travel in the newest successfulmainrun'seval-resultsartifact, so each calling repository keeps its own baseline.claude -pper leg, limited toReadandGrep. It reads this run's trajectory,main's trajectory, the verifier output and the PR's commits, then explains what went wrong and where any extra steps came from. The result is posted as a sticky PR comment.Reuse: whichever repository triggered the run is checked out at its commit, and the other at its input ref (
stack_ref/skills_ref). A caller picks its ownlegsandrequire_skills; the header comment has an example. Because everything the workflow runs is in the file, a caller can't get a script that doesn't match its workflow.Plugins and hooks: Harbor 0.22 has no route for them.
--skillcopies SKILL.md bundles, the agents expose no plugin or setup hook, and only a custom agent class could add one. Plugin installs therefore stay with agent-skills'e2e-hooks.yml.Removed:
.github/scripts/trace_digest.py,evals/prompt.mdandevals/tasks/, with no replacement outsideeval.yml.Needs
REPO_READ_TOKEN: a secret withcontents:readon lightcone-evals, needed while that repository is private. Without itpreparefails. Once lightcone-evals is public, thetoken:line and this requirement go away.Verified
First end-to-end run, on an earlier revision with the task vendored (1db117b): oracle 1.0, and claude-code reward 1.00 in 10 steps with skills loaded. The analysis was posted.
Report steps: taken out of the workflow and run on these cases:
mainrun appending history;require_skillson a leg with a skill call and on one without.On lightcone-bench's real ATIF fixture they count 59 agent steps, the same as the bench's Python metric.
Legs: the default, a custom leg with
env, and the three-leg list in agent-skills#56 pass. Malformed lists (missing keys, not JSON, empty) are refused inprepare.Analysis: one real
claude -p --allowedTools Read Greprun read the raw trajectory and produced a step-cited analysis.Checks: actionlint is clean, and
Testsis green on the head.Open
🤖 Generated with Claude Code
https://claude.ai/code/session_01Y9FLtiiMxVhhkvZjd9SQp4