Skip to content

docs(research,eval): deepseek-harness lessons + tier-1 eval harness repairs - #1409

Open
wildcard wants to merge 7 commits into
mainfrom
claude/deepseek-harness-improvements-tktop1
Open

wildcard wants to merge 7 commits into
mainfrom
claude/deepseek-harness-improvements-tktop1

Conversation

@wildcard

@wildcard wildcard commented Aug 16, 2026

Copy link
Copy Markdown
Owner

Description

Research into deepseek-ai/deepseek-harness ("Everything is a Plugin"), mapped against caro's three harnesses — the AgentLoop runtime, the CaroML validator/journal layer, and the evaluation harness — with tiered adoption proposals: docs/research/deepseek-harness-lessons.md. Alongside the doc, this PR ships the smallest repairs the research surfaced (Tier-1/P6a).

Motivation

Cargo.toml's candidate-ranking feature says: "flip to default in v1.4.0 after the eval harness shows ranking wins." We are at v1.5.0. The flip isn't overdue because ranking lost — the harness couldn't render the verdict: 3 of 4 CI eval matrix legs were silently no-ops, concurrency config was dead, and the one honest leg's regression floor (31.0) was 47 points below measured reality (78.2%). The doc's proposals all route toward making that verdict renderable; the fix commits repair what was unambiguous.

Changes Made

  • docs/research/deepseek-harness-lessons.md (new): dsh case study; caro mapping; 8-row principle gap table; proposals P1–P8 in three tiers; what NOT to adopt (incl. the inversion: dsh's "no privileged core" must stay inverted — caro's safety floor is deliberately privileged); 24-gap eval inventory (Appendix A); orphan-crate salvage list (Appendix B).
  • src/evaluation/harness.rs: HarnessConfig::max_concurrency was declared but never read — run_all_tests spawned one unbounded task per (case × backend). Now bounded by a tokio::sync::Semaphore; the permit is acquired before tokio::spawn, so at most max_concurrency tasks (and their captured clones) exist at once, and it is held across generate+evaluate. New regression guard: evaluation::harness::tests::test_max_concurrency_bounds_in_flight_generations.
  • .github/workflows/evaluation.yml: matrix reduced to static_matcher — the only leg that evaluates anything (the runner registers only StaticMatcher; --backend doesn't filter; embedded-* legs exited 2 behind || true). Regression baseline set to the measured 78.2 (the workflow's existing −5 rule then blocks below 73.2 and warns under 78.2; the previous 31.0 was stale). Comments explain what restores the other legs.
  • Cargo.toml: declare benches/performance.rs as [[bench]] harness = false; cargo auto-discovery ran it under libtest where criterion_main! never executed.
  • CLAUDE.md: nonexistent cargo run --bin caro-evalcargo test --test evaluation; version banner 1.4.0 → 1.5.0.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactoring (code restructuring without changing behavior)
  • Documentation update (changes to docs, comments, or guides)
  • Performance improvement (makes code faster or more efficient)
  • Test coverage (adds or improves tests)
  • CI/CD or tooling (changes to build, release, or development tools)

Checklist

Code Quality

  • I have run cargo fmt --all (cargo fmt --check clean)
  • I have run cargo clippy -- -D warnings (clean; run with --tests --benches, --no-default-features --features embedded-cpu)
  • I have run cargo test (81 lib tests in evaluation:: pass; full eval harness run below)
  • I have run cargo audit (not run locally — no dependency changes; CI cargo-audit and dependency-review are green on this PR)

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have added contract tests for new public APIs (no new public APIs)
  • I have added integration tests for cross-module workflows (n/a)
  • I have verified performance requirements are met (bench target now actually executes — see Testing Evidence)

Documentation

  • I have added rustdoc comments for new public APIs (no new public APIs; semaphore behavior documented on run_all_tests)
  • I have updated relevant documentation (research doc; CLAUDE.md drift fixes)
  • I have added examples to demonstrate new functionality (n/a)
  • I have updated the CHANGELOG.md (CHANGELOG entries are compiled at release time per release-version-alignment)

TDD Workflow

  • I followed the Red-Green-Refactor cycle — the guard test fails without the semaphore (unbounded spawns observe >2 concurrent generations) and passes with it
  • I wrote failing tests before implementing the solution
  • I verified tests with cargo watch -x test during development (single-shot runs in CI-like environment)

Breaking Changes

None. The semaphore bounds concurrency at the existing default (10); results are unchanged (same pass counts), only in-flight parallelism is capped.

API Changes

None.

Migration Guide

n/a

Deprecation Plan

n/a


Related Issues and Specs

  • Related to PR #1108 (candidate-ranking pipeline — the doc's proposals route toward its overdue eval-gated default flip)
  • Related to PR #1245 (Fireworks hybrid-harness learnings — the precedent for this research genre)
  • Prior art: thoughts/shared/plans/evaluation-harness-maturity-milestone.md

Performance Impact

Eval harness runs are now bounded at max_concurrency (default 10) in-flight generations instead of unbounded (101 × backends at once). For the static matcher this is latency-neutral (sub-second full run); for future LLM backends it prevents resource exhaustion.

Benchmarks

cargo bench --bench performance -- --test: all criterion groups now execute (cli_startup, safety validation single/batch/concurrent/sustained, shell types, pattern matching) — previously this target never ran at all, so there is no "before" to compare.

Binary Size

Unchanged (no dependency or shipped-code additions; changes are eval/test/CI-side).

Memory Usage

Bounded rather than unbounded task fan-out in eval runs (permit acquired before spawn).


Screenshots / Examples

Before

$ cargo test --test evaluation -- --backend embedded-qwen   # what 2 of 4 CI legs ran
Invalid backend: embedded-qwen. Must be one of: static_matcher, mlx, ollama, vllm
(exit 2, masked by `|| true` — leg reports "backend not available", green)

After

$ cargo test --test evaluation -- --backend static_matcher
Total Tests: 101 · Passed: 79 (78.2%) · Correctness 26/26 · Safety 25/25 · POSIX 24/25 · MultiBackend 4/25
(the only honest leg, now the only leg — baseline is the measured 78.2 instead of a stale 31.0)

Testing Evidence

Test Output

$ cargo test --no-default-features --features embedded-cpu --lib evaluation::
test evaluation::harness::tests::test_max_concurrency_bounds_in_flight_generations ... ok
test result: ok. 81 passed; 0 failed; 0 ignored; 0 measured; 518 filtered out

$ cargo test --no-default-features --features embedded-cpu --test evaluation -- --backend static_matcher
Total Tests: 101 · Passed: 79 (78.2%) · Failed: 22 (21 of 22 are MultiBackend cases, which need ≥2 registered backends)

$ cargo bench --no-default-features --features embedded-cpu --bench performance -- --test
Testing cli_startup ... Success  ·  Testing pattern_matching ... Success  ·  (all groups) Success

CI (green): ci.yml run · LLM Evaluation Harness run — the Evaluate static_matcher job independently measured 79/101 = 78.2% on ubuntu-latest / default features / Rust 1.97.1, matching the local run on a different feature set and toolchain (static matcher is deterministic).

Manual Testing

  • Tested on macOS (Apple Silicon / Intel)
  • Tested on Linux (Ubuntu-based container; embedded-cpu feature set) + CI ubuntu-latest default features
  • Tested on Windows (10 / 11)
  • Tested with different backends (static matcher — the backend this PR's CI leg evaluates)
  • Tested edge cases and error conditions (guard test pins the concurrency bound; max_concurrency: 0 clamps to 1)

Additional Context

Technical Decisions

  • Kept || true in the workflow: the runner exits 1 whenever pass rate < 100% (tests/evaluation/main.rs:231), so the real gate is the baseline-compare step; removing || true would turn CI permanently red. Fixing the exit-code contract is gap A23 in the doc, deliberately out of scope here.
  • Matrix reduced rather than "fixed": registering real embedded backends in the runner is gap A4 — a feature, not a repair; the honest state today is one leg.
  • Baseline = measured, not "measured minus headroom" (per Codex review): the workflow already subtracts 5 points for the blocking line; pre-subtracting again would have let a drop to 70% pass silently.
  • Doc proposals are proposals: nothing beyond the P6a repairs is implemented here. P5 (runtime profiles) is explicitly flagged as user-facing → validation-discipline gates before any spec.
  • Review feedback addressed (Codex ×1, cubic ×4): see the resolved threads — baseline math, floor reproducibility evidence, doc LOC figures re-measured, BaselineStore claim narrowed, semaphore acquired before spawn.
  • Devil's Advocate Review: being posted as a ## Devil's Advocate Review comment on this PR (Gate-4 culture for AI-drafted proposals, applied voluntarily to internal-tooling research).

Future Work

Tier-1: P7 CI doc-verification gates (seed cases: README.md:34 / CLAUDE.md:119 "93.1% pass rate" — untraceable to any harness output); P8 DeepSeek pricing/catalog rows if a DeepSeek backend ever lands. Tier-2: P1 generation journal (unlocks the currently-unreachable sft_export), P3 validator middleware chain, P2 execution seam, P6b eval consolidation (incl. deleting the never-compiled tests/evaluation/src/ orphan). Tier-3: P4 wire the candidate pipeline + flip the flag on evidence; P5 profiles.

Questions for Reviewers

Is setting the regression baseline to the measured 78.2 in this PR acceptable, or should the baseline change ship separately with its own bake time? (It is a one-value revert either way.)


Reviewer Checklist

  • Code follows Rust best practices and project conventions
  • Tests are comprehensive and follow TDD principles
  • Documentation is clear and complete
  • Changes align with project specifications
  • Performance impact is acceptable
  • Breaking changes are justified and documented
  • Security implications have been considered

By submitting this PR, I confirm that:

  • My code follows the style guidelines of this project (see AGENTS.md)
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings or errors
  • I have read and followed the contributing guidelines
  • I agree to the Code of Conduct

🤖 Generated with Claude Code

https://claude.ai/code/session_01JfmCW2L5d5qkNJ18mDfz6a

claude added 3 commits August 16, 2026 01:01
Maps deepseek-ai/deepseek-harness ('Everything is a Plugin') onto caro's
AgentLoop, CaroML validator/journal layer, and evaluation harness. Tiered
proposals P1-P8 route toward one outcome: rendering the eval verdict the
candidate-ranking default flip has waited on since v1.4.0. Argues one dsh
principle must invert for caro: the safety floor stays privileged.

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

- Consume HarnessConfig::max_concurrency (was declared but never read) via a
  tokio Semaphore in run_all_tests; permits span generate+evaluate so a local
  LLM backend never sees the whole dataset at once. Regression guard:
  evaluation::harness::tests::test_max_concurrency_bounds_in_flight_generations.
- evaluation.yml: reduce the matrix to static_matcher, the only leg that
  evaluates anything (the runner registers only StaticMatcher and --backend
  does not filter; embedded-* legs exited 2 behind '|| true'). Raise the
  regression floor 31.0 -> 75.0 (measured 78.2% on the 101-case dataset).
- Declare benches/performance.rs [[bench]] harness=false; cargo auto-discovery
  ran it under libtest where criterion_main! never executed. Verified via
  cargo bench --bench performance -- --test.
- CLAUDE.md: replace nonexistent 'cargo run --bin caro-eval' with
  'cargo test --test evaluation'; version banner 1.4.0 -> 1.5.0.

Validation: 81 lib tests pass; eval run 79/101 (78.2%): correctness 26/26,
safety 25/25, posix 24/25, multi_backend 4/25 (needs >=2 registered backends);
clippy -D warnings clean; fmt clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfmCW2L5d5qkNJ18mDfz6a
The validated run (79/101, 78.2%) replaces the stale 31% framing: 21 of 22
failures are MultiBackend cases starved of a second backend, and the CI floor
was 47 points below measured reality.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfmCW2L5d5qkNJ18mDfz6a
@wildcard wildcard added documentation Improvements or additions to documentation ci/cd CI/CD and GitHub Actions labels Aug 16, 2026 — with Claude

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
caro-foss-website Ready Ready Preview Sep 12, 2026 11:23pm UTC
5 Skipped Deployments
Project Deployment Actions Updated
caro-docs Ignored Ignored Sep 12, 2026 11:23pm UTC
caro-slides Ignored Ignored Sep 12, 2026 11:23pm UTC
caro-storybook Ignored Ignored Sep 12, 2026 11:23pm UTC
cmdai Ignored Ignored Sep 12, 2026 11:23pm UTC
cmdai-saas Ignored Ignored Sep 12, 2026 11:23pm UTC

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

Awesome contribution! 🌟

@github-actions github-actions Bot added rust Rust source code changes dependencies Dependency updates labels Aug 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions github-actions Bot added the size/M Medium PR (50-200 lines) label Aug 16, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b58a84613

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/evaluation.yml Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread .github/workflows/evaluation.yml Outdated
Comment thread docs/research/deepseek-harness-lessons.md Outdated
Comment thread docs/research/deepseek-harness-lessons.md Outdated
Comment thread src/evaluation/harness.rs
@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Website Claims Verification Report

Run ID: 34725236965
SHA: 7acb4c0
Date: 2026-09-12

Platform Results

claims-report-macos-latest

{
  "suite": "website-claims",
  "platform": "macos-latest",
  "timestamp": "2026-09-12T23:25:14Z",
  "passed": 84,
  "skipped": 0,
  "warnings": 1,
  "run_id": "34725236965",
  "sha": "7acb4c009e887560a0ab0317da4151771e97974b"
}

claims-report-ubuntu-latest

{
  "suite": "website-claims",
  "platform": "ubuntu-latest",
  "timestamp": "2026-09-12T23:26:12Z",
  "passed": 84,
  "skipped": 0,
  "warnings": 1,
  "run_id": "34725236965",
  "sha": "7acb4c009e887560a0ab0317da4151771e97974b"
}

Documentation

Next Steps

  1. Review warnings and address any gaps
  2. Update website if claims are inaccurate
  3. Implement missing features if claims are aspirational

@wildcard wildcard added the path:refuse-list caro-merge-review-integrate dispatcher classification label Aug 22, 2026
@wildcard

Copy link
Copy Markdown
Owner Author

[agent]

Agent: Claude Code (claude-opus-5)


Dispatcher classification: path:refuse-list (automated resurfacing declined; human merge path unaffected).

Which glob fired: .github/workflows/** — this PR touches .github/workflows/evaluation.yml.

Rationale (from .claude/automation/config/policy.yaml): workflow definitions are set to auto_dispatch: false, auto_rebase: false. CI definitions are the mechanism that validates every other change, so an automated agent must not edit or resurface them unattended — a bad workflow edit degrades the signal that would catch it.

The other touched paths do not independently refuse: Cargo.toml is deps_only (satisfied), and src/evaluation/harness.rs, CLAUDE.md, docs/research/deepseek-harness-lessons.md are unlisted.

Relaxation path: any of the following unblocks it —

  1. Split the evaluation.yml change into its own PR and human-review it; the remaining harness + docs changes then classify as path:scoped and get dispatched normally.
  2. A human review approval on this PR — refuse-list gates agent dispatch, not maintainer merge. This PR is MERGEABLE with green checks and can be merged by hand today.
  3. Amend the policy glob to carve out an allowance (separate PR against policy.yaml; this routine never edits policy itself).

No rebase bead was filed for this PR — refuse-list PRs wait on policy or human review, not on coder-loop work.

If the workflow-file constraint should soften for eval-harness CI specifically, reply here and it will be picked up in the next grooming cycle.

…easured 78.2

Review feedback on #1409:
- cubic: the semaphore permit was acquired inside the spawned task, so it
  bounded execution but not spawn fan-out. Acquire before tokio::spawn so at
  most max_concurrency tasks (and their captured clones) exist at once; the
  permit is still held across generate+evaluate. Guard test unchanged and
  passing.
- Codex: BASELINE=75.0 plus the workflow's own -5 rule made 70.0 the blocking
  line. BASELINE is now the measured 78.2 (block <73.2, warn <78.2). The same
  78.2% was reproduced by this PR's CI leg on ubuntu/default features.

Validation: 81 lib tests pass; eval 79/101 (78.2%) unchanged; clippy
-D warnings clean; fmt clean.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfmCW2L5d5qkNJ18mDfz6a
… claim

Review feedback on #1409 (cubic):
- Re-measured: src/evaluation/ is 5,267 LOC (previous 3,285 omitted
  evaluators/); tests/evaluation/src/ is 4,812 LOC across 26 modules
  (not ~6,400 / 20).
- BaselineStore::store() has no caller (no baseline is ever written), but
  load()/compare() are reachable via the --baseline CLI flag, which CI never
  passes. Section 2.5 and row A6 now say exactly that.
- Floor wording follows the workflow: baseline 78.2, block below 73.2.

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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/research/deepseek-harness-lessons.md Outdated
…ope, gate scope

Devil's-advocate pass on the research doc (Gate-4 culture, applied
voluntarily to internal-tooling research):
- Narrative spine reframed: the candidate-ranking flip has two independent
  prerequisites — the pipeline was never wired into AgentLoop (P4) AND the
  eval harness cannot render a verdict (P6a/P6b). Repairing the harness alone
  flips nothing.
- P1: define "replay" as reconstruction, not re-execution (backends are
  non-deterministic); order the three payoffs; offer a narrower P1a
  (SFT + verdict record); default-on gated on the privacy review.
- §4.0: every Tier 2 item ships default-off; flipping to default-on is a
  user-facing change that re-enters the validation-discipline gates.
- §5: tie each rejection to the proposal it constrains; §5.1 states plainly
  that dsh's hot-loading is a TypeScript-runtime affordance and the rejection
  concerns a hypothetical Rust port.

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

Copy link
Copy Markdown
Owner Author

Devil's Advocate Review

Adversarial pass by the devils-advocate agent over docs/research/deepseek-harness-lessons.md (Gate-4 culture, applied voluntarily — this is internal-tooling research, not a feature spec). Transparency note: the agent's default model was rejected by the account's spend limit, so this pass ran on a smaller model with a focused prompt; the earlier Codex/cubic findings were excluded from its scope. Verdict returned: REVISE. Objections below verbatim in substance, with the author's disposition; revisions landed in 59f0d98.

# Objection (severity as rated) Disposition
1 BLOCKING — "dsh claims unverified": asks for dsh's Rust plugin loader and suggests §5.1's dlopen warning is an unverified claim about how dsh works. Rejected as blocking, accepted as a clarity fix. dsh is TypeScript (doc §1.1, Exec Summary); §5.1 argues about a hypothetical Rust port, not about dsh. The dsh claims come from its own README and docs/architecture.md (fetched in-session). §5.1 now states plainly that hot-loading is a TS-runtime affordance and the rejection concerns a Rust translation.
2 SHOULD-FIX — the narrative spine ("flip overdue because the eval harness can't render the verdict") understates that the pipeline was never wired into AgentLoop; harness repair alone flips nothing. Accepted. Blockquote and §2.2 reframed: two independent prerequisites — wire it (P4) and be able to measure it (P6a/P6b).
3 SHOULD-FIX — P1 conflates SFT feed, audit record, and debug transcript; "replayability" is undefined for non-deterministic backends; privacy deferred. Accepted. P1 now orders the three payoffs, defines "replay" as reconstruction (not re-execution), offers a narrower P1a (SFT + verdict record), and gates default-on on the privacy review.
4 SHOULD-FIX — gate allocation inconsistent: if P1/P3 ever ship default-on they are user-facing too, not only P5. Accepted. §4.0 now says every Tier 2 item ships default-off; flipping any to default-on re-enters the validation-discipline gates.
5 NOTE — §5.1/5.2/5.4 read as pre-rebuttal; only §5.3 is load-bearing. Partially accepted. Added a §5 preamble tying each rejection to the proposal it constrains (§5.1/5.2 → P1 closed enum + P3 fixed-order chain; §5.4 → advisor stays a plain backend). Sections kept: they are the reason those designs are closed rather than extensible.
6 NOTE — dsh optimizes for multi-turn agents; doc should weigh whether each lesson matches caro's single-shot problem. Recorded, not changed. §5.4 already frames caro as single-shot; §3's gap table is the per-principle mapping. Will revisit if P5 ever reaches spec.

Reviewer's "weakest assumptions to watch" (kept verbatim for the record): the Rust translation of dsh's plugin model; the P1 privacy story beyond the sanitizer sketch; what replayability delivers with non-deterministic backends; whether P3's monotonic-veto rule stays simple to maintain.

CI status on the current head

  • Evaluate static_matcher: green at the measured 78.2 baseline.
  • cargo-audit / Security Audit: failing on advisory-database updates (two new RUSTSEC entries plus yanked/unsound warnings) against a Cargo.lock this PR does not change (0 lines vs main). This reproduces on the base branch and needs its own dependency-bump PR; not fixed here.
  • Knowledge Integration Tests (ubuntu-latest): one failure, test_lancedb_healthEmbedderInit("Connection reset by peer") while fastembed downloads its model — a runner network reset at setup, unrelated to this diff. Re-running on the new head.

Generated by Claude Code

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread docs/research/deepseek-harness-lessons.md Outdated
…ting claim

cubic re-review on #1409: Appendix B rounded the orphan sub-crate to 4,800 LOC
while A21/P6b say 4,812 — use one figure. The §4.0 sentence claimed every
Tier 2 item ships behind a flag; only P1 does. P2/P3 are behavior-preserving
refactors and P6b is consolidation, so the gating claim now matches the
proposal text.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JfmCW2L5d5qkNJ18mDfz6a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd CI/CD and GitHub Actions dependencies Dependency updates documentation Improvements or additions to documentation path:refuse-list caro-merge-review-integrate dispatcher classification rust Rust source code changes size/M Medium PR (50-200 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants