diff --git a/tools/spec-loop/.last-sync b/tools/spec-loop/.last-sync index be96efb3b..f97ccffa7 100644 --- a/tools/spec-loop/.last-sync +++ b/tools/spec-loop/.last-sync @@ -1 +1 @@ -bcd8b7f28e5d926ca8eff6e603c64b327ae038fe +da660f14e69670145e6096aa27626845ae910327 diff --git a/tools/spec-loop/specs/adapters.md b/tools/spec-loop/specs/adapters.md index 58570b8b8..e58f48d96 100644 --- a/tools/spec-loop/specs/adapters.md +++ b/tools/spec-loop/specs/adapters.md @@ -2,7 +2,7 @@ https://www.apache.org/licenses/LICENSE-2.0 --> --- -title: Adapters (Gmail / PonyMail / Jira / GitHub / Bitbucket / mail-source / SourceHut / maildir / VCS / change-request) +title: Adapters (Gmail / PonyMail / Jira / GitHub / GitLab / Bitbucket / mail-source / SourceHut / maildir / VCS / change-request / chat) status: experimental kind: feature mode: infra @@ -14,7 +14,7 @@ source: > tools/sourcehut/, tools/maildir/, tools/vcs/, tools/change-request/, tools/asf-svn/, tools/mail-archive/, tools/mail-patch/, tools/jira-patch/, tools/forwarder-relay/, tools/github-body-field/, - tools/github-rollup/. + tools/github-rollup/, tools/gitlab/, tools/chat/, tools/chat-slack/. acceptance: - Project-specific integrations live behind adapter modules, not hardcoded into skills. @@ -24,7 +24,7 @@ acceptance: redactor before any LLM read. --- -# Adapters (Gmail / PonyMail / Jira / GitHub / Bitbucket / SourceHut / maildir / VCS / change-request) +# Adapters (Gmail / PonyMail / Jira / GitHub / GitLab / Bitbucket / SourceHut / maildir / VCS / change-request / chat) ## What it does @@ -45,8 +45,29 @@ by swapping the adapter, not the skill. - `tools/jira/` — issue-tracker adapter for projects on Jira. - `tools/github/` — issues/PRs/labels read + write-back helpers. Sub-adapters: `tools/github-body-field/` (reads GitHub issue/PR body - structured field sets) and `tools/github-rollup/` (aggregates - multi-repo PR state into a single view). + structured field sets) and `tools/github-rollup/` (`contract:tracker`, + stdlib-only), which maintains the single status-rollup comment on a + tracker issue in a subprocess so the growing rollup body never enters + agent context. + `append` and `amend-latest` print the rollup comment's URL on stdout + (#1451), so a caller links to the entry without a second lookup. + Its subcommands are `append` (creates the rollup if none exists), + `amend-latest` (replaces the newest entry's body, keeping its date and + user, and refuses with exit 4 when that entry's action differs, so another + writer's entry is never overwritten), `fold` (moves one legacy bot comment + into the rollup with its own date and author, then deletes it; refuses to + fold the rollup itself), `list`, and `latest`. + An existing rollup is found by any ` - **The existing bullets need a one-off backfill.** Nine bullets across eight specs describe shipped capabilities, and eleven more are @@ -231,7 +235,9 @@ test -f tools/spec-loop/PROMPT_update.md acceptance criterion 7 requires it to fire on a violation that exists in the tree today, so landing it before the repo-health counts are reconciled turns main red for everyone. Reconcile first, then land - the HARD check. + the HARD check. The spec-to-spec half of the disagreement has since + closed (both specs say six); the prose-to-frontmatter half, six against + seven, is still open. - **A predicate can drift from its bullet.** Nothing binds the comment to the prose above it, so an edit that rewrites a bullet without updating its predicate leaves a check that passes while describing diff --git a/tools/spec-loop/specs/spec-loop-runner.md b/tools/spec-loop/specs/spec-loop-runner.md index 31fdf9ef9..aedfcab92 100644 --- a/tools/spec-loop/specs/spec-loop-runner.md +++ b/tools/spec-loop/specs/spec-loop-runner.md @@ -55,6 +55,9 @@ and never opens a pull request. - `tools/spec-loop/PROMPT_update.md` — spec back-fill prompt for functionality that landed outside the loop. - `tools/spec-loop/PROMPT_consolidate.md` — plan-size reduction prompt. +- `tools/spec-inventory/` — `spec-inventory --brief` supplies the compact + repository inventory appended to every prompt, and `spec-scope` maps + changed paths to the specs whose *Where it lives* sections name them. - `tools/spec-loop/AGENTS.md` — loop-specific operational context: repository map, validation commands, branch rules, hard limits, and commit rules. @@ -90,6 +93,12 @@ and never opens a pull request. incremental-scope guidance, then amends or creates a marker commit after the agent finishes. Prompts must not instruct the agent to edit the marker. +- **Deterministic scope mapping.** When `.last-sync` names a previous sync, + the runner lists the paths changed since it + (`git diff --name-only .. -- .claude/skills tools docs/modes.md`), + pipes them through `spec-scope`, and appends the specs it returns as + likely relevant. The mapping is advisory: a `spec-scope` failure is + silently skipped and the agent still reads the raw path list. - **Plan-size hysteresis.** Build mode switches to one consolidate pass when `IMPLEMENTATION_PLAN.md` exceeds `SPEC_LOOP_PLAN_MAX`, then builds even if planned work alone keeps the file over the threshold. The latch @@ -180,5 +189,13 @@ uv run --project tools/spec-validator --group dev spec-validate - The non-Claude harnesses rely on external policy/config plus the OS sandbox for push/PR denial; only Claude has a per-invocation hard-deny flag in the current runner. -- The update beat's incremental-scope mapping is path-based; it does not - yet map changed files to likely spec topics with a deterministic helper. +- The deterministic scope helper this bullet used to call missing has + shipped: `loop.sh` pipes the incremental diff through + `tools/spec-inventory`'s `spec-scope`. +- The incremental diff's pathspec (`.claude/skills tools docs/modes.md`) + no longer covers where skills live. `.claude/skills/magpie-` entries + are symlinks (through `.agents/skills/`) into + `plugins/magpie-/skills//`, so an edit to a skill's content + changes nothing under `.claude/skills` and drops out of the scoped list; + so do `plugins/magpie-setup/templates/`, `.github/`, `projects/`, and every + `docs/` page other than `docs/modes.md`. diff --git a/tools/spec-loop/specs/triage-mode.md b/tools/spec-loop/specs/triage-mode.md index 8a7b94636..781c5b511 100644 --- a/tools/spec-loop/specs/triage-mode.md +++ b/tools/spec-loop/specs/triage-mode.md @@ -7,8 +7,10 @@ status: experimental kind: feature mode: Triage source: > - MISSION.md § Technical scope (Triage). docs/modes.md § Triage. - Implemented by the pr-management, issue, and security skill families. + MISSION.md § Technical scope (Triage). docs/modes.md § Triage + (38 skills). Implemented by the pr-management, issue, security, + contributor-growth, repo-health, and release-management skill + families. acceptance: - Every triage skill is read-only on tracker state or proposes-then- confirms; none transitions, closes, or labels without confirmation. @@ -32,7 +34,11 @@ suggestion the human signs off on. - PR queue: `pr-management-triage`, `pr-management-stats`, `pr-management-code-review` (deep review is a triage variant), `pr-management-quick-merge` (read-only express-lane surfacing of - trivial, low-risk PRs a maintainer can review in seconds). + trivial, low-risk PRs a maintainer can review in seconds), + `pr-stale-sweep` (inactivity nudge or pre-close notice for PRs, + skipping maintainer-court and ready-labelled PRs), and + `reviewer-routing` (roster-bounded reviewer suggestion; see + [reviewer-routing.md](reviewer-routing.md)). Reference implementation: `tools/pr-management-stats/`. - General issues: `issue-triage`, `issue-reassess`, `issue-reproducer`, `issue-stale-sweep` (configurable inactivity sweep: nudge or @@ -44,13 +50,27 @@ suggestion the human signs off on. `issue-backlog-stats` (read-only maintainer dashboard over the open general-issue backlog — health rating, age/staleness, area pressure, triage funnel). -- Contributor readiness: `contributor-nomination` (read-only brief for a - named contributor — activity breadth, consistency, and nomination- - evidence prose for a committer or PMC thread); +- Contributor readiness (the `mode: Triage` members of the + contributor-growth family; see + [contributor-growth.md](contributor-growth.md)): + `contributor-nomination` (read-only brief for a named contributor — + activity breadth, consistency, and nomination-evidence prose for a + committer or PMC thread); `contributor-activity-sweep` (read-only GitHub activity card for a named contributor over a configurable window); - `committer-onboarding` (post-vote ICLA/account/permissions/welcome - checklist for committer and PMC promotions). + `contributor-calibrate` (threshold floors derived from past nomination + decisions, behind the privacy-LLM gate; numbers-only config diff); + `contributor-candidate-screen` (screens recent contributors against + the floors and writes a per-candidate report to a verified-private + repository); + `contributor-identity-map` (GitHub handle to chat, mailing-list, and + social identities, recording only maintainer-confirmed mappings); + `contributor-sentiment` (sentiment-signal gate report for + `experimental` to `stable` advancement). + `committer-onboarding` (post-vote checklist) belongs to the same + family but carries `mode: Meta`. + Counting is deterministic through `tools/contributor-metrics`; chat + evidence is read through `tools/chat` (`contract:chat`). - Security inbound: `security-issue-import`, `-import-from-pr`, `-import-from-md`, `-import-from-scan` (triage-first scanner-output import via pluggable scan-format adapters), @@ -59,9 +79,17 @@ suggestion the human signs off on. `security-issue-triage` (batch-triage open tracker issues carrying `needs triage`), `security-issue-deduplicate`, `security-issue-invalidate`, `security-issue-sync`, - `security-cve-allocate`. + `security-cve-allocate`, and `security-model-verify` (pre-flight on a + published security model). +- Repo-health audits (see [repo-health-family.md](repo-health-family.md)) + and the four read-only `release-*` skills (`release-verify-rc`, + `release-vote-tally`, `release-archive-sweep`, + `release-audit-report`; see + [release-management-lifecycle.md](release-management-lifecycle.md)) + are also catalogued under Triage in `docs/modes.md`. - Adapters it reads through: `tools/github`, `tools/jira`, - `tools/ponymail`, `tools/gmail`, `tools/mail-source`. + `tools/ponymail`, `tools/gmail`, `tools/mail-source`, + `tools/contributor-metrics`, `tools/chat`. ## Behaviour & contract @@ -103,14 +131,12 @@ uv run --project tools/skill-and-tool-validator --group dev skill-and-tool-valid (`experimental`); `issue-stale-sweep` provides stale-handling / close-proposal. No adopter-pilot eval has run on the general-issue family yet, so behaviour may change. -- **The contributor-growth skills span the path but are not yet a named - family.** `contributor-nomination`, `contributor-activity-sweep`, - `committer-onboarding`, and `good-first-issue-author` (Agentic Mentoring) are - now all catalogued in the specs. Missing members of the - contributor-to-committer path: PMC-member nomination (distinct from - committer), emeritus / inactive-committer handling, and contributor - offboarding. Worth deciding whether this becomes a named family with - its own spec. +- **The contributor-growth skills are now a named family.** They ship + as the `magpie-contributor-growth` plugin (with three Mentoring + members in `magpie-mentoring`) and have their own spec, + [contributor-growth.md](contributor-growth.md), which tracks the + remaining gaps: PMC-member nomination (distinct from committer), + emeritus / inactive-committer handling, and contributor offboarding. - **Repo-health audits are now a six-skill family — feature-complete.** `ci-runner-audit`, `workflow-security-audit` (zizmor-backed), `dependency-audit`, `license-compliance-audit`, `flaky-test-triage`, and diff --git a/tools/spec-loop/specs/vetted-command-surface.md b/tools/spec-loop/specs/vetted-command-surface.md index 82aca6453..dd29a933c 100644 --- a/tools/spec-loop/specs/vetted-command-surface.md +++ b/tools/spec-loop/specs/vetted-command-surface.md @@ -53,6 +53,13 @@ cve.org check, invoke it through the same `uv run --project /tools/vetted-ops vetted-op-read …` spelling every permission rule and sandbox exclusion names — a bare `vetted-op-read` would miss the allowlist and prompt or run sandboxed (#1339). +Two spellings are recognised, and each is both allowed and excluded from the +sandbox: `uv run --project … vetted-op-read` and `uvx --from … vetted-op-read`, +the form the read-only gatherer agents use (#1393). Before #1393 only the +`uv run --project` form was excluded and neither was allowed, so every +gatherer read prompted. The adopter install now carries these read `allow` +entries into the settings merge and the update skill diffs them; `vetted-op` +(writes) stays on `ask`. The `procedure` backend carries the tracker read-modify-write updates that `tools/github-rollup` and `tools/github-body-field` do outside the sandbox: @@ -66,6 +73,25 @@ read), with bodies on stdin and no `@file` fields. An operation declared read-only gets a runner that refuses every write. The parsing and composing modules are vendored byte-for-byte from the two tools, with a test that fails on drift, because the dispatcher installs without them. +The runner also refuses a `gh api` call that names its own repo or host, a +path that traverses, a method other than `GET`, `PATCH` or `DELETE`, and a +`gh issue --body-file` other than `-`, so no procedure makes `gh` read a local +file. +The dispatcher refuses a plan bound to any repository other than the policy's +tracker. +`rollup-amend-latest` refuses when the latest entry carries a different action, +and `rollup-fold` refuses the rollup comment itself or a comment that belongs +to another issue, and deletes the folded comment only after the append +succeeded. +Skills write with `vetted-op-tracker --caller rollup-append|rollup-amend-latest|rollup-fold|body-field-set …` +and read a field with `vetted-op-read --caller body-field-get …`; +the `github-rollup` and `github-body-field` uv CLIs remain for use outside the +sandbox (#1448). +On stdout, `body-field-get` prints the one value and `rollup-append` / +`rollup-amend-latest` print the rollup comment's URL (`…#issuecomment-`), +so a caller can link to the entry without reading the rollup (#1451). +The security skills are the first callers (#1451), and the policy example +grants each security caller exactly the tracker operations it uses. A third entry point, `vetted-op-tracker`, refuses every operation except the procedure ones before it reads the policy — the same shape as @@ -88,6 +114,15 @@ session, and it is `Edit`-denied alongside the catalogue. A `*` in place of the version would also match spaces, approving a command with extra `uv` options spliced in at that position; sandbox-lint rejects any Bash `allow` rule with a `*` before its end. +The hook (`tools/vetted-ops/hooks/link-stable-path.sh`) only ever replaces a +symlink: a real file or directory at the path is left alone and reported. The +isolated-setup update and verify skills report a leftover versioned glob as +must-fix (#1406). +Under `permissions.blockReadsOutsideWorkingDirectories`, reads of the fixed +path would prompt every time, so `sandbox-add-project-root.sh` lists +`$HOME/.claude/magpie`, resolved, as a working directory in each worktree's +`settings.local.json` (#1418; see +[`agent-isolation-sandbox.md`](agent-isolation-sandbox.md)). ## Scoping — what is real and what is aspiration