Skip to content

ci: scope every expensive job to a classifier capability vector (#1152) - #1155

Merged
rickylabs merged 10 commits into
mainfrom
ci/scope-expensive-jobs
Aug 3, 2026
Merged

ci: scope every expensive job to a classifier capability vector (#1152)#1155
rickylabs merged 10 commits into
mainfrom
ci/scope-expensive-jobs

Conversation

@rickylabs

@rickylabs rickylabs commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

Promotes .github/scripts/ci-classify-changes.ts from a two-output e2e-cli gate to a capability
vector (needs_deno / needs_docker / needs_desktop / needs_docs / needs_surface) consumed
by e2e-cli.yml, ci.yml and surface-diff.yml, with the two #1122 precision fixes: only the
tier-defining workflows (e2e-cli.yml, ci.yml) escalate the scaffold tiers, and a tasks-only
root deno.json edit is a script alias, not a toolchain change. Paths decide, the frozen three
ci:* labels override, every gated job still starts and reports SUCCESS
(scaffold-static's skipped-by-policy pattern), and an unrecognised path forces the whole vector
true. Also bumps all version-tagged actions to Node-24 majors (owner request).

Scope

Slices

Validation

Definition of Done

  • ci-classify-changes.ts emits the capability vector, unit-tested per output incl. negatives
  • check-test/quality consult needs_deno and report skipped-by-policy when false
  • scaffold-runtime gated as the docker tier; scaffold-static is the deno-only default tier
    (owner-ratified D5: no third suite)
  • No routing table in workflow YAML; jobs read classifier outputs only
  • Label set unchanged (ci:full, ci:skip-scaffold, ci:skip-e2e)
  • Unrecognised path still forces every gate to run (explicit SAFETY tests)
  • Measured before/after recorded on ci: scope every expensive job to a capability vector — paths decide, labels override #1152 (audited baseline + live demo measurements;
    post-merge sample observation continues on the issue)

Harness

  • Run dir: .llm/runs/ci-scope-expensive-jobs--1152/
  • Phase: impl — owner ratified the plan directly and ordered proceed-to-green (recorded in
    drift.md); formal PLAN-EVAL superseded by owner authority.

Drift / Debt

  • quality gate widened to needs_deno || needs_docs (docs PRs still need fmt/docs-accuracy);
    needs_docs excludes agent-context Markdown so the docs(release): a failed canary is fixed forward, not yanked #1055 class skips everything. See drift.md.
  • Follow-up: needs_docker package-set tightening against observed green history; sqlite runtime
    tier tracked separately.

rickylabs and others added 2 commits August 3, 2026 17:03
)

The job declared needs: classify but never read the verdict, so it built
a .deb and signed updater on every PR (20/20 in the last-20 audit, ~41
min). It now runs only when the classifier says either scaffold tier
runs, short-circuiting to the scaffold-static skipped-by-policy pattern
otherwise so it stays eligible as a required check. Fail-closed: a
failed classify still forces a full run; a dedicated needs_desktop
signal is #1152 scope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
… + plan for #1152)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
@rickylabs rickylabs added this to the 0.0.5 milestone Aug 3, 2026
@rickylabs rickylabs added area:tooling type:chore Tooling, config, or housekeeping status:plan Harness plan phase priority:p1 High labels Aug 3, 2026
@rickylabs

Copy link
Copy Markdown
Owner Author

[PHASE: PLAN]

Capability-vector plan committed (.llm/runs/ci-scope-expensive-jobs--1152/plan.md); PLAN-EVAL pending before any slice lands.

Locked decisions

  1. D1 One classifier, five outputs; unrecognised path ⇒ entire vector true (unit-tested); ci:full forces all; skip labels keep exactly their current scaffold-only semantics; label set frozen.
  2. D2 v1 stays deliberately wide: needs_deno = !docs_only; needs_docker keeps all of packages/** (v1 docker savings come from workflow/deno.json precision, not package guessing); needs_desktop = packages/cli/** + toolchain (the whole .deb surface lives there).
  3. D3 feat(release): derive canary labels from published versions #1122 precision: only e2e-cli.yml/ci.yml escalate scaffold tiers; deno.json gets structural tasks-only vs toolchain discrimination fed from git show BASE/HEAD, unparseable ⇒ toolchain.
  4. D4 Every consumer copies the scaffold-static skipped-by-policy pattern verbatim — required checks keep reporting; no second pattern, no routing in YAML.
  5. D5 The "deno-only default tier" is the existing scaffold-static; run_runtime := needs_docker. No third e2e suite in this PR (that would be packages/cli/e2e framework work — wrong lane).

Open questions for PLAN-EVAL / owner

  • D5 reading of the "splits into a deno-only default tier" acceptance box.
  • Whether non-tier workflow edits may drop needs_deno later (v1: keep true).
  • .llm/tools/**/*.ts is docs-classified today but root deno test may discover its tests — S2 settles this empirically, defaulting toward running.

Next

  • Dispatch PLAN-EVAL (separate open-model evaluator session per lane-policy.md); slices S1–S6 begin only on PASS.

rickylabs and others added 6 commits August 3, 2026 17:25
…1152 S1+S2)

decide() now emits needs_deno/needs_docker/needs_desktop/needs_docs/
needs_surface alongside run_static/run_runtime. Only the tier-defining
workflows (e2e-cli.yml, ci.yml) escalate the scaffold tiers; a root
deno.json diff touching only tasks is a script alias, not a toolchain
change. Unrecognised paths force the ENTIRE vector true, root deno test
discovery keeps .llm/tools code on needs_deno, and every output carries
positive and negative unit coverage (50 tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
…S3)

desktop-native-linux swaps the #1151 run_static||run_runtime proxy for
the dedicated needs_desktop output (packages/cli is the whole .deb
surface); scaffold-runtime is documented as the docker tier; classify
extracts root deno.json base/head for the tasks-only discrimination and
lane visibility reports the desktop selection directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
ci.yml gains its own classify job (same script, same fail-closed rule).
check-test reads needs_deno; quality reads needs_deno || needs_docs so
docs-only PRs still get fmt/docs-accuracy. Both required checks always
start and report SUCCESS via the scaffold-static skipped-by-policy
pattern; push events classify as run-everything; close-gate and
deps-report stay ungated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
…1152 S5)

The workflow-level paths filter meant no status report on non-package
PRs, blocking required-check promotion. needs_surface mirrors the old
filter; the job now always starts and short-circuits to
skipped-by-policy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
checkout v4->v5, upload-artifact v4->v5, download-artifact v4->v5,
setup-dotnet v4->v5, upload-pages-artifact v3->v5, deploy-pages v4->v5,
configure-pages v5->v6 — the smallest majors whose runtime is node24 for
the release-critical actions. SHA-pinned third-party actions are left as
pinned; denoland/setup-deno@v2 is already the latest major.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVEZJ1CBtRYNXzGQRZrTat
rickylabs and others added 2 commits August 3, 2026 17:31
@rickylabs rickylabs added status:impl and removed status:plan Harness plan phase labels Aug 3, 2026
@rickylabs

rickylabs commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

[PHASE: IMPL]

All six slices landed and live-verified. The two measured waste classes from the audit are now proven skips:

Class Demo Result
docs/agent-context-only (#1055/#1063/#1123) PR #1156, run 30827771974 scaffold-static, scaffold-runtime, desktop-native-linux all skipped-by-policy, all report SUCCESS
release-tooling (#1122) PR #1157, run 30827782060 same three skips on a release-canary.yml-only diff

The positive case is this PR's own CI (tier-workflow edit → full run). ci.yml's docs-only negative can only manifest on a post-merge PR (its trigger is branch-filtered); expression parity with the proven e2e-cli pattern plus the classifier's unit tests cover it until the first live observation, which will be recorded on #1152.

Acceptance evidence

  • ci-classify-changes.ts emits the capability vector above, unit-tested per output — 50 tests incl. per-output negatives: https://github.com/rickylabs/netscript/pull/1155/files (ci-classify-changes.test.ts)
  • check-test and quality consult needs_deno and report skipped-by-policy when it is false — ci.yml classify job + RUN gates in this PR's diff; fail-closed on classify failure; live docs-only observation to follow post-merge on ci: scope every expensive job to a capability vector — paths decide, labels override #1152
  • scaffold-runtime splits into a deno-only default tier and a docker tier gated on — owner-ratified D5: the existing scaffold-static IS the deno-only default tier and scaffold-runtime is the docker tier (run_runtime reads the docker signal); demo runs 30827771974 and 30827782060 show the tier skipping by policy
  • No second routing table exists in workflow YAML — jobs read classifier outputs only — every gated job reads a two-term classifier expression; all path logic lives solely in the unit-tested script (see the PR diff)
  • The label set is unchanged: ci:full, ci:skip-scaffold, ci:skip-e2e, and no others — no label additions in this PR; frozen-semantics negative test "skip labels never widen to the vector"
  • Conservative default preserved: an unrecognised path still forces the gate to run — SAFETY tests: unrecognised paths and .github/scripts force the ENTIRE vector true; empty diff and non-PR events run everything
  • Measured before/after on a comparable PR sample, recorded on this issue — measurement comment on ci: scope every expensive job to a capability vector — paths decide, labels override #1152 (audited 390-min baseline, live demo class measurements, projection and ongoing-sample commitment)

Next

  • PR CI green → acceptance mirror → status:ready-merge → merge (owner-authorized).

@rickylabs
rickylabs marked this pull request as ready for review August 3, 2026 15:42
@rickylabs
rickylabs merged commit 950a059 into main Aug 3, 2026
30 of 38 checks passed
@rickylabs
rickylabs deleted the ci/scope-expensive-jobs branch August 3, 2026 15:49
@github-actions github-actions Bot added the canary:0.0.4-canary.1 Published NetScript prerelease 0.0.4-canary.1 label Aug 3, 2026
rickylabs added a commit that referenced this pull request Aug 3, 2026
Evidence-base definition widened with per-claim citations instead of silent
promotion; note-accumulation and the #1142 mitigation downgraded to [asserted]
with gaps stated; identity derivation re-anchored on the release-canary.yml
wiring; drift-gate section reduced to its observable contract; quota/transport
gates given a recorded-output proof form; stage-C operability wired to
tooling.md/agent-handoff.md and codex-watch turn interception; D2 tension
(#1153/#1155 pre-ratification merges) surfaced rather than claimed away.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq
rickylabs added a commit that referenced this pull request Aug 3, 2026
…gates; escalate C9, M1/M2

The two previously undemonstrated gates now carry real negative cases
(gate-demos.md): check 3 fires RED on a synthetic new-ignore diff and stays
GREEN on excluded-path quotes; the #1142 selection rule recovers PR #1155's
true pre-merge verdict from a live rollup containing a post-merge FAILURE.
D2 evidence box unticked pending the owner's ruling; the [observed]
source-of-record dispute is recorded in drift.md for the owner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq
rickylabs added a commit that referenced this pull request Aug 3, 2026
…ile, rolling canary cadence (#1161)

* chore(harness): bootstrap milestone-orchestrator authoring run + locked outline

Run dir + supervisor identity + plan of record for the three #1120 artifacts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* docs(harness): rolling canary cadence — trigger, membership, D3 identity, note, drift gate

The schedule artifact of #1120. Wave boundary as the canary point and content-derived
membership are [observed] from the 0.0.4 trace; open questions stay [asserted] and
owner-undecided. Wires to the shipped release:canary-label surface (#1121/#1122);
publish mechanics remain with netscript-release; #1119's collision is disambiguated,
not deepened.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* docs(harness): milestone-run profile — stage contracts, pre-merge gate, cut checklist, DoD

The run artifact of #1120. Every gate carries its observed firing evidence and a stated
did-not-run signature; the honesty rule (#1092/#1146 precedents) and the #1142 false-red
trap are encoded. Role judgement stays in the orchestrator skill; canary schedule in
canary-cadence.md; publish mechanics in netscript-release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* feat(harness): agent-milestone-orchestrator skill + regenerated .claude/skills mirror

The role artifact of #1120: clustering, wave sequencing, re-planning absorption,
delegation judgement, merge authority, canary-point decisions, honesty rules, and
supervision pitfalls — every rule marked [observed] (0.0.4 trace) or [asserted].
Gate lists, run artifacts, label mechanism, and routing are referenced, never
restated. Mirror regenerated via agentic:sync-claude (incl. aspire and
netscript-release mirrors that were stale on main); agentic:check-claude green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* chore(harness): close out authoring run — S4 evidence + status flip recorded

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* fix(harness): apply Sol adversarial review findings C1-C9, M1-M6

Evidence-base definition widened with per-claim citations instead of silent
promotion; note-accumulation and the #1142 mitigation downgraded to [asserted]
with gaps stated; identity derivation re-anchored on the release-canary.yml
wiring; drift-gate section reduced to its observable contract; quota/transport
gates given a recorded-output proof form; stage-C operability wired to
tooling.md/agent-handoff.md and codex-watch turn interception; D2 tension
(#1153/#1155 pre-ratification merges) surfaced rather than claimed away.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* fix(harness): Sol cycle-2 — fix C3-residue/C10/M7, demonstrate C7+M4 gates; escalate C9, M1/M2

The two previously undemonstrated gates now carry real negative cases
(gate-demos.md): check 3 fires RED on a synthetic new-ignore diff and stays
GREEN on excluded-path quotes; the #1142 selection rule recovers PR #1155's
true pre-merge verdict from a live rollup containing a post-merge FAILURE.
D2 evidence box unticked pending the owner's ruling; the [observed]
source-of-record dispute is recorded in drift.md for the owner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* chore(harness): record owner rulings — D2 orchestrated-delivery reading; [observed] definition ratified

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* fix(harness): Sol cycle-3 residues — C10 tag-existence implication dropped, M8 stale acceptance row

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* chore(harness): record Sol cycle-4 PASS — eval loop closed green

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

* chore(harness): note mirror/label event race; retrigger CI with ready-merge label present

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReZGc3KP8xvEuruz1io7Pq

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:tooling canary:0.0.4-canary.1 Published NetScript prerelease 0.0.4-canary.1 priority:p1 High status:shipped type:chore Tooling, config, or housekeeping

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: scope every expensive job to a capability vector — paths decide, labels override

1 participant