docs(ccc): podman setup, CCC handoff, and skillsbench inventory - #412
Conversation
|
❌ Automatic Labeling Failed An error occurred while trying to automatically label this pull request. Please check the workflow logs for details and add labels manually. |
9f1b9d8 to
94aba9d
Compare
OsherElhadad
left a comment
There was a problem hiding this comment.
Review — docs(ccc): podman setup, CCC handoff, and skillsbench inventory
Reviewed the full diff (7 files, +2100/-0), read every added file end to end, syntax-checked and dry-ran the scripts locally, and ran the core suite.
Thanks for writing this up — the podman-without-subuid archaeology in CCC_PODMAN_SETUP.md is genuinely valuable, hard-won knowledge, and the "why" annotation on every workaround is exactly right. The troubleshooting table keyed to failure signatures is the best part of the PR. The SKILLSBENCH_INVENTORY.md numbers all check out (categories sum to 87; the 21-task coverage table has 21 rows; 43×3×7 = 903).
I'm requesting changes: the scripts as committed only work from one person's account, and CI is red.
Blocking
1. scripts/ccc/setup_podman.sh is dead code — nothing sources it.
Both runner scripts source the author's personal copy on shared storage instead of the sibling script this PR adds:
run_ccc_experiment.sh:179 source /dccstor/knewedge2/boazc/workarea/python/setup_podman.sh
run_ccc_smoke.sh:90 source /dccstor/knewedge2/boazc/workarea/python/setup_podman.sh
setup_podman.sh's own usage comment (line 6) points at the same external path. So for anyone who isn't boazc, the committed script is never executed, and both runners fail at Phase 1. Please use "$SCRIPT_DIR/setup_podman.sh" (SCRIPT_DIR is already computed at line 114 / 62). Same for the doc: CCC_PODMAN_SETUP.md and HANDOFF_CCC.md tell readers to source /dccstor/knewedge2/boazc/... and never mention that the script now lives in the repo — which is the single most useful thing this PR added.
2. run_ccc_experiment.sh:248 hardcodes the cap-evolve binary to one account.
CE_BIN="/dccstor/knewedge2/boazc/workarea/python/skillberry_ai/cap-evolve/.venv/bin/cap-evolve"
if [[ ! -x "$CE_BIN" ]]; then echo "FATAL: ..."; exit 2; fiHard exit 2 for every other user. Suggest CE_BIN="${CE_BIN:-$(command -v cap-evolve)}" with the current path as a documented fallback, or $PROJECT_ROOT/.venv/bin/cap-evolve.
3. submit_ccc_experiment.sh --dry-run is broken on any machine but the author's. I ran the exact invocation from the script's own header comment (line 19-20):
$ bash scripts/ccc/submit_ccc_experiment.sh --suite-id test --max-iterations 0 --dry-run
mkdir: /dccstor: Read-only file system
rc=1
Two defects in one line: CCC_LOGS defaults to /dccstor/knewedge2/boazc/ccc_logs (line 50), and mkdir -p "$CCC_LOGS" (line 90) runs unconditionally before the --dry-run guard at line 123. Please move the mkdir after the dry-run exit and default CCC_LOGS to something account-neutral ($PROJECT_ROOT/results/.ccc_logs, or require the env var).
4. CI is red — please fix before this lands.
- Docs link check fails on 2 dangling links, both in
HANDOFF_CCC.md:[.env](.env)at line 73 (no such file, and there never will be —.envis gitignored) and the root-relative/u/boazc/.local/share/uv/...link at line 164. - DCO fails — neither commit (
1bf7167,94aba9d) carries aSigned-off-by:trailer.git rebase --signoffon the two commits.
5. results/ is not gitignored, and both runners write into it. run_ccc_experiment.sh:128 and run_ccc_smoke.sh:65 write $PROJECT_ROOT/results/<suite>/<run>/ — including env_snapshot.txt (a redacted .env) and bench.log. A git add -A after a run commits credentials-adjacent artifacts. Please add /results/ to .gitignore in this PR.
HANDOFF_CCC.md — I don't think this belongs in the repo as-is
This reads as a paused-session journal rather than documentation, and it is internally contradictory. The header says "plumbing validated end-to-end … a one-task bench eval run smoke completes with errored=0" and "All CCC-specific workarounds are in place", while §"Where we paused" says "Result: still errors=1", §"For a fresh Claude session" says "The blocker is at the aardvark-dns/systemd layer", and the "Layers resolved" list says aardvark was resolved (item 5). A reader can't tell which is true.
Also:
- It is addressed to an AI session ("For a fresh Claude session picking this up", "You do NOT have SSH access… ask the user to paste commands' output", "Good luck.") rather than to a contributor.
- Ground truth is one specific person's account:
boazc,/dccstor/knewedge2/boazc/…,podman-561567, hostcccxc554, UIDs561567:608693. - §"Error log archive" says
errors_1.txt…errors_5.txtare "Kept in-tree for pattern-matching future failures". They are not in the tree, in this PR or anywhere else. - §39 and §259 reference a "parent
HANDOFF.md" — not in the repo; the only pointer is an absolute path on the author's filesystem.
My suggestion: drop HANDOFF_CCC.md from this PR and fold the still-useful, still-true parts (the layer-by-layer resolution list, the filesystem-layout table with <user> placeholders) into CCC_PODMAN_SETUP.md. CCC_PODMAN_SETUP.md on its own is a good how-to; the handoff mostly duplicates it plus stale state.
Security
a. Credential surface documented in HANDOFF_CCC.md §"Credentials". Lines 75-80 publish the internal endpoint https://ete-litellm.ai-models.vpc-int.res.ibm.com, plus the token's length and prefix (<real; 25 chars, prefix "sk-">). The token isn't leaked, but publishing an internal VPC hostname and a token's shape in a public-facing repo is free reconnaissance for no benefit. Please cut the section to "put your endpoint + token in .env; see .env.example".
b. Bearer token on the process command line, on a shared multi-user cluster. run_ccc_smoke.sh:152 (and the doc's smoke recipe) pass --agent-env "ANTHROPIC_AUTH_TOKEN=$ANTHROPIC_AUTH_TOKEN". On CCC that argv is readable by any other user via ps -ef, and it lands in bench.log if bench ever echoes its own invocation. If benchflow supports an env-file or ambient-env passthrough, prefer it; if not, please note the exposure in the doc.
c. curl | sh, unpinned, twice. setup_podman.sh:268 and :271 pipe https://astral.sh/uv/install.sh straight to sh with no version pin and no checksum — baked into a base image every downstream rollout inherits. Slightly awkward, since CCC_PODMAN_SETUP.md §C.1 diagnoses this exact pattern in the SkillsBench verifiers as a failure mode. The doc even shows the verifier pinning uv/0.9.7; the script installs latest, so image contents drift silently between rebuilds. Please pin the version and prefer UV_INSTALL_DIR + a checksum over piping. Same for the doc's docker-compose install (line 104-106): releases/latest/download with no checksum, then chmod +x.
d. Redaction in the env snapshot is allowlist-shaped. sed 's/\(TOKEN\|KEY\)=.*/\1=<REDACTED>/' (run_ccc_experiment.sh:219, run_ccc_smoke.sh:128) catches *TOKEN= / *KEY= and nothing else — a *_SECRET, *_PASSWORD, or Authorization= line goes to disk in cleartext. Invert it: redact everything after = except an explicit safe list.
e. The patched image shadows the official docker.io/library/ubuntu:24.04 tag — please flag the blast radius. setup_podman.sh:275 does podman rmi -f docker.io/library/ubuntu:24.04 and rebuilds under the same tag, with chown/chgrp/useradd/groupadd/usermod/groupmod/adduser/addgroup/dpkg-statoverride all replaced by wrappers that swallow every error (2>/dev/null || :, not just EINVAL), plus TAR_OPTIONS=--no-same-owner in /etc/environment. Consequences worth documenting loudly, or designing away:
- Any other project on that node building
FROM ubuntu:24.04silently gets a mutated base with error-swallowing coreutils and no way to notice. - Genuine permission bugs inside task images now pass silently, which can turn a real failure into a wrong-but-green verifier result. That matters for benchmark integrity, not just convenience.
- There is no documented un-patch path; the user's pristine cached upstream image is destroyed by the
rmi -f.
A distinct tag (localhost/ccc-ubuntu:24.04) plus a documented FROM override would keep the blast radius inside this project. If tag-shadowing is genuinely the only workable route, please say so explicitly and add a "how to revert" section.
Accuracy / completeness
f. CCC_PODMAN_SETUP.md §C prescribes an env var that nothing in this repo reads. "the adapter should read SKILLSBENCH_SANDBOX_USER from .env and pass it through" — grep -rn SKILLSBENCH_SANDBOX_USER . finds zero hits outside these new docs, and examples/skillsbench/adapters/adapter.py never passes --sandbox-user (it only sets SANDBOX = "docker" at line 54). So the run_ccc_experiment.sh → cap-evolve → adapter path hits exactly the failure the doc's own troubleshooting table warns about (chown: changing ownership of '/home/agent/.claude': Invalid argument). run_ccc_smoke.sh passes --sandbox-user '' to bench directly and is fine — so the smoke passes and the real run fails, which is the worst arrangement. Either land the adapter change alongside, or mark §C as "requires an adapter change not yet in main" and say so in run_ccc_experiment.sh.
g. CCC_PODMAN_SETUP.md §"Batch (LSF) mode — TODO" is stale. It ends with "Draft plan (untested) … Detailed instructions will follow after we've done a batch dry-run" — while this same PR adds submit_ccc_experiment.sh, which implements precisely that plan. Replace the TODO with a pointer to the script.
h. Section ordering. The setup doc runs §A → §B → §C.1 → §C. C.1 before C reads like a mis-merge; renumber.
i. Portability of the docker-shim assertion. [[ "$(readlink -f "$(which docker)")" != "$HOME/.local/bin/docker" ]] (run_ccc_experiment.sh:192, run_ccc_smoke.sh:102, and the doc's sanity check at line 619) compares a fully-resolved path against an unresolved $HOME. If any component of $HOME is a symlink — common when /u/<user> fronts GPFS — this trips and run_ccc_experiment.sh aborts with exit 3 on a correctly configured node. Compare readlink -f on both sides.
j. Smoke task disagreement. run_ccc_smoke.sh defaults to invoice-fraud-detection ("the one we know passes with seed skills"); both docs use offer-letter-generator as the smoke task, and §C.1 reports it as the one confirmed fixed by the v7 image. Pick one, or explain why they differ.
k. Small script nits.
run_ccc_smoke.shheader (line 30) documents a marker file namedPASS/FAIL/ERROR; the code writes a file namedOUTCOMEcontaining that word (lines 105/203).run_ccc_smoke.sh:161-162— comment says "Newest run subdir (timestamped)" butfind … | head -1returns filesystem order, not newest. Harmless today becauserm -rf "$JOBS"precedes it, but the comment will mislead the next person, and it silently picks one of N trials.--helpoutput is truncated mid-section by hardcodedsedranges:sed -n '2,25p'(smoke, cuts the output-layout list) andsed -n '2,40p'(submit).submit_ccc_experiment.shheader example (line 16) pairs--queue x86_1hwith--walltime 6:00.submit_ccc_experiment.sh:97passes-M 64G. LSF-Munits depend onLSF_UNIT_FOR_LIMITS; can you confirm CCC's LSF accepts theGsuffix rather than needing-R "rusage[mem=64G]"?setup_podman.sh:245export PYTHONPATH=…(inrun_ccc_experiment.sh) clobbers any inheritedPYTHONPATHinstead of prepending.setup_podman.shleaksSTORAGE_BASE,RUN_BASE,CONF_DIR,CONF_FILEinto the sourcing shell (theunsetat line 297 misses them) — generic names in a shell the user keeps using.setup_podman.sh:70-71overwrites an existing~/.config/containers/storage.confwith no backup. It's described as idempotent, but it's destructive to a hand-maintained file. A.bakon first write would be cheap.setup_podman.shhas a#!/bin/bashshebang, ischmod +x, and is meant to besourced; line 98's${var//…}is bash-only. Worth a one-line "must be sourced from bash" note.
Placement / conventions
l. third_party/skillbench/docs/SKILLSBENCH_INVENTORY.md is in the wrong place. Two problems:
third_party/in this repo holds vendored upstream code with provenance — seethird_party/spreadsheetbench/with itsNOTICE.md+README.md.SKILLSBENCH_INVENTORY.mdis our own analysis (it contains our baseline numbers, "our current 4-skill seed package", and a cap-evolve-vs-EvoSkills strategy section). It isn't third-party content and carries no upstream notice.- The directory is spelled
skillbenchwhile the benchmark isskillsbencheverywhere else in the tree:examples/skillsbench/,ci/benchmarks/skillsbench/,docs/REPRODUCE_skillsbench.md.
docs/evidence/ or examples/skillsbench/ would fit the existing structure better.
m. Nothing links to the new docs. README.md:304 is the single entry point for how-to guides and points only at cap-evolve-with-exgentic-tau2.md. Please add a row for the CCC guide, otherwise these 900 lines are unreachable except by find.
n. Generalizability — clean, and I want to note it. I checked the diff for code changes: there are none outside scripts/ccc/. Nothing under core/ or skills/ is touched, so no CCC- or SkillsBench-specific assumption leaks into the algorithm surface. The SkillsBench-specific values in run_ccc_smoke.sh (claude-agent-acp, claude-opus-4-6, the task id, seed_capability) are fine where they are — a CCC smoke script is legitimately environment-specific, and an environment-specific setup guide is not a generalizability violation. No objection on that axis.
Verification I ran
bash -non all four scripts: clean.submit_ccc_experiment.sh --dry-run: fails as described in (3).run_ccc_experiment.sh --dry-run: reaches the spec check and exits cleanly with a good error message.- Confirmed
cap-evolve runaccepts every flag the scripts pass (--spec --project --run-ts --resume --max-iterations), and that--spec .capevolve/project/capevolve.yamlwith--project .capevolve/projectresolves correctly after thecd "$PROJECT_ROOT"—_resolve_specresolves an explicit--specagainst the cwd and its inside-project check passes. No bug there, though--specis redundant since it's the default. - Core suite green on this branch: 954 passed, 12 skipped. Nothing in shared config was disturbed. (Note the branch is 9 commits behind
origin/main; a rebase before merge would be good hygiene.)
Recommendation
Request changes. Must-fix before merge: (1) source the in-repo setup_podman.sh, (2) de-hardcode CE_BIN, (3) fix the --dry-run mkdir and CCC_LOGS default, (4) green CI (DCO sign-off + the two dangling links), (5) /results/ in .gitignore. I'd also drop HANDOFF_CCC.md, trim the credentials section, move the inventory out of third_party/, and pin the uv install.
Once the scripts run from a clean checkout and CI is green, this is a solid contribution — the setup guide is the kind of institutional knowledge that usually evaporates, and it's worth keeping.
— Reviewed by Osher-Elhadad
…tick CI Addresses Osher's review on skillberry-ai#412. Blocking: 1. Source the in-repo setup_podman.sh. Both runners sourced the author's personal copy on shared storage, so the committed script was dead code and Phase 1 failed for anyone else. Now "$SCRIPT_DIR/setup_podman.sh", overridable via $CCC_SETUP_PODMAN, with a clear error if unreadable. The docs told readers to source that external path too — all eight references now point at scripts/ccc/setup_podman.sh. 2. De-hardcode CE_BIN: $CE_BIN, then $PROJECT_ROOT/.venv, then $PATH, with an error naming all three. Note that a worktree does not inherit the main checkout's .venv. 3. submit --dry-run works from any account: mkdir moved after the dry-run guard, and CCC_LOGS defaults to $PROJECT_ROOT/results/.ccc_logs. Verified with the exact invocation from the script's own header. 4. CI: signed off, and both dangling links in HANDOFF_CCC.md removed (the .env self-link and the absolute /u/boazc uv path). 5. /results/ added to .gitignore — the runners write a redacted .env and bench logs there, so `git add -A` after a run could commit them. Security: - Invert the env-snapshot redaction. The sed only caught *TOKEN=/*KEY=, so a *_SECRET, *_PASSWORD or Authorization= line went to disk in cleartext. Now an allowlist of known-non-secret keys, everything else redacted; verified against a .env containing each of those. - Pin the uv installer (ARG UV_VERSION=0.9.7) instead of installing latest, so image contents stop drifting between rebuilds. - Document the ubuntu:24.04 tag-shadowing blast radius, including that the wrappers swallow every error (so a real permission failure can score as a pass — a benchmark-integrity risk, not just a convenience one) and that other projects on the node inherit the mutated base. Adds a revert recipe, which did not exist. - Note that --agent-env puts the bearer token on argv, readable via ps -ef on a shared cluster. - Trim the credentials section to "put it in .env" — it published an internal VPC hostname and the token's length and prefix. Accuracy: - Flag that the cap-evolve path does NOT pass --sandbox-user '': nothing reads SKILLSBENCH_SANDBOX_USER, so the smoke is green while a real run hits the chown /home/agent/.claude failure. Marked in both the doc and run_ccc_experiment.sh rather than left as a silent trap. - Resolve both sides of the docker-shim readlink comparison; comparing a resolved path against an unresolved $HOME aborts with exit 3 on a correctly configured node whenever $HOME contains a symlink. - Move the inventory out of third_party/ — it is our own analysis, not vendored upstream code. An identical copy already lives on the skillbench-history branch at insights/SKILLSBENCH_INVENTORY.md, so this deletes rather than relocates. - Link the CCC guide from README's how-to table; it was unreachable. - Prepend rather than clobber $PYTHONPATH. - setup_podman.sh: back up an existing storage.conf before overwriting, unset the four generic vars it leaked into the sourcing shell, and note that it must be sourced from bash. - submit: --help no longer truncates, --memory documents that CCC's LSF accepts the G suffix (verified: bjobs reports "64 G"), stale --walltime and --cpus defaults corrected in the header. - smoke: header said the marker file is named PASS/FAIL/ERROR when it is named OUTCOME; corrected the misleading "newest run subdir" comment on a `find | head -1`; explained why its default task differs from the docs' example task. Also folds the LSF batch-mode guidance into the submit wrapper itself: it no longer passes -W at all unless asked (a wall-clock limit kills these jobs after the result is already written), defaults to -n 1 for --max-iterations 0, and gains --host for the required one-host-per-job pin. Documents that the cccxc600-630 range is permanently reserved for another group despite showing as idle in bhosts. Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
…tick CI Addresses Osher's review on skillberry-ai#412. Blocking: 1. Source the in-repo setup_podman.sh. Both runners sourced the author's personal copy on shared storage, so the committed script was dead code and Phase 1 failed for anyone else. Now "$SCRIPT_DIR/setup_podman.sh", overridable via $CCC_SETUP_PODMAN, with a clear error if unreadable. The docs told readers to source that external path too — all eight references now point at scripts/ccc/setup_podman.sh. 2. De-hardcode CE_BIN: $CE_BIN, then $PROJECT_ROOT/.venv, then $PATH, with an error naming all three. Note that a worktree does not inherit the main checkout's .venv. 3. submit --dry-run works from any account: mkdir moved after the dry-run guard, and CCC_LOGS defaults to $PROJECT_ROOT/results/.ccc_logs. Verified with the exact invocation from the script's own header. 4. CI: signed off, and both dangling links in HANDOFF_CCC.md removed (the .env self-link and the absolute /u/boazc uv path). 5. /results/ added to .gitignore — the runners write a redacted .env and bench logs there, so `git add -A` after a run could commit them. Security: - Invert the env-snapshot redaction. The sed only caught *TOKEN=/*KEY=, so a *_SECRET, *_PASSWORD or Authorization= line went to disk in cleartext. Now an allowlist of known-non-secret keys, everything else redacted; verified against a .env containing each of those. - Pin the uv installer (ARG UV_VERSION=0.9.7) instead of installing latest, so image contents stop drifting between rebuilds. - Document the ubuntu:24.04 tag-shadowing blast radius, including that the wrappers swallow every error (so a real permission failure can score as a pass — a benchmark-integrity risk, not just a convenience one) and that other projects on the node inherit the mutated base. Adds a revert recipe, which did not exist. - Note that --agent-env puts the bearer token on argv, readable via ps -ef on a shared cluster. - Trim the credentials section to "put it in .env" — it published an internal VPC hostname and the token's length and prefix. Accuracy: - Flag that the cap-evolve path does NOT pass --sandbox-user '': nothing reads SKILLSBENCH_SANDBOX_USER, so the smoke is green while a real run hits the chown /home/agent/.claude failure. Marked in both the doc and run_ccc_experiment.sh rather than left as a silent trap. - Resolve both sides of the docker-shim readlink comparison; comparing a resolved path against an unresolved $HOME aborts with exit 3 on a correctly configured node whenever $HOME contains a symlink. - Move the inventory out of third_party/ — it is our own analysis, not vendored upstream code. An identical copy already lives on the skillbench-history branch at insights/SKILLSBENCH_INVENTORY.md, so this deletes rather than relocates. - Link the CCC guide from README's how-to table; it was unreachable. - Prepend rather than clobber $PYTHONPATH. - setup_podman.sh: back up an existing storage.conf before overwriting, unset the four generic vars it leaked into the sourcing shell, and note that it must be sourced from bash. - submit: --help no longer truncates, --memory documents that CCC's LSF accepts the G suffix (verified: bjobs reports "64 G"), stale --walltime and --cpus defaults corrected in the header. - smoke: header said the marker file is named PASS/FAIL/ERROR when it is named OUTCOME; corrected the misleading "newest run subdir" comment on a `find | head -1`; explained why its default task differs from the docs' example task. Also folds the LSF batch-mode guidance into the submit wrapper itself: it no longer passes -W at all unless asked (a wall-clock limit kills these jobs after the result is already written), defaults to -n 1 for --max-iterations 0, and gains --host for the required one-host-per-job pin. Documents that the cccxc600-630 range is permanently reserved for another group despite showing as idle in bhosts. Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
e138b90 to
f5819b1
Compare
|
Thanks — this was a genuinely useful review; the account-portability problems were real and the redaction one was worse than reported. All blocking items are fixed and CI is green (DCO included). Pushed as three commits, then rebased with Blocking
Security(d) was the important one. The
Accuracy
|
Consolidated CCC/podman operational docs and the ccc/ helper scripts used to run cap-evolve on CCC compute nodes without root: podman graphroot setup, job submission wrapper, and a smoke test, plus an inventory of what's staged for SkillsBench runs. Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
…_party/skillbench/docs Keep top level clean: operational CCC/podman docs live under docs/how-to/, and SkillsBench-specific docs live under third_party/skillbench/docs, consistent with third_party/spreadsheetbench. Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
The "Batch (LSF) mode — TODO" section was a draft plan marked untested. Running the transfer_eval_v1 8-fold pilot through bsub tested it. Most of the plan held (the setup_podman.sh wrapper, host-local DOCKER_HOST/dbus paths, /tmp cleanup), but the wall-time advice was actively harmful, so this replaces the section with what we learned: - Do NOT pass -W. A --max-iterations 0 job finishes in ~45 min then often fails to exit, hanging in a post-run step with the result already written. With -W 2:00, LSF killed those jobs via TERM_RUNLIMIT *after* the work was done, turning valid results into EXIT and forcing reruns. - Detect completion by grepping cap-evolve.log for the result JSON, not from bjobs STAT — a finished-but-hung job sits in RUN forever. Kill by exact job ID only; concurrent worktrees share the UID. - Distinguish a hung payload (complete log → kill, keep result) from a stalled setup (no log after ~45 min → kill, resubmit elsewhere with a fresh --run-ts). One fold sat in RUN 15.6 h frozen in Phase 2. - One dedicated host per concurrent job: podman's graphroot is per-user per-host, so co-located jobs corrupt each other's container state. Cross-check bhosts against brsvs — reservations hide behind idle hosts. - Use -n 1 for single-eval runs. - Note that submit_ccc_experiment.sh hardcodes -W and --cpus 4, and that run_ccc_experiment.sh resolves the CLI from a worktree-local .venv rather than PATH. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
…tick CI Addresses Osher's review on skillberry-ai#412. Blocking: 1. Source the in-repo setup_podman.sh. Both runners sourced the author's personal copy on shared storage, so the committed script was dead code and Phase 1 failed for anyone else. Now "$SCRIPT_DIR/setup_podman.sh", overridable via $CCC_SETUP_PODMAN, with a clear error if unreadable. The docs told readers to source that external path too — all eight references now point at scripts/ccc/setup_podman.sh. 2. De-hardcode CE_BIN: $CE_BIN, then $PROJECT_ROOT/.venv, then $PATH, with an error naming all three. Note that a worktree does not inherit the main checkout's .venv. 3. submit --dry-run works from any account: mkdir moved after the dry-run guard, and CCC_LOGS defaults to $PROJECT_ROOT/results/.ccc_logs. Verified with the exact invocation from the script's own header. 4. CI: signed off, and both dangling links in HANDOFF_CCC.md removed (the .env self-link and the absolute /u/boazc uv path). 5. /results/ added to .gitignore — the runners write a redacted .env and bench logs there, so `git add -A` after a run could commit them. Security: - Invert the env-snapshot redaction. The sed only caught *TOKEN=/*KEY=, so a *_SECRET, *_PASSWORD or Authorization= line went to disk in cleartext. Now an allowlist of known-non-secret keys, everything else redacted; verified against a .env containing each of those. - Pin the uv installer (ARG UV_VERSION=0.9.7) instead of installing latest, so image contents stop drifting between rebuilds. - Document the ubuntu:24.04 tag-shadowing blast radius, including that the wrappers swallow every error (so a real permission failure can score as a pass — a benchmark-integrity risk, not just a convenience one) and that other projects on the node inherit the mutated base. Adds a revert recipe, which did not exist. - Note that --agent-env puts the bearer token on argv, readable via ps -ef on a shared cluster. - Trim the credentials section to "put it in .env" — it published an internal VPC hostname and the token's length and prefix. Accuracy: - Flag that the cap-evolve path does NOT pass --sandbox-user '': nothing reads SKILLSBENCH_SANDBOX_USER, so the smoke is green while a real run hits the chown /home/agent/.claude failure. Marked in both the doc and run_ccc_experiment.sh rather than left as a silent trap. - Resolve both sides of the docker-shim readlink comparison; comparing a resolved path against an unresolved $HOME aborts with exit 3 on a correctly configured node whenever $HOME contains a symlink. - Move the inventory out of third_party/ — it is our own analysis, not vendored upstream code. An identical copy already lives on the skillbench-history branch at insights/SKILLSBENCH_INVENTORY.md, so this deletes rather than relocates. - Link the CCC guide from README's how-to table; it was unreachable. - Prepend rather than clobber $PYTHONPATH. - setup_podman.sh: back up an existing storage.conf before overwriting, unset the four generic vars it leaked into the sourcing shell, and note that it must be sourced from bash. - submit: --help no longer truncates, --memory documents that CCC's LSF accepts the G suffix (verified: bjobs reports "64 G"), stale --walltime and --cpus defaults corrected in the header. - smoke: header said the marker file is named PASS/FAIL/ERROR when it is named OUTCOME; corrected the misleading "newest run subdir" comment on a `find | head -1`; explained why its default task differs from the docs' example task. Also folds the LSF batch-mode guidance into the submit wrapper itself: it no longer passes -W at all unless asked (a wall-clock limit kills these jobs after the result is already written), defaults to -n 1 for --max-iterations 0, and gains --host for the required one-host-per-job pin. Documents that the cccxc600-630 range is permanently reserved for another group despite showing as idle in bhosts. Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
… guide
Per review: HANDOFF_CCC.md was a paused-session journal, not documentation,
and it contradicted itself — the header claimed the smoke passed and all
workarounds were in place, while "Where we paused" said errors=1 and "For a
fresh Claude session" named aardvark-dns as the live blocker. That blocker
was resolved; the scripts in this PR have since run an 87-task benchmark and
an 8-fold transfer pilot. It documented a state that no longer exists.
It was also addressed to an AI session rather than a contributor, used one
account as ground truth throughout (boazc, /dccstor/..., podman-561567,
cccxc554, specific UIDs), and pointed at errors_1.txt..errors_5.txt as
"kept in-tree" when they are in no tree.
Rather than relocate a stale, self-contradictory doc, this deletes it. Git
history keeps the original recoverable:
git show 1bf7167:docs/how-to/ccc/HANDOFF_CCC.md
Four durable pieces move into CCC_PODMAN_SETUP.md, which already carried
the full detail the handoff only summarized:
- "Layer index: symptom -> fix" — the 13-layer list as a scannable table,
cross-referenced to the sections holding the detail. This was the best
thing in the handoff and the setup guide had no equivalent index.
- "What this touches outside the repo" — every path the setup writes to,
so a reader knows their blast radius on their own account, plus the note
that `uv tool install --force benchflow` wipes the SS A/SS B patches.
- "If you ever get admin help, delete all of it" — every workaround here
routes around one missing subuid range; worth saying plainly so nobody
maintains this forever.
- The Modal/benchflow-0.6.5 limitation, already covered under
"What's NOT solved".
Dropped: the paused-session narrative, "For a fresh Claude session", the
old last-blocker post-mortem, "Where we paused", the errors_x archive, and
the git-state snapshot. Nothing references the deleted file.
Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
The bench-patch sections ran A, B, C.1, C. Beyond reading like a mis-merge, the ".1" falsely implied the uv section was a sub-part of the --sandbox-user section; the two are unrelated (one patches the base image, the other is a bench CLI flag). Renamed C.1 to D and moved it after C, so the order is A, B, C, D. Pure reorder: no prose changed apart from the heading, and nothing referenced "C.1" anywhere. Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
08aa171 to
f4b1e61
Compare
…completion sweep Two lessons from the c4 task-by-task run (2026-09-02). Remove --walltime/-W from submit_ccc_experiment.sh outright rather than leaving it as an opt-in that defaults to unset. A stale copy of this script carrying the old 2:00/8:00 auto-default was still in use in a worktree and silently killed completed runs with TERM_RUNLIMIT during post-run hangs. With no variable, no flag and no code path, the default cannot be reintroduced by copying an old command line. Document `lout <jobid> | grep "Exit: 0"` as the fast first-pass sweep for the finish-then-hang case. Grepping cap-evolve.log needs the suite-id/job-id paths for each run; lout triages every in-flight job in one loop and is authoritative that the work is done, so a bkill on that exact id is cleanup rather than an interruption. The log check stays for when you need the actual result, not just completion. Signed-off-by: Boaz Carmeli <boazc@il.ibm.com>
f4b1e61 to
607d206
Compare
Consolidated CCC/podman operational docs and the
scripts/ccc/helper scripts used to run cap-evolve on CCC compute nodes without root access: podman graphroot setup, job submission wrapper, and a smoke test, plus an inventory of what's staged for SkillsBench runs.