Answers 'how can the weekly run produce counts like the hand count?' — by doing exactly what the hand count did, deterministically. Two changes: 1. PAGINATION. The scanner requested per_page=100 and stopped. This endpoint caps at 100 AND ignores ?page= (it re-returns the same rows — which is how a manual count first produced exact triplicates and a bogus 300). Busy projects were silently truncated: discourse has 286 advisories, so a single page could not see the window at all. Now follows the Link rel=next cursor to exhaustion. 2. DATE-BASED FALLBACK. Version strings cannot be ordered across a scheme change (discourse semver 3.5.3 -> calver 2026.7.1), which is why the scan first reported a false 133, then correctly refused. Release DATES always order. When the version path refuses, the scan now resolves both versions to their git tag dates on the primary repo and counts advisories PUBLISHED in that window, labelling the method in the output. The version path is still preferred when usable — it is exact rather than temporal. Verified: discourse 3.5.3 -> 2026.7.1 now reports 123, matching the hand count (1 critical, 16 high, 91 medium, 16 low; window 2025-12-30 -> 2026-07-31); gitea 1.27.0 -> 1.27.1 still reports 2 via the version path.
cc-ci-plan
Self-contained handoff package for building the cc-ci Co-op Cloud recipe CI server with two autonomous Claude loops (a Builder and an adversarial Reviewer) running over days.
Start here
- Read
plan.md— the full plan and single source of truth (mission, Definition of Done, architecture, milestones, the two-agent coordination protocol, loop discipline). - Read
kickoff.md— how to launch and supervise the loops. - Run
./launch.sh startto bring up both loops + the watchdog.
Files
| File | Purpose |
|---|---|
plan.md |
The Phase-1 plan (build the CI server). Agents treat it as their single source of truth. |
plan-phase1c-full-reproducibility.md |
Phase 1c (runs first): make the VM fully reproducible from git (all secrets incl. the wildcard cert in sops, in a separate private cc-ci-secrets repo as a flake input; base stays well-parameterized) and do the genuine throwaway-VM live rebuild to close D8 honestly (the "infeasible by design" was overstated). |
plan-phase1b-review-lint.md |
Phase 1b (after 1c): deterministic linting/formatting in CI + a white-box review checklist (real tests, DRY harness, idempotent Nix, no footguns/secrets), ending in a full cold re-verification of all D1–D10 — now covering 1c's refactor. |
plan-phase1d-generic-test-suite.md |
Phase 1d (after 1b, before 2): a generic install/upgrade/backup/restore suite that runs on any recipe with zero config, with a recipe's own test_<op>.py overriding or extending the generic (Builder's call) and reusing the generic's deployment — no redeploy, plus optional custom install-steps; recipes needing special setup fail the generic form gracefully. The test-architecture foundation Phase 2 builds on. |
plan-phase1e-harness-corrections.md |
Phase 1e (after 1d, before 2): three operator-review corrections to the shared generic harness — (HC1) upgrade goes previous-release → PR head via deploy --chaos; (HC2) repo-local PR code runs only for approved recipes (default = cc-ci overlays + generic only); (HC3) the generic runs by default alongside an overlay, skipped only via explicit opt-out. |
plan-phase2-recipe-tests.md |
Phase 2 (after Phase 1e): build on the corrected generic suite — author the recipe overlays (port recipe-maintainer tests as test_*.py) + define custom install steps where a recipe fails generically. |
plan-phase2b-test-performance.md |
Phase 2b (after Phase 2, before Phase 3): empirically measure where test time goes and reduce it (image cache, readiness tuning, dedup deploys, warm infra, concurrency) — no weakened tests. |
plan-phase3-results-ux.md |
Phase 3 (after Phase 2b): beautiful YunoHost-style results — per-run level, image-forward PR comment (badge + summary card + app screenshot), polished dashboard. |
IDEAS.md |
Deferred/future ideas, parked out of current scope. |
brief.md |
The original one-page brief (context only; plan.md supersedes it). |
kickoff.md |
Launch & supervision guide. |
launch.sh |
Starts both loops + a watchdog; restarts dead loops; stops on ## DONE. |
prompts/builder.md |
Builder loop prompt (fed to claude by the script). |
prompts/adversary.md |
Adversary loop prompt. |
Before launching
- Set the org in
plan.md(git.autonomic.zone/recipe-maintainers/cc-ci) and lock the six proof recipes (§8). - Ensure the launching shell has: SSH+sudo to
cc-ci, the Gitea token,git.autonomic.zoneaccess. - Preconfigure test-app DNS + TLS (plan §4.0): point a wildcard
*.ci.commoninternet.netrecord at a gateway that TLS-passthroughs to cc-ci, and pre-issue the wildcard cert (*.ci.commoninternet.net+ci.commoninternet.net, via Gandi DNS-01) into/var/lib/ci-certs/live/on cc-ci. The agent handles everything else on cc-ci (Traefik file provider → that cert, swarm, routing) and does no ACME; renewal (~90 days) is an out-of-band operator task, so the DNS token never goes to the agent. export CC_CI_REPO=https://git.autonomic.zone/recipe-maintainers/cc-ci.gitso the watchdog can detect## DONE.
What "done" means
The loops stop only when all of plan.md §2 (D1–D10) hold and the Adversary has independently
re-verified each within 24h. The watchdog then tears the loops down automatically.