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
39 changes: 36 additions & 3 deletions .agents/skills/ione-backlog/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,43 @@
---
name: ione-backlog
description: Implement one human-approved IONe federation or reliability issue with Postgres-backed verification and an unmerged PR. Use for the scheduled IONe backlog loop or an explicitly selected backlog-ready issue.
description: Carry one IONe issue from backlog-ready to merged — failing test, smallest safe change, verified PR, green CI, squash merge. Use for the scheduled IONe backlog loop or an explicitly selected backlog-ready issue.
---

# IONe backlog

Require `backlog-ready`, non-red `main`, no open `automation-pr`, and an isolated worktree. Process one issue. TerraYield federation changes require a matching `eo_ag` issue with the same versioned interface, auth, error, and compatibility contract.
This loop merges. No human reads the diff before it lands on `main`, so the verification below is the only thing standing between a bad change and the default branch. Treat a gate you cannot run as a reason to stop, never as a reason to proceed.

Add a failing contract test, implement the smallest safe change, run focused Rust tests, then migrated Postgres-backed ignored tests serially when persistence or federation is involved. Run Playwright for static UI or browser contracts. Open a PR labeled `automation-pr` with provenance, `Closes #N`, exact verification, risks, and unrun external gates. Stop before merge or deployment.
## Pick the run's work

Evaluate everything against remote state after `git fetch origin`.

1. **An open `automation-pr` already exists** — that is this run's work. Do not open a second one. Drive it to green and merge it, then stop. A prior run's stalled PR blocks the queue, and unblocking it matters more than starting something new.
2. **Otherwise** — take the oldest open issue carrying `backlog-ready` and not carrying `needs-human-auth`. `backlog-ready` counts as approval whether Ryan applied it or the `auto-backlog-ready` workflow promoted it from `bug-candidate` or `research-candidate`. `needs-human-auth` is Ryan's manual hold; nothing else applies it.
3. **`main` CI is red** — fixing `main` is the run's work. Do not layer a feature on a broken base.
4. **Nothing matches** — stop and say so. A no-op run is a fine outcome.

One issue per run. TerraYield federation changes require a matching `eo_ag` issue carrying the same versioned interface, auth, error, and compatibility contract; if it does not exist, stop and say so rather than changing one side of a wire contract alone.

## Build it

Write a failing contract test first, then the smallest safe change that passes it. Never edit an already-applied migration — a checksum break took down all 57 suites once, which is what issue #31 exists to prevent.

## Verify

Run the gates the change actually touches, and run them before the PR, not after:

- always: `cargo fmt --all -- --check`, `cargo clippy --all-targets -- -D warnings`, `cargo test --lib --bins`, `cargo test --test phase01_chat`
- persistence or federation: `docker compose up -d postgres minio`, `cargo sqlx migrate run`, then each relevant suite as `DATABASE_URL=postgres://ione:ione@localhost:5433/ione IONE_SKIP_LIVE=1 cargo test --test <suite> -- --include-ignored --test-threads=1`
- static UI or browser contract: `npm run test:e2e`

If the runner cannot start Postgres, MinIO, or a browser, say which gates did not run and why. CI runs the full matrix on the PR — let it be the first place they execute, and treat its verdict as binding.

## Land it

Open one PR labeled `automation-pr` with `Closes #N`, provenance naming the scheduled run and date, the exact commands and their output, risks, and any gate that did not run locally.

Wait for CI. Fix what it turns red — this is your own PR. When every required check is green, `gh pr merge --squash --delete-branch`.

Do not merge on a red or pending check, do not merge past a gate you skipped, and do not use admin override to bypass a failing check. If CI stays red after a genuine attempt to fix it, leave the PR open with a comment explaining what is wrong and stop — the next run will resume it under rule 1.

Stop before any deployment, release, or version bump. Never write a secret value into a commit, PR body, or issue comment.
29 changes: 29 additions & 0 deletions .agents/skills/ione-scout/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
name: ione-scout
description: Research IONe OLAP, OLTP, data-connection, federated-data, edge-computing, and application-support opportunities and file evidence-backed research candidates. Use for the scheduled IONe scouting loop or inbound enhancement triage.
---

# IONe idea scout

Scout these six areas and nothing else:

- **OLAP** — aggregate query paths, materialization, columnar/vector layout, pgvector index choice, chart/table aggregate endpoints, query plans that degrade with row count.
- **OLTP** — write path latency, transaction scope, lock contention, connection pooling, migration safety, RLS overhead on hot paths.
- **Data connections** — connector coverage and quality (`src/connectors/`), auth flows, retry/backoff, schema drift, ingest validation, signed webhook ingress.
- **Federated data systems** — MCP peer surface, context slices, catalog search, peer identity and credential lifecycle, conformance gaps between the kit and production semantics.
- **Edge computing** — running IONe close to the data: single-binary footprint, offline/degraded operation, sync and reconciliation after partition, resource ceilings on constrained hardware.
- **Application support** — what a downstream app (TerraYield, GroundPulse, a third party) needs from IONe as a substrate: API contracts, provisioning, error semantics, docs that match behavior.

Ground every candidate in current primary sources plus current repo state: `md/design/`, `md/requirements/active/`, open issues, recent PRs, and the code itself. Read `CLAUDE.md` and `md/design/ione-substrate.md` first — IONe is domain-agnostic federation infrastructure, not a geospatial product, and candidates that assume otherwise are wrong.

Verify any "already shipped" claim against the remote, never the local checkout: `git fetch origin` first, then `git merge-base --is-ancestor <sha> origin/main` or `gh pr view <n> --json state`. A commit appearing in bare `git log` proves nothing.

Deduplicate against every open and recently closed issue before filing. Propose the smallest testable change, not a program of work.

Filing `research-candidate` issues is pre-authorized — file them without asking, including on scheduled runs where no human is present to answer. Ending a run with candidates described but unfiled is a failed run: the builder reads issues, not logs. Cap a scheduled run at three issues; a fourth good idea keeps until next week.

Each issue states: dated sources, the current gap with a `file:line` citation, user or reliability value, the smallest validation experiment, blast radius, and provenance (scheduled scout run, date).

Everything you file gets built and merged without a human reading the issue first. That is the intended design, and it makes the issue body the specification — write it so the builder cannot misread the scope. Prefer a change that ships behind a narrow contract test over one that needs judgment at implementation time. If you cannot state the acceptance criterion in a sentence, the candidate is not ready; keep researching it and file it next run.

Never modify code, open a PR, merge, bump a version, or start a release. Never put secret values in an issue body.
4 changes: 4 additions & 0 deletions .agents/skills/ione-scout/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "IONe Idea Scout"
short_description: "Research IONe OLAP, OLTP, connector, federation, edge, and app-support opportunities"
default_prompt: "Use $ione-scout to research IONe improvement opportunities and file evidence-backed research-candidate issues."
25 changes: 25 additions & 0 deletions .agents/skills/ione-triage/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: ione-triage
description: Triage inbound IONe bug reports into reproducible, scoped bug-candidate issues, or close them out. Use for the scheduled IONe triage loop or a specific inbound report.
---

# IONe bug triage

Process open issues that carry `bug` and carry none of `bug-candidate`, `backlog-ready`, `automation-pr`, or `wontfix`. Oldest first. Cap a scheduled run at three issues.

For each, do the work the reporter could not:

1. **Reproduce.** Build a minimal case against current `main`. Use the cheap Rust path first, then migrated Postgres and the `#[ignore]`-gated suites serially when persistence or federation is involved, then Playwright for browser behavior. `docker compose up -d postgres minio`, `cargo sqlx migrate run`.
2. **Locate.** Cite the responsible code as `file:line`. A stack trace is not a location.
3. **Scope.** State the smallest change that fixes it and what it could break.

Then take exactly one action:

- **Reproduced** — comment with the repro command and its actual output, the `file:line` cause, the proposed fix, and a failing-test name the builder should write first. Apply `bug-candidate`. That label promotes to `backlog-ready` automatically, so do not apply `bug-candidate` to anything you did not personally reproduce.
- **Not reproducible** — comment with exactly what you ran, on what commit, and what you saw instead. Ask the reporter for the missing piece. Change no labels.
- **Already fixed** — verify against the remote (`git fetch origin`, then `git merge-base --is-ancestor <sha> origin/main` or `gh pr view <n> --json state` reporting `MERGED`), comment with that evidence, and close. A commit in bare `git log` is not evidence.
- **Not a bug** — comment with the contract or design doc that defines the current behavior and say so. Change no labels.

Anything you mark `bug-candidate` gets fixed and merged without a human reading it first. Your repro is the specification. That is why reproducing is not optional and why "looks wrong in the code" is never enough.

Never guess at a repro, never mark a report reproduced on code reading alone, never modify code, never open a PR, and never put secret values, tokens, or raw credential material in a comment. Fixing is the builder's job.
4 changes: 4 additions & 0 deletions .agents/skills/ione-triage/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "IONe Bug Triage"
short_description: "Reproduce and scope inbound IONe bug reports into bug-candidate issues"
default_prompt: "Use $ione-triage to reproduce and scope open inbound IONe bug reports."
1 change: 1 addition & 0 deletions .claude/skills/ione-backlog
1 change: 1 addition & 0 deletions .claude/skills/ione-scout
1 change: 1 addition & 0 deletions .claude/skills/ione-triage
33 changes: 33 additions & 0 deletions .github/workflows/auto-backlog-ready.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Auto backlog-ready

# Closes the scout/triage -> builder loop. An evidence-backed `bug-candidate`
# or `research-candidate` is promoted to `backlog-ready` (the builder's pickup
# gate) without manual approval, and the builder merges its own PR once CI is
# green — so nothing here waits on a human. `needs-human-auth` is Ryan's manual
# hold: applying it to an issue keeps that one issue out of the loop. No agent
# applies it to its own work.
on:
issues:
types: [labeled]

permissions:
issues: write

jobs:
promote:
if: github.event.label.name == 'bug-candidate' || github.event.label.name == 'research-candidate'
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
script: |
const labels = context.payload.issue.labels.map(l => l.name);
if (labels.includes('needs-human-auth')) { core.info('held: needs-human-auth'); return; }
if (labels.includes('backlog-ready')) { core.info('already backlog-ready'); return; }
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: ['backlog-ready'],
});
core.info(`promoted #${context.payload.issue.number} to backlog-ready`);
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ IONe is active federated geospatial infrastructure. Read `CLAUDE.md` for current

Use cheap Rust tests first. Persistence and federation claims require migrated Postgres and the ignored integration suite run serially; browser behavior requires the Playwright flow. Changes shared with TerraYield require matching issue-level interface contracts in both repositories before modifying either side.

Backlog automation accepts only Ryan-applied `backlog-ready`, skips red `main` and an existing `automation-pr`, works on one issue in an isolated worktree, opens one verified PR, and stops before merge or deployment.
Backlog automation is autonomous through merge. It accepts `backlog-ready` from Ryan or from the `auto-backlog-ready` workflow, never from an issue carrying `needs-human-auth` (Ryan's manual hold). It resumes an existing `automation-pr` before starting new work, repairs a red `main` before layering on it, takes one issue per run in an isolated worktree, opens one verified PR, drives CI green, and squash-merges. Green CI is the only merge authority: never merge on a red or pending check and never admin-override one. Stop before any deployment, release, or version bump.

Scheduled scouting and triage are read-only on code. They file `research-candidate` and `bug-candidate` issues, which promote to `backlog-ready` automatically — so the issue body is the specification the builder ships against, and a bug is never marked a candidate without a real reproduction. No agent applies `needs-human-auth` to its own work. No agent writes a secret value into an issue, comment, commit, or PR.
21 changes: 21 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ npm run test:e2e
```
Unset `IONE_SKIP_LIVE` to exercise live Ollama generator/critic/router paths.

## Automation loops
Three scheduled cloud agents, each driven by a skill in `.agents/skills/`
(symlinked into `.claude/skills/`):

| Skill | Cadence | Writes |
|---|---|---|
| `ione-scout` | Mon, Thu | `research-candidate` issues — OLAP, OLTP, data connections, federated data, edge, app support |
| `ione-triage` | Mon, Wed, Fri | reproduces inbound `bug` reports into `bug-candidate` issues |
| `ione-backlog` | Mon, Wed, Fri | one `backlog-ready` issue → `automation-pr` → green CI → squash merge |

The loop is autonomous end to end. `auto-backlog-ready.yml` promotes
`bug-candidate` and `research-candidate` to `backlog-ready`, and the builder
merges its own PR once CI is green. Nothing waits on a human.

Green CI is the only merge authority — no merging on red or pending checks, no
admin override, and no deploy, release, or version bump from any loop. The
issue body is the specification, since nobody reads it before the change lands.

Ryan steers by filing issues. `needs-human-auth` on an issue holds it out of the
loop; no agent applies that label to its own work.

## Secrets
`IONE_TOKEN_KEY` / `IONE_WEBHOOK_SECRET_KEY` live in `.env` (gitignored).
Never commit `.env` or embed key values in settings/permissions entries.
Loading