Skip to content

v4.0.0: pure-Rust restructure — six commands, deploy via scripts - #59

Merged
NOGIT007 merged 25 commits into
mainfrom
feature/v4.0-restructure
May 6, 2026
Merged

NOGIT007 merged 25 commits into
mainfrom
feature/v4.0-restructure

Conversation

@NOGIT007

@NOGIT007 NOGIT007 commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Pure-Rust only (drops TS legacy branches and "if Rust" conditionals)
  • Eight commands collapse to six (/code:start, /code:fix, /code:plan, /code:ship, /code:review, /code:install-ci)
  • /code:plan does grill + PRD + tasks in one extended turn with three on-disk checkpoints; inline anti-slop self-critique before TaskCreate
  • /code:ship runs the audit gate post-merge with one auto-retry on CRITICAL/HIGH findings — bounded self-healing
  • /code:start runs cargo update post-scaffold (non-fatal) so every dep is at its latest semver-compatible patch
  • Deploy & upload must be via scripts/deploy.sh / scripts/upload.sh — wired into just deploy <env> and just upload <kind> <env>. CLAUDE.md template encodes the rule.
  • README cut from 605 to 218 lines; CLAUDE.md cleaned of TS-legacy
  • Doctrine (architecture.md, anti-slop.md, testing.md), hooks, and CI gate are unchanged

Migration

v3.x v4.0
/code:bootstrap /code:start
/code:go /code:fix
/code:grill + /code:prd + /code:plan-issue /code:plan
/code:implement /code:ship
/code:audit just audit (or runs inside /code:ship)
/code:install-ci /code:install-ci
new /code:review

PRD files under plans/YYYY-MM-DD-<slug>.md keep working — /code:plan Phase 3 picks up an existing PRD and jumps straight to task decomposition.

GitHub Actions

The CI workflow uses public actions (actions/checkout, dtolnay/rust-toolchain, Swatinem/rust-cache, taiki-e/install-action, bnjbvr/cargo-machete, rustsec/audit-check, EmbarkStudios/cargo-deny-action). GitHub fetches them automatically — nothing to install. secrets.GITHUB_TOKEN is auto-provided.

Test plan

  • claude --plugin-dir ./code-et-implementer loads all six commands; /code: lists them
  • /code:start <name> scaffolds, runs cargo update, exits clean
  • cd <name> && just audit passes against the bundled fixture
  • cd <name> && just deploy staging aborts at the first # TODO: with a clear message (placeholder discipline works)
  • /code:plan writes plans/<date>-<slug>.md then asks before decomposing tasks
  • /code:ship runs audit after task swarm; auto-retries once on synthetic CRITICAL
  • /code:review runs full audit then delegates to engineering plugin's code-review

🤖 Generated with Claude Code

NOGIT007 and others added 25 commits May 6, 2026 20:46
PRD at plans/2026-05-06-v3.10-audit-command.md decomposes into 9 vertical-slice
tasks at .claude/code-et-tasks.json. T1 corrects PRD spec drift against the
shipped v3.9.0 yaml; T2 ships the foundation (command + yaml-parsed runner +
report writer + Cargo.toml guard + portability) covering 5 PRD stories.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PRD was drafted from CHANGELOG prose and described a 4-stage pipeline
(udeps + clippy dead-code, layer-deps, machete+audit+deny, clippy.toml
thresholds) that does not exist in the merged yaml at
code-et-implementer/templates/shared/.github/workflows/code-et-audit.yml.

Update Solution paragraph, AC-1.1, AC-1.3, AC-4.1, AC-5.1, US-9, AC-9.1,
AC-9.2, Testing Decisions, and Implementation Decisions to reflect the
actual seven shipped stages: fmt, clippy -D warnings, layer-deps
validator, cargo-machete, cargo-audit, cargo-deny, nextest tests.

US-9 reframed from nightly-udeps fallback to generic missing-tool
fallback for cargo-machete / cargo-audit / cargo-deny so its spirit
(graceful degradation) survives but its letter targets the real
toolset.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…iter

Adds a local mirror of the v3.9.0 CI audit gate. The workflow yaml is the
single source of truth — audit-stages.sh parses it at runtime and emits the
seven gate stages in declared order, so CI and local cannot drift. audit.sh
runs each stage from a Rust workspace it locates (target dir, falling back
to the git root), groups failures into a severity-sorted markdown report at
.claude/audit-<UTC>.md, and exits non-zero on any genuine failure. Missing
optional toolchain binaries (cargo-machete, cargo-audit, cargo-deny,
cargo-nextest) skip silently with a stderr notice — T7 will refine this
into formal LOW-severity findings. Workspace guard: no Cargo.toml → exit 0
"not a Rust workspace, skipping" with no report (AC-6.1).

Tests: audit-skips-non-rust.sh covers the workspace-guard path; the parity
test re-parses the yaml with an independent extraction and asserts
audit-stages.sh's output matches step-for-step (AC-8.2). The slice covers
US-1, US-6, US-7, US-8, US-11.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the contract that lets verify-gate (T5) and implement.md (T4) call
audit cheaply on the hot path: --fast runs only fmt+clippy, --stage <n>
runs the n-th stage in declared order. Mutually exclusive. Validation
reads the parsed yaml — no hardcoded count. Bad input prints a usage
message listing every <n>) <name> and exits non-zero.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Refines T1's silent skip into formal LOW-severity findings: when
cargo-machete / cargo-audit / cargo-deny / cargo-nextest is not on PATH,
or scripts/layer-deps-validator.sh is missing from the workspace, the
stage emits a WARNING line on stderr and records a LOW finding through
audit-report.sh's existing pipe. Path slot uses the canonical binary or
script name (e.g. cargo-machete:1) so a grep discriminates skip findings
from real failures. Exit code stays 0 unless another stage actually
fails (AC-9.2). Drive-by: audit-report.sh's printf needs `--` to keep
bash 5.3's builtin from treating `-` format strings as a flag — the bug
was latent in T1 because nothing was emitting findings on the only test
path that exercised it.

Verified by tests/audit-skips-missing-tools.sh — minimal Rust workspace
plus a stub `cargo` shim on a sanitised PATH covers all four cargo-tool
cases and the missing-script case in one deterministic run.

Ticks US-9 in plans/2026-05-06-v3.10-audit-command.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Prepend the highest-severity finding (CRITICAL > HIGH > MEDIUM) as a one-line
summary at the top of the audit report when any non-LOW finding is present,
with a stage-specific remediation hint. Re-echo that line on stderr from the
runner on failure so the worst issue is visible without opening the file.

Also fix `printf` invocation in audit-report.sh emit_group: bash 5.3 builtin
parses the leading `-` of the format string as an option flag, breaking every
non-empty report on macOS. Add `--` separator.

AC-12.1: report's first line matches `^\[(CRITICAL|HIGH|MEDIUM)\] .* — fix:`
when any non-LOW finding is present; LOW-only and clean runs keep the
existing heading as line 1.
AC-12.2: audit.sh re-echoes the writer's first line to stderr on non-zero
exit (no separate ranking — single source of truth lives in the writer).
Adds `--review` to /code:audit. After the seven static stages pass, the
runner detects the engineering plugin via SKILL.md presence and, if found,
captures `git diff <merge-base>..HEAD` into the same `.claude/audit-<UTC>.md`
report under a `## Review` heading — queued for consumption by the plugin's
code-review skill (the audit shell does not invoke the LLM itself).

Detection order: $CLAUDE_PLUGIN_ROOT sibling → ~/.claude/plugins/cache/*
glob → workspace-local override. Absence → exit 1 with `engineering plugin
not installed; run /plugin install engineering to enable --review` on
stderr (AC-5.3). Static-stage failure short-circuits the review wiring so
a failing audit stays actionable without review noise.

Argument parsing rewritten as a flag-tolerant loop so T3's --fast / --stage
can plug in without another rewrite. audit-report.sh gains an optional
--review-file <path> arg; findings still arrive on stdin so the writer's
two inputs stay disjoint. Latent printf bug in the writer (format string
beginning with `-` was being parsed as a flag once any finding existed)
fixed with `printf --`.

Tests sandbox HOME and CLAUDE_PLUGIN_ROOT, build a minimal Cargo.toml
workspace with a two-commit git history, and shrink PATH to a core toolset
so cargo/clippy aren't reachable — every static stage skips cleanly,
isolating the plugin-detection branch under test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
# Conflicts:
#	code-et-implementer/scripts/audit-report.sh
# Conflicts:
#	code-et-implementer/commands/audit.md
#	code-et-implementer/scripts/audit-report.sh
#	code-et-implementer/scripts/audit.sh
#	plans/2026-05-06-v3.10-audit-command.md
Implement.md's chain ended at simplify with no static-analysis pass.
Insert Skill("audit", "--fast") (stages 1-2: fmt + clippy) so style
and lint regressions surface inside the implement loop. The audit
runner already echoes 'audit: report written to <path>' on stderr —
that stderr line is the AC-2.2 surfacing mechanism.

The new test splits chain-halt verification into two phases:
structural grep on implement.md (AC-2.1) plus a regression-fixture
exit-code check that drives audit.sh --fast against a tiny Cargo
workspace whose unused variable trips clippy under -D warnings
(AC-2.2). Phase B skips when cargo is missing so the wiring check
still runs on stripped CI images.
Add .github/workflows/audit-smoke.yml at the repo root: on every PR and
push to main, install the Rust toolchain plus cargo-nextest, cargo-machete,
cargo-audit, cargo-deny via taiki-e/install-action, then run
`bash code-et-implementer/scripts/audit.sh code-et-implementer/templates/rust/dioxus-fullstack`.
Uploads the generated .claude/audit-*.md as an artifact for inspection.

Mirrors the toolchain setup of templates/shared/.github/workflows/code-et-audit.yml
so the fixture doubles as the audit's regression suite — local and CI never drift.
Add a Cargo.toml-guarded audit step to verify-gate.sh so SubagentStop
catches fmt/clippy regressions one step earlier than the implement-chain
hook. Detects repo root via `git rev-parse --show-toplevel`, falls back
to PWD; skips silently on non-Rust trees so the gate stays safe to wire
into shared SubagentStop hooks across all of Kennet's repos.

Two integration tests cover both branches: stub run-tests.sh + audit.sh
shims with sentinel files prove the audit is invoked on Rust workspaces
and not on bare temp dirs.
# Conflicts:
#	plans/2026-05-06-v3.10-audit-command.md
- audit.sh: parse stages once at top, drop STAGE_LIST_FOR_VALIDATE
- audit.sh: capture summary line from writer's stdout instead of re-reading the report file (drops the regex re-validation)
- audit.sh: trim narrating WHAT comments and the duplicate severity table in the docstring (373 → 325 lines)
- audit-report.sh: echo summary line on stdout for callers
Breaking restructure. The plugin is now pure-Rust only and condenses
to six commands. Adds always-latest deps, deploy/upload scripting
discipline, and inline anti-slop self-critique in /code:plan.

Commands (was 8, now 6):
- /code:start    (was /code:bootstrap; runs `cargo update` post-scaffold)
- /code:fix      (was /code:go; Rust-only, no TS conditionals)
- /code:plan     (was /code:grill + /code:prd + /code:plan-issue;
                  one extended turn, three on-disk checkpoints,
                  inline anti-slop self-critique before TaskCreate)
- /code:ship     (was /code:implement; built-in post-merge audit
                  with one auto-retry on CRITICAL/HIGH)
- /code:review   (new; pre-merge gate — full audit + diff review)
- /code:install-ci (unchanged)

Standalone /code:audit removed — runs as `just audit`, the SubagentStop
hook, and inside /code:ship.

Always-latest: /code:start runs `cargo update` post-scaffold (non-fatal).
Caret pins (dioxus 0.7, axum 0.8, sqlx 0.8, tokio 1, tower 0.5) deliver
latest minor/patch. Major bumps are a documented manual `cargo upgrade`.

Deploy & upload via scripts: scripts/deploy.sh + scripts/upload.sh ship
in every scaffolded project, wired into `just deploy <env>` and
`just upload <kind> <env>`. CLAUDE.md template encodes the rule:
never deploy via raw cargo/docker/gcloud commands.

README cut from 605 to 218 lines. CLAUDE.md trimmed of TS-legacy
paragraphs and "if Rust" conditionals — every project follows the
four-crate Clean Architecture.

Doctrine docs (architecture, anti-slop, testing), hooks, and CI gate
yaml are unchanged. The audit pipeline (audit.sh + audit-stages.sh
+ audit-report.sh) is unchanged — still parses the CI yaml at runtime
so local and CI cannot drift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two CI failures from the v4.0 PR's audit-smoke run:

1. Linux runner missing glib-2.0/gtk-3 system libraries — dioxus-desktop's
   wry/webkit2gtk transitive build chain fails to compile without them.
   Add an `apt-get install` step to both workflows (audit-smoke.yml +
   the shipped templates/shared/.../code-et-audit.yml) covering libgtk-3-dev,
   libglib2.0-dev, libsoup-3.0-dev, libjavascriptcoregtk-4.1-dev,
   libwebkit2gtk-4.1-dev. Documented as skippable when --targets excludes
   desktop.

2. cargo-audit CRITICAL on RUSTSEC-2023-0071 (rsa 0.9.x Marvin Attack,
   no fixed upgrade). The crate is pulled in transitively by sqlx-macros
   to support compile-time `query!` checking across all DB backends — but
   we use sqlite + postgres only, so the rsa code is never reached at
   runtime. Ignored in three places (cargo-audit's `--ignore` flag in the
   shipped workflow, deny.toml's [advisories.ignore] for cargo-deny,
   audit.toml for local `cargo audit` invocations) with a long-form
   rationale and a "remove when sqlx-macros decouples mysql" note.

The dioxus-desktop chain also surfaces several `unmaintained` warnings
(gtk-rs 0.18, fxhash, paste, proc-macro-error, etc.). cargo-audit exits
0 on warnings by default — they show up in the report but don't block
the gate. Documented in audit.toml.

Replaces the rustsec/audit-check@v1 GitHub Action with a direct
`run: cargo audit --ignore <ID>` step. The audit-stages.sh parser
already supports `run:` steps verbatim, so the local audit picks up
the same ignore set automatically.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three more failures from the second audit-smoke run on PR #59:

1. Linker error `cannot find -lxdo` — `tray-icon` (transitive via
   dioxus-desktop) needs `libxdo-dev`. Add to apt-get install in both
   workflows alongside the GTK/WebKit packages.

2. cargo-deny rejected three permissive licenses transitively required
   by the dioxus-desktop chain:
     - NCSA          (libfuzzer-sys via image → ravif → rav1e)
     - CDLA-Permissive-2.0  (webpki-roots)
     - BSL-1.0       (xxhash-rust)
   All three are OSI-approved permissive licenses. Added to deny.toml's
   allow list with rationale.

3. cargo-deny rejected `{ workspace = true }` path deps as wildcards.
   `allow-wildcard-paths` does not suppress this for crates that look
   publishable to crates.io (which our workspace members do, since we
   don't set `publish = false`). Downgraded `wildcards = "deny"` to
   "warn" — internal workspace path deps are wildcards by construction;
   real `serde = "*"` slips are caught at review.

Verified locally: `cargo deny check` exits 0 with the new config.
The audit pipeline still enforces the meaningful checks (CDLA/NCSA/BSL
are explicit allowlists with rationale; wildcards still surface as
warnings in the report).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
cargo-deny v2 defaults `unmaintained = "all"`, which errors on every
transitively-pulled unmaintained crate. The dioxus-desktop stack drags
in 10+ unmaintained gtk-rs 0.18 / fxhash crates that we cannot fix
without dioxus migrating upstream.

Set `unmaintained = "workspace"` so cargo-deny only errors if one of
OUR workspace crates (domain/application/infrastructure/interface and
the four apps) becomes unmaintained. Transitive unmaintained advisories
still surface in cargo-audit's report (stage 5) and the CI logs — they
are visible, just no longer merge-blocking.

Also explicitly ignore RUSTSEC-2024-0429 (glib 0.18 unsound) and
RUSTSEC-2026-0097 (rand 0.7 unsound). These came in via the same
dioxus-desktop transitive chain. `unsound` stays at error by default
so any new unsoundness in our own code or non-dioxus deps still fails
the gate.

Verified locally: `cargo deny check` exits 0 with all four checks green
("advisories ok, bans ok, licenses ok, sources ok").

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
cargo-machete flagged unused deps in the dioxus-fullstack template
fixture. Each was either pre-staged for "future use" (slop per v4.0
ethos) or feature-gated. Trimmed to actually-imported deps; added
`# Add when first used: ...` hints in each Cargo.toml so users know
which workspace deps are pinned and ready.

Per crate:
- domain: drop `time`. Hint to re-add when introducing a value object
  that needs DateTime/Duration.
- application: drop `anyhow`. Application errors should be thiserror-
  derived; anyhow rarely belongs in a use case.
- infrastructure: drop `thiserror`, `serde_json`, `tokio`, `tracing`,
  `reqwest`. Kept `anyhow` (used in config.rs's from_env). Hints for
  thiserror/serde_json/tokio/tracing/reqwest cover the common adapter
  expansions.
- interface: drop `async-trait`, `anyhow`, `tracing`. Kept `serde_json`
  (used as `serde_json::to_value` in handlers without a `use`).
  Added `[package.metadata.cargo-machete] ignored = ["tokio", "tower",
  "tower-http"]` for the feature-gated optional deps under the `server`
  feature — cargo-machete does not match feature-flagged deps.
- apps/server: drop `domain`, `application` (composition root currently
  delegates wiring to `interface::http::router`; the deps come back when
  `main.rs` constructs a use case directly).

Verified locally:
  cargo check --workspace          → clean
  cargo machete                    → no unused deps
  cargo deny check                 → advisories ok, bans ok, licenses ok, sources ok
  bash scripts/audit.sh <fixture>  → exit 0 (full pipeline; nextest skipped locally)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@NOGIT007
NOGIT007 merged commit f95bd48 into main May 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant