Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Reusable CI workflows, `mise` task templates and config presets behind a single

Companion repo: **[cmaintz-skills](https://github.com/CMaintz/cmaintz-skills)** — the agent half (skills, hooks). The seam between them is [CONTRACT.md](./CONTRACT.md), which is copied verbatim into both.

> **New here? Read [OVERVIEW.md](./OVERVIEW.md)** — the full narrative tour of how the gates, habit sensors, skills, and the self-improving `learn` loop fit together.
> **New here? Read [OVERVIEW.md](./docs/OVERVIEW.md)** — the full narrative tour of how the gates, habit sensors, skills, and the self-improving `learn` loop fit together.
>
> **[FEATURES.md](./FEATURES.md)** is the canonical inventory of everything Foundry provides — and the backport checklist: anything non-language-specific built in a consumer repo comes back here.
> **[FEATURES.md](./docs/FEATURES.md)** is the canonical inventory of everything Foundry provides — and the backport checklist: anything non-language-specific built in a consumer repo comes back here.

## The idea

Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
| `ratchet-report.yml` | PR comment showing how the accepted-debt baselines moved |
| `autofix.yml` | add an `autofix` label to a PR → runs `mise run fix`, commits + pushes the result |

Split them across `gate.yml` / `quality.yml` / `security.yml` / `bootstrap.yml` (see [OVERVIEW.md](./OVERVIEW.md) §13).
Split them across `gate.yml` / `quality.yml` / `security.yml` / `bootstrap.yml` (see [OVERVIEW.md](./docs/OVERVIEW.md) §13).

### Presets

Expand All @@ -75,16 +75,16 @@ Shared config and agent-facing docs the scaffold copies (or, for the docs, `@`-i
|---|---|
| [`habit-hooks/<stack>.toml`](./presets/habit-hooks/) | structural-smell config per stack — tests excluded, the language-independent `generic` duplication check everywhere ([details](./presets/habit-hooks/README.md)) |
| [`habit-hooks/java/guides/`](./presets/habit-hooks/java/guides/) | per-smell coaching for the Java sensor — concrete "fix toward this", rendered inline in-loop *and* in CI |
| [`pmd/ruleset.xml`](./presets/pmd/) · `pmd/no-var.xml` | tuned Java ruleset (`ExcessiveParameterList` ≥ 8) + the no-`var` rule |
| [`gitleaks.toml`](./presets/gitleaks.toml) · [`renovate.json`](./presets/renovate.json) | secret-scan allowlist starting point + the dependency-update path the "pin everything" rule needs |
| [`code-standards.md`](./presets/code-standards.md) · [`collaboration.md`](./presets/collaboration.md) · [`agent-loop.md`](./presets/agent-loop.md) | agent-facing standing docs — clean code (functions do one thing / SRP), working discipline (branch hygiene + sub-agents), and the self-correcting loop (observe → fix the cause → verify → repeat until green *and* honest) |
| [`ticket-schema.md`](./presets/ticket-schema.md) · [`ISSUE_TEMPLATE/agent-feature.yml`](./presets/ISSUE_TEMPLATE/agent-feature.yml) | the GitHub-Issue ticket the `/feature` driver works — intent, an acceptance-criteria checklist, scope, pointers. Copy the template into a consumer's `.github/ISSUE_TEMPLATE/` |
| [`pmd/ruleset.xml`](./presets/lint/pmd/) · `pmd/no-var.xml` | tuned Java ruleset (`ExcessiveParameterList` ≥ 8) + the no-`var` rule |
| [`gitleaks.toml`](./presets/security/gitleaks.toml) · [`renovate.json`](./presets/renovate.json) | secret-scan allowlist starting point + the dependency-update path the "pin everything" rule needs |
| [`code-standards.md`](./presets/agent/code-standards.md) · [`collaboration.md`](./presets/agent/collaboration.md) · [`agent-loop.md`](./presets/agent/agent-loop.md) | agent-facing standing docs — clean code (functions do one thing / SRP), working discipline (branch hygiene + sub-agents), and the self-correcting loop (observe → fix the cause → verify → repeat until green *and* honest) |
| [`ticket-schema.md`](./presets/tickets/ticket-schema.md) · [`ISSUE_TEMPLATE/agent-feature.yml`](./presets/tickets/ISSUE_TEMPLATE/agent-feature.yml) | the GitHub-Issue ticket the `/feature` driver works — intent, an acceptance-criteria checklist, scope, pointers. Copy the template into a consumer's `.github/ISSUE_TEMPLATE/` |

### From ticket to PR — the `/feature` driver

Foundry answers *"when is a change done?"* — a green gate. The **`/feature`** driver is the thing in front of that — **ticket in, PR out** — the [`feature`](https://github.com/CMaintz/cmaintz-skills) skill in cmaintz-skills, specified in [designs/backlog-feature-driver.md](./designs/backlog-feature-driver.md). Foundry ships the intake it consumes (the schema + issue template above); the driver:
Foundry answers *"when is a change done?"* — a green gate. The **`/feature`** driver is the thing in front of that — **ticket in, PR out** — the [`feature`](https://github.com/CMaintz/cmaintz-skills) skill in cmaintz-skills, specified in [designs/backlog-feature-driver.md](./docs/designs/backlog-feature-driver.md). Foundry ships the intake it consumes (the schema + issue template above); the driver:

1. **Claim** an `agent:ready` ticket — a GitHub Issue on the [`agent-feature`](./presets/ISSUE_TEMPLATE/agent-feature.yml) form ([schema](./presets/ticket-schema.md)) — flipping it to `agent:working` (atomic, WIP = 1) in its own worktree off `origin/main`.
1. **Claim** an `agent:ready` ticket — a GitHub Issue on the [`agent-feature`](./presets/tickets/ISSUE_TEMPLATE/agent-feature.yml) form ([schema](./presets/tickets/ticket-schema.md)) — flipping it to `agent:working` (atomic, WIP = 1) in its own worktree off `origin/main`.
2. **Loop to the gate** — implement → `mise run gate` → act on the failure + habit-hooks coaching → retry, *bounded* (≤ 5 cycles; bail early on no progress, posting the stuck state to the issue thread and flipping `agent:blocked`).
3. **Verify** the result against the ticket's acceptance-criteria checklist — green ≠ correct.
4. **Hand to `/ship`** — which re-gates, runs a fresh-context review against the linked issue, commits, and opens the PR. The driver never opens a PR itself, so there's one trusted path to `main`.
Expand Down Expand Up @@ -118,7 +118,7 @@ Two ideas do most of the work:

The corollary is enforced rather than requested: a PR that changes the ruleset *and* production source fails `ruleset-guard` unless a human labels it `ruleset-change`. Otherwise the cheapest fix for `high-complexity` is `// eslint-disable-next-line`.

Full rationale: [DESIGN.md](./DESIGN.md).
Full rationale: [DESIGN.md](./docs/DESIGN.md).

## Status

Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions OVERVIEW.md → docs/OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A narrative tour of the system: the harness engineering, the gates, the habit
sensors, the skills, and the loop that lets an agent get better at a codebase
over time. If you read one document, read this one.

For the rules themselves see [CONTRACT.md](./CONTRACT.md); for the design
For the rules themselves see [CONTRACT.md](../CONTRACT.md); for the design
rationale and decisions see [DESIGN.md](./DESIGN.md).

---
Expand Down Expand Up @@ -39,7 +39,7 @@ The system is three moving parts, deliberately separated by who consumes them:
us. It's the structural-smell sensor layer, and Foundry borrows its
tool-independent smell vocabulary as a backbone.

The seam between `foundry` and `cmaintz-skills` is [CONTRACT.md](./CONTRACT.md),
The seam between `foundry` and `cmaintz-skills` is [CONTRACT.md](../CONTRACT.md),
copied verbatim into both. If those two copies ever need to differ, the split
was wrong.

Expand Down
2 changes: 1 addition & 1 deletion docs/build-cast.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const steps = [
[0.6, ' lint ' + ok + '\r\n'],
[0.5, ' typecheck ' + ok + '\r\n'],
[0.6, ' test ' + ok + dim(' 142 passed . coverage 91%') + '\r\n'],
[0.6, ' audit ' + ok + dim(' 0 criticals . secrets clean') + '\r\n'],
[0.6, ' audit ' + ok + dim(' 0 critical . secrets clean') + '\r\n'],
[0.9, ' ' + badge + dim(' nothing merges without this') + '\r\n'],
[1.3, '\r\n' + dim('# linters, types, tests & scanners hold sole authority — the LLM only proposes.') + '\r\n'],
[1.4, ' '],
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ preset artifacts in `foundry`. So:
| Artifact | Repo | Path |
|---|---|---|
| The `/feature` driver skill | `cmaintz-skills` | `skills/feature/SKILL.md` (+ helpers) |
| GitHub issue template | `foundry` | `presets/ISSUE_TEMPLATE/agent-feature.yml` |
| Ticket schema (reference) | `foundry` | `presets/ticket-schema.md` |
| GitHub issue template | `foundry` | `presets/tickets/ISSUE_TEMPLATE/agent-feature.yml` |
| Ticket schema (reference) | `foundry` | `presets/tickets/ticket-schema.md` |
| Inventory entry | `foundry` | `FEATURES.md` (same session) |

Adding a skill is **additive** under CONTRACT versioning — no major bump.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
**Home:** foundry (per-`mise` template) · **Placement weight:** shift-left (local only)

**Implemented:** `mise/ts.toml` — `lint` + `test` honour `FOUNDRY_SINCE` (validated
across unset / valid-ref / empty / unresolvable-ref); `presets/agent-loop.md` documents
across unset / valid-ref / empty / unresolvable-ref); `presets/agent/agent-loop.md` documents
the activation (fast scoped inner-loop runs, whole-tree final gate); `mise/java.toml` —
honest "Gradle already scopes it" note, `novar` folded into `lint` and made
ratchet-scoped via `FOUNDRY_BASE_REF`; reusable `java.yml` — separate `no-var` job +
Expand Down
2 changes: 1 addition & 1 deletion designs/flake-triager.md → docs/designs/flake-triager.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ post-processes a test report (JUnit XML *and* vitest JSON) against `flaky-baseli
and fails only if a NON-quarantined test failed (quarantined flakes are printed, never
hidden); `classify` mode reruns failed tests N times to separate flakes (flip) from real
failures (always fail) and surfaces prune candidates (quarantined-but-now-stable). Both
modes tested across formats + quarantined/real/no-baseline cases. `presets/flaky-baseline.example.json`
modes tested across formats + quarantined/real/no-baseline cases. `presets/baselines/flaky-baseline.example.json`
(schema); baseline reuses the guard's `snooze` kind — verified add=loosening (needs
label), remove=tightening (free), no new guard code. `mise/ts.toml` gains an opt-in
`test:flaky` integration task. **Not yet:** live rerun on a real runner (no JVM/node
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/gate-demo.cast
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[1.9,"o"," lint \u001b[1;32mok\u001b[0m\r\n"]
[2.4,"o"," typecheck \u001b[1;32mok\u001b[0m\r\n"]
[3,"o"," test \u001b[1;32mok\u001b[0m\u001b[90m 142 passed . coverage 91%\u001b[0m\r\n"]
[3.6,"o"," audit \u001b[1;32mok\u001b[0m\u001b[90m 0 criticals . secrets clean\u001b[0m\r\n"]
[3.6,"o"," audit \u001b[1;32mok\u001b[0m\u001b[90m 0 critical . secrets clean\u001b[0m\r\n"]
[4.5,"o"," \u001b[1;42m GATE GREEN \u001b[0m\u001b[90m nothing merges without this\u001b[0m\r\n"]
[5.8,"o","\r\n\u001b[90m# linters, types, tests & scanners hold sole authority — the LLM only proposes.\u001b[0m\r\n"]
[7.2,"o"," "]
Loading
Loading