Skip to content

Commit 3d012ea

Browse files
chore: scheduled maintenance — loop-gate release, story, version bumps (#311)
loop-gate release path, loop-worktree story (#229), loop-audit 1.6.1 + mcp-server 1.1.0 bumps.
1 parent eaf89e9 commit 3d012ea

7 files changed

Lines changed: 173 additions & 9 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Release loop-gate
2+
3+
on:
4+
push:
5+
tags:
6+
- 'loop-gate-v*'
7+
workflow_dispatch:
8+
inputs:
9+
tag:
10+
description: 'Tag to publish (e.g. loop-gate-v1.0.0)'
11+
required: true
12+
type: string
13+
14+
permissions:
15+
contents: read
16+
id-token: write
17+
18+
jobs:
19+
test-and-publish:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v7
23+
with:
24+
ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', github.event.inputs.tag) || github.ref }}
25+
26+
- uses: actions/setup-node@v7
27+
with:
28+
node-version: '22'
29+
registry-url: 'https://registry.npmjs.org'
30+
cache: 'npm'
31+
cache-dependency-path: tools/loop-gate/package-lock.json
32+
33+
- name: Ensure npm supports trusted publishing (OIDC)
34+
run: npm install -g npm@latest
35+
36+
- name: Install, build, test
37+
working-directory: tools/loop-gate
38+
run: |
39+
npm ci
40+
npm run build
41+
npm test
42+
43+
- name: Skip if version already published
44+
id: check
45+
working-directory: tools/loop-gate
46+
run: |
47+
VERSION=$(node -p "require('./package.json').version")
48+
if npm view "@cobusgreyling/loop-gate@${VERSION}" version 2>/dev/null; then
49+
echo "Version ${VERSION} already on npm — skipping publish."
50+
echo "skip=true" >> "$GITHUB_OUTPUT"
51+
else
52+
echo "Publishing @cobusgreyling/loop-gate@${VERSION}"
53+
echo "skip=false" >> "$GITHUB_OUTPUT"
54+
fi
55+
env:
56+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
57+
58+
- name: Publish to npm
59+
if: steps.check.outputs.skip != 'true'
60+
working-directory: tools/loop-gate
61+
run: npm publish --access public --provenance
62+
env:
63+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

‎STATE.md‎

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
# Loop State — loop-engineering reference
22

3-
Last run: 2026-07-17T09:41:37Z (automated daily-triage workflow)
3+
Last run: 2026-07-19T18:55:00Z (scheduled maintenance)
44

55
## High Priority (loop is acting or waiting on human)
66

77
- Maintain loop readiness score ≥ 58 (current: **100**, level **L3**).
8-
- Keep npm packages current after tool changes (tag `loop-audit-v*`, `loop-init-v*`, `loop-cost-v*` — see docs/RELEASE.md).
9-
8+
- npm publish in flight after this run: `loop-gate` 1.0.0, `loop-audit` 1.6.1, `loop-mcp-server` 1.1.0 (tags after merge).
9+
- Configure npm trusted publisher / `NPM_TOKEN` for `@cobusgreyling/loop-gate` if first publish fails.
1010

1111
## Watch List
1212

1313
- Expand contributor failure stories (dependency sweeper, multi-loop).
1414
- Collect a production story for Post-Merge Cleanup.
15+
- Remaining Cursor doc gaps: [#220](https://github.com/cobusgreyling/loop-engineering/issues/220), [#223](https://github.com/cobusgreyling/loop-engineering/issues/223), [#224](https://github.com/cobusgreyling/loop-engineering/issues/224).
1516
- Validate `loop-init` scaffolds on fresh projects across all patterns.
17+
- Optional: StackMap outreach [#300](https://github.com/cobusgreyling/loop-engineering/issues/300).
18+
19+
## Housekeeping (2026-07-19 maintenance)
20+
21+
- Merged [#307](https://github.com/cobusgreyling/loop-engineering/pull/307) (Devin appendix → closes #200), [#302](https://github.com/cobusgreyling/loop-engineering/pull/302) (starter loop-gate), [#303](https://github.com/cobusgreyling/loop-engineering/pull/303) (MCP loop-gate), [#308](https://github.com/cobusgreyling/loop-engineering/pull/308) (audit/MCP cost fixes).
22+
- Landed `release-loop-gate.yml` + RELEASE.md docs (supersedes conflicted [#305](https://github.com/cobusgreyling/loop-engineering/pull/305)).
23+
- Landed loop-worktree week-two story from [#299](https://github.com/cobusgreyling/loop-engineering/pull/299) (story only; matrix noise dropped).
24+
- Closed draft [#304](https://github.com/cobusgreyling/loop-engineering/pull/304) as superseded.
25+
- Pruned automated star-history / daily-triage remote branches.
1626

1727
## Recent Noise (ignored this run)
1828

19-
—
29+
- Star-history automation PRs (#309, #310) already merged.
30+
- StackMap marketing issue #300.
2031

2132
---
22-
Run log: Updated by `.github/workflows/daily-triage.yml`. See `LOOP.md` for cadence and gates.
33+
Run log: Updated by `.github/workflows/daily-triage.yml`. See `LOOP.md` for cadence and gates.

‎docs/RELEASE.md‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Release playbook — npm packages
22

3-
This repo ships eight public npm packages from `tools/`:
3+
This repo ships nine public npm packages from `tools/`:
44

55
| Package | Directory | Release tag |
66
|---------|-----------|-------------|
@@ -11,6 +11,7 @@ This repo ships eight public npm packages from `tools/`:
1111
| `@cobusgreyling/loop-context` | `tools/loop-context` | `loop-context-v*` |
1212
| `@cobusgreyling/loop-mcp-server` | `tools/mcp-server` | `loop-mcp-server-v*` |
1313
| `@cobusgreyling/loop-worktree` | `tools/loop-worktree` | `loop-worktree-v*` |
14+
| `@cobusgreyling/loop-gate` | `tools/loop-gate` | `loop-gate-v*` |
1415
| `@cobusgreyling/goal-audit` | `tools/goal-audit` | `goal-audit-v*` |
1516

1617
## One-time setup (trusted publishing — recommended)
@@ -26,6 +27,7 @@ Link npm to GitHub, then for **each package** on [npmjs.com](https://www.npmjs.c
2627
| `@cobusgreyling/loop-context` | `cobusgreyling/loop-engineering` | `release-loop-context.yml` |
2728
| `@cobusgreyling/loop-mcp-server` | `cobusgreyling/loop-engineering` | `release-loop-mcp-server.yml` |
2829
| `@cobusgreyling/loop-worktree` | `cobusgreyling/loop-engineering` | `release-loop-worktree.yml` |
30+
| `@cobusgreyling/loop-gate` | `cobusgreyling/loop-engineering` | `release-loop-gate.yml` |
2931
| `@cobusgreyling/goal-audit` | `cobusgreyling/loop-engineering` | `release-goal-audit.yml` |
3032

3133
Names must match **exactly** (case-sensitive). No `NPM_TOKEN` secret is required when trusted publishing is configured.
@@ -73,12 +75,16 @@ git push origin loop-mcp-server-v1.0.0
7375
git tag loop-worktree-v1.0.0
7476
git push origin loop-worktree-v1.0.0
7577

78+
# loop-gate (path denylist + auto-merge allowlist)
79+
git tag loop-gate-v1.0.0
80+
git push origin loop-gate-v1.0.0
81+
7682
# goal-audit (Goal Engineering readiness scorer — companion repo)
7783
git tag goal-audit-v1.0.2
7884
git push origin goal-audit-v1.0.2
7985
```
8086

81-
Workflows: `.github/workflows/release-loop-audit.yml`, `.github/workflows/release-loop-init.yml`, `.github/workflows/release-loop-cost.yml`, `.github/workflows/release-loop-sync.yml`, `.github/workflows/release-loop-context.yml`, `.github/workflows/release-loop-mcp-server.yml`, `.github/workflows/release-loop-worktree.yml`, `.github/workflows/release-goal-audit.yml`.
87+
Workflows: `.github/workflows/release-loop-audit.yml`, `.github/workflows/release-loop-init.yml`, `.github/workflows/release-loop-cost.yml`, `.github/workflows/release-loop-sync.yml`, `.github/workflows/release-loop-context.yml`, `.github/workflows/release-loop-mcp-server.yml`, `.github/workflows/release-loop-worktree.yml`, `.github/workflows/release-loop-gate.yml`, `.github/workflows/release-goal-audit.yml`.
8288

8389
## Verify after publish
8490

‎stories/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Real-world loop engineering — including failures. Contribute yours via [CONTRI
1616
| [quant-loop-the-verifier-problem.md](./quant-loop-the-verifier-problem.md) | Quant research (domain) | Numerical checker beats LLM-as-verifier for backtests |
1717
| [quant-loop-out-of-time.md](./quant-loop-out-of-time.md) | Quant research (domain) | Strategy passed research, failed out-of-time data |
1818
| [ky-cut-surface-generation-vs-consequence.md](./ky-cut-surface-generation-vs-consequence.md) | Philosophy → loop bridge | Generation ≠ consequence; preserve the cut surface |
19+
| [loop-worktree-week-two.md](./loop-worktree-week-two.md) | PR Babysitter + loop-worktree | Pair worktrees with `loop-context --check`; exact `outcome: failure` enum |
1920

2021
**Template for new stories:**
2122

‎stories/loop-worktree-week-two.md‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Week Two with loop-worktree: PR Babysitter, one fix at a time
2+
3+
**Pattern:** PR Babysitter
4+
**Tool:** loop-worktree (paired with loop-context)
5+
6+
## What I was doing
7+
8+
I was running a small PR Babysitter loop: watch a PR, try a fix in isolation,
9+
verify it, and only escalate to a human if the fix doesn't land. The part I
10+
wanted to get right this week was making retries safe — if attempt #1 fails,
11+
attempt #2 shouldn't be fighting attempt #1 for the same branch.
12+
13+
## The workflow
14+
15+
For each fix attempt, I create an isolated worktree keyed to the run:
16+
17+
```
18+
npx @cobusgreyling/loop-worktree create --run-id pr-42-fix-1 --pattern pr-babysitter
19+
```
20+
21+
That gives me a fresh checkout under `.loop-worktrees/pr-42-fix-1` on its own
22+
branch (`loop/pr-42-fix-1`), tracked in `.loop-worktrees/manifest.json` — so
23+
nothing touches the branch another attempt might still be using.
24+
25+
Once the verifier rejects an attempt, I mark it rather than deleting it
26+
immediately — that keeps the audit trail intact:
27+
28+
```
29+
npx @cobusgreyling/loop-worktree mark --run-id pr-42-fix-1 --status rejected
30+
```
31+
32+
`list` gives me a quick read on what's currently tracked:
33+
34+
```
35+
npx @cobusgreyling/loop-worktree list
36+
```
37+
38+
And periodically I sweep anything rejected or escalated:
39+
40+
```
41+
npx @cobusgreyling/loop-worktree cleanup --status rejected --older-than 24h
42+
```
43+
44+
## Pairing with loop-context --check
45+
46+
Before letting the loop retry again, I run the ledger through
47+
`loop-context --check` so a stuck fix doesn't just keep burning attempts:
48+
49+
```
50+
npx @cobusgreyling/loop-context --check --ledger run.json --stagnation 3 --json
51+
```
52+
53+
With three identical failures in a row it stayed green (`shouldContinue: true`),
54+
but on the fourth repeat of the same error it correctly flipped to
55+
`escalate: true` with exit code 2 — which is the signal I use to stop the loop
56+
and hand the PR back to a human instead of trying a fifth time.
57+
58+
## The surprise
59+
60+
The gotcha that cost me the most time: `--check`'s stagnation trigger only
61+
recognizes attempts with `"outcome": "failure"` exactly. I'd first logged
62+
attempts as `"outcome": "fail"` — `--summary` and `--status` happily counted
63+
those as failures and showed the repeated error, so everything *looked*
64+
right, but `--check` never escalated no matter how many times the same error
65+
repeated. Nothing errors out to tell you the value was wrong; the breaker
66+
just quietly stays at "continue." Since the whole point of pairing
67+
loop-worktree with loop-context is to stop a bad retry loop before it wastes
68+
a worktree (and tokens) on a fix that isn't working, a silently-inert circuit
69+
breaker is exactly the failure mode you don't want.
70+
71+
Separately, a smaller but good surprise: `cleanup --older-than 24h` refused
72+
to remove a worktree I'd just marked rejected seconds earlier — it only acts
73+
once the attempt is actually old enough (or you pass `--force`). That's the
74+
right default; I just didn't expect it on first try and thought the command
75+
had silently no-op'd.
76+
77+
## What I'd change
78+
79+
I'd want `--check` to validate the `outcome` field against the documented
80+
enum and fail loudly (or at least warn) on an unrecognized value, instead of
81+
silently treating it as a no-op for the stagnation/no-progress triggers while
82+
`--summary` keeps counting it as a failure. Right now the two commands can
83+
disagree about the same ledger without telling you.

‎tools/loop-audit/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@cobusgreyling/loop-audit",
3-
"version": "1.6.0",
3+
"version": "1.6.1",
44
"description": "Loop engineering readiness auditor. Compute Loop Readiness Score (L0-L3), detect activity, and get actionable suggestions. npx @cobusgreyling/loop-audit . --suggest",
55
"type": "module",
66
"bin": {

‎tools/mcp-server/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@cobusgreyling/loop-mcp-server",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "MCP server for loop-engineering — exposes patterns, skills, state, and audit tools as runtime-queryable resources for AI agents",
55
"type": "module",
66
"bin": {

0 commit comments

Comments
 (0)