Skip to content
Closed
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
9 changes: 8 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ updates:
open-pull-requests-limit: 3
commit-message:
prefix: "chore(audit)"
- package-ecosystem: "npm"
directory: "/tools/loop-init"
schedule:
interval: "weekly"
open-pull-requests-limit: 3
commit-message:
prefix: "chore(loop-init)"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
interval: "weekly"
34 changes: 22 additions & 12 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ on:
pull_request:
branches: [main]
schedule:
# Daily-ish dogfood of the reference itself
- cron: '17 9 * * *'

jobs:
Expand All @@ -31,33 +30,44 @@ jobs:
npm ci
npm test
echo "=== Audit of repo root ==="
node dist/cli.js ../../ || true
node dist/cli.js ../../ --json > /tmp/root-audit.json
echo ""
echo "=== Audit of starters ==="
echo "=== Audit of starters (L1 gate) ==="
FAILED=0
for s in ../../starters/*/; do
echo "--- $(basename "$s") ---"
node dist/cli.js "$s" || true
NAME=$(basename "$s")
node dist/cli.js "$s" --json > "/tmp/starter-${NAME}.json"
node -e "
const data = JSON.parse(require('fs').readFileSync('/tmp/starter-${NAME}.json', 'utf8'));
console.log('--- ${NAME}: score=' + data.score + ' level=' + data.level);
if (data.score < 38) {
console.error('Starter ${NAME} below L1 threshold (38): ' + data.score);
process.exit(1);
}
" || FAILED=1
done
if [ "$FAILED" -ne 0 ]; then
echo "One or more starters failed L1 gate"
exit 1
fi
cp /tmp/root-audit.json /tmp/audit.json

- name: Report score and gate on critically low (reference is source, not a consumer project)
run: |
cd tools/loop-audit
node dist/cli.js ../../ --json > /tmp/audit.json || true
SCORE=$(node -e '
node -e '
const fs = require("fs");
try {
const data = JSON.parse(fs.readFileSync("/tmp/audit.json", "utf8"));
console.log("Reference score: " + data.score);
// Reference repo dogfoods L2: STATE.md, skills/, AGENTS.md, LOOP.md gates.
if (data.score < 58) {
console.error("Reference score below L2 threshold (58). Restore dogfood signals: STATE.md, skills/, AGENTS.md.");
process.exit(2);
}
} catch (e) {
console.error("Could not parse audit JSON:", e.message);
process.exit(0); // do not fail the whole job on parse issues
process.exit(1);
}
')
'

- name: Comment PR with loop readiness score
if: github.event_name == 'pull_request'
Expand Down Expand Up @@ -89,4 +99,4 @@ jobs:
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
});
86 changes: 86 additions & 0 deletions .github/workflows/changelog-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Changelog Drafter (dogfood)

on:
schedule:
- cron: '30 18 * * 1'
workflow_dispatch:

permissions:
contents: read
issues: write

jobs:
draft:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Summarize release window
id: window
run: |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none")
SINCE=$(git log -1 --format=%ci "${LAST_TAG}" 2>/dev/null || git log -1 --format=%ci)
echo "last_tag=${LAST_TAG}" >> "$GITHUB_OUTPUT"
echo "since=${SINCE}" >> "$GITHUB_OUTPUT"
git log --oneline "${LAST_TAG}..HEAD" 2>/dev/null | head -30 || git log --oneline -15

- name: Open or update release-prep issue (L1 — human drafts notes)
uses: actions/github-script@v9
with:
script: |
const title = `Release prep — week of ${new Date().toISOString().slice(0, 10)}`;
const body = [
'## Changelog drafter (L1 dogfood)',
'',
'Automated scan surface for release notes. **Human reviews and edits before any publish.**',
'',
`- Last tag: \`${{ steps.window.outputs.last_tag }}\``,
`- Window since: ${{ steps.window.outputs.since }}`,
'',
'### Next steps',
'1. Run the changelog-drafter starter skills locally or in your agent TUI.',
'2. Produce `RELEASE_NOTES_DRAFT.md` from merges since the last tag.',
'3. Update `changelog-drafter-state.md` when the draft is ready.',
'',
'Pattern: [changelog-drafter.md](https://github.com/cobusgreyling/loop-engineering/blob/main/patterns/changelog-drafter.md)',
'',
'_Generated by `.github/workflows/changelog-drafter.yml` — report-only, no auto-publish._',
].join('\n');

const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'release-prep',
state: 'open',
per_page: 1,
});

if (issues.length) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issues[0].number,
body: `### Weekly scan refresh\n\n${body}`,
});
return;
}

try {
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'release-prep',
color: '3ee8c5',
description: 'Release notes draft tracking (changelog-drafter L1)',
});
} catch (_) {}

await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title,
labels: ['release-prep'],
body,
});
6 changes: 3 additions & 3 deletions .github/workflows/daily-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ jobs:
## High Priority (loop is acting or waiting on human)

- Maintain loop readiness score ≥ 58 (current: **${SCORE}**, level **${LEVEL}**).
- Publish \`@cobusgreyling/loop-audit\` to npm if not yet live (enables \`npx\` installs).
- Publish \`@cobusgreyling/loop-audit\` and \`@cobusgreyling/loop-init\` to npm when \`NPM_TOKEN\` is configured (see docs/RELEASE.md).
$([ "$FAILING" -gt 0 ] && echo "- **${FAILING}** dogfood workflow(s) failing — investigate CI.")

## Watch List

- Expand contributor failure stories (dependency sweeper, multi-loop).
- Complete Claude Code / Codex starters for all L2 patterns.
- Run \`loop-init\` on a fresh project and verify scaffold output.
- Collect a production story for Post-Merge Cleanup.
- Validate \`loop-init\` scaffolds on fresh projects across all patterns.

## Recent Noise (ignored this run)

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release-loop-init.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ jobs:
node-version: '22'
registry-url: 'https://registry.npmjs.org'

- name: Build & publish
- name: Test, build & publish
working-directory: tools/loop-init
run: |
npm install
npm run build
npm ci
npm test
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
17 changes: 15 additions & 2 deletions .github/workflows/validate-patterns.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ jobs:
steps:
- uses: actions/checkout@v6

- uses: actions/setup-node@v6
with:
node-version: '22'

- name: Check registry covers all pattern files
run: |
set -e
Expand Down Expand Up @@ -44,7 +48,16 @@ jobs:
test -f templates/loop-budget.md.template || (echo "Missing loop-budget template"; exit 1)
echo "Templates present ✓"

- name: Validate registry.yaml schema
- name: Validate registry.yaml schema and starter paths
run: |
npm install --no-save yaml@2
npm install --no-save yaml@2 ajv@8
node scripts/validate-registry.mjs

- name: Verify loop-init pattern sync
run: node scripts/check-loop-init-sync.mjs

- name: Smoke test loop-init package layout
run: |
cd tools/loop-init
npm ci
npm test
8 changes: 8 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Default owner for review routing (solo maintainer today).
* @cobusgreyling

/patterns/ @cobusgreyling
/tools/ @cobusgreyling
/.github/ @cobusgreyling
/docs/ @cobusgreyling
/starters/ @cobusgreyling
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@

<p align="center">
<img src="assets/cobus-greyling.jpg" alt="Cobus Greyling" />
<br>
</p>

</p>



**Loop engineering is replacing yourself as the person who prompts the agent. You design the system that does it instead.**

A loop is a recursive goal: you define a purpose and the AI iterates (often with sub-agents, verification, and external state) until the goal is complete or the loop decides to hand off to you.
Expand Down Expand Up @@ -132,6 +127,13 @@ bash scripts/before-after-demo.sh
/loop 1d Run loop-triage. Update STATE.md. No auto-fix in week one.
```

Packages publish from tagged releases — see [docs/RELEASE.md](docs/RELEASE.md). Until npm is live, run from this repo:

```bash
cd tools/loop-init && npm ci && npm test && node dist/cli.js /path/to/project --pattern daily-triage --tool grok
cd tools/loop-audit && npm ci && npm test && node dist/cli.js /path/to/project --suggest
```

Phased rollout: **L1 report → L2 assisted fixes → L3 unattended** — see [loop-design-checklist](docs/loop-design-checklist.md).

## Examples by Tool
Expand Down Expand Up @@ -166,7 +168,7 @@ Addy Osmani:

## Contributing

Share production patterns, tool mappings, and failure stories. See [CONTRIBUTING.md](CONTRIBUTING.md).
Share production patterns, tool mappings, and failure stories. See [CONTRIBUTING.md](CONTRIBUTING.md) and [GitHub Discussions](https://github.com/cobusgreyling/loop-engineering/discussions).

## Sources

Expand Down
5 changes: 4 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ Loop engineering runs unattended automation against your codebase. Treat loops l

## Reporting vulnerabilities

Email security concerns privately if you discover issues in this reference repo or in `loop-audit` / `loop-init` tooling. Do not open public issues for exploitable vulnerabilities.
Report security issues **privately** — do not open public issues for exploitable vulnerabilities.

- **Preferred:** [GitHub private vulnerability reporting](https://github.com/cobusgreyling/loop-engineering/security/advisories/new)
- **Email:** security@cobusgreyling.me (PGP on request)

For general loop safety guidance, see [docs/safety.md](docs/safety.md).

Expand Down
13 changes: 6 additions & 7 deletions STATE.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
# Loop State — loop-engineering reference

Last run: 2026-06-09T10:49:32Z (automated daily-triage workflow)
Last run: 2026-06-09T13:45:00Z (manual improvement batch)

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

- Maintain loop readiness score ≥ 58 (current: **100**, level **L3**).
- Publish `@cobusgreyling/loop-audit` to npm if not yet live (enables `npx` installs).

- Add `NPM_TOKEN` repo secret and publish `@cobusgreyling/loop-audit` + `@cobusgreyling/loop-init` (see [docs/RELEASE.md](docs/RELEASE.md)).

## Watch List

- Expand contributor failure stories (dependency sweeper, multi-loop) beyond the six in `stories/`.
- Complete Claude Code / Codex starters for all L2 patterns.
- Validate `loop-init` scaffolds on fresh projects across all patterns (including changelog-drafter).
- Expand contributor failure stories (dependency sweeper, multi-loop) beyond stories in `stories/`.
- Collect a production story for Post-Merge Cleanup.
- Monitor starter L1 gates in `audit.yml` after the loop-init packaging fix.

## Recent Noise (ignored this run)


---
Run log: Updated by `.github/workflows/daily-triage.yml`. See `LOOP.md` for cadence and gates.
Run log: Updated by `.github/workflows/daily-triage.yml`. See `LOOP.md` for cadence and gates.
8 changes: 4 additions & 4 deletions docs/GITHUB_PAGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
3. **Folder**: `/docs`
4. Save — showcase at `https://cobusgreyling.github.io/loop-engineering/`

The homepage (`docs/index.md`) is the full interactive showcase with patterns, primitives, quick-start, and an anatomy diagram.
The homepage (`docs/index.html`) is the full interactive showcase with patterns, primitives, quick-start, and an anatomy diagram.

The root `README.md` and `LOOP.md` now describe how this reference dogfoods its own patterns via `.github/workflows/audit.yml` + `validate-patterns.yml`.
The root `README.md` and `LOOP.md` describe how this reference dogfoods its own patterns via `.github/workflows/audit.yml` + `validate-patterns.yml`.

First deploy may take 1–2 minutes. After enabling, the daily scheduled audit workflow will also keep the published site "honest" about the reference's own loop readiness.
First deploy may take 1–2 minutes. After enabling, the daily scheduled audit workflow keeps the published site aligned with the reference's loop readiness score.

**Pro tip**: once live, run `node tools/loop-audit/dist/cli.js . --suggest` locally and improve the score over time — the workflows will reflect it.
**Pro tip**: run `node tools/loop-audit/dist/cli.js . --suggest` locally and improve the score over time — the workflows will reflect it.
51 changes: 51 additions & 0 deletions docs/RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Release playbook — npm packages

This repo ships two public npm packages from `tools/`:

| Package | Directory | Release tag |
|---------|-----------|-------------|
| `@cobusgreyling/loop-audit` | `tools/loop-audit` | `loop-audit-v*` |
| `@cobusgreyling/loop-init` | `tools/loop-init` | `loop-init-v*` |

## One-time setup

1. Create an npm org/user scope `@cobusgreyling` on [npmjs.com](https://www.npmjs.com/).
2. Generate an npm **Automation** or **Publish** token.
3. Add it to the repo as **`NPM_TOKEN`** (Settings → Secrets → Actions).

## Version bump

Edit `version` in the package `package.json`, update that package's `CHANGELOG.md` if present, and commit to `main` via PR.

## Publish

Tag pushes trigger the release workflows:

```bash
# loop-audit (runs tests before publish)
git tag loop-audit-v1.3.0
git push origin loop-audit-v1.3.0

# loop-init (bundles starters/templates, runs smoke tests)
git tag loop-init-v1.1.0
git push origin loop-init-v1.1.0
```

Workflows: `.github/workflows/release-loop-audit.yml`, `.github/workflows/release-loop-init.yml`.

## Verify after publish

```bash
npx @cobusgreyling/loop-audit --help
npx @cobusgreyling/loop-init --help

mkdir /tmp/loop-init-test && cd /tmp/loop-init-test
npx @cobusgreyling/loop-init . --pattern daily-triage --tool grok --dry-run
```

## Before npm is live (local / monorepo)

```bash
cd tools/loop-audit && npm ci && npm test && node dist/cli.js ../.. --suggest
cd tools/loop-init && npm ci && npm test && node dist/cli.js /tmp/target --pattern daily-triage --dry-run
```
Loading