From d696438d1d0a1e6a353be8f8bb813705572f26b6 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Tue, 21 Jul 2026 19:32:29 +0100 Subject: [PATCH 01/10] docs: initialise the summit project description Replace the placeholder README with a description of summit as a meta-repository that aggregates the Spine SDK repositories as submodules for cross-repository automation, with a grouped submodule inventory and bootstrapping steps. Fill in docs/project.md (the .agents/project.md orientation doc) from the template. Also swap the delivery-server submodule for gcloud-jvm and reorder .gitmodules so the floating .agents/shared entry stays last. Co-Authored-By: Claude Opus 4.8 --- .gitmodules | 6 +-- README.md | 116 +++++++++++++++++++++++++++++++++++++++++++++++- delivery-server | 1 - docs/project.md | 37 ++++++++++----- gcloud-jvm | 1 + 5 files changed, 145 insertions(+), 16 deletions(-) delete mode 160000 delivery-server create mode 160000 gcloud-jvm diff --git a/.gitmodules b/.gitmodules index b37014f..598dfea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,9 +10,6 @@ [submodule "tool-base"] path = tool-base url = https://github.com/SpineEventEngine/tool-base.git -[submodule "delivery-server"] - path = delivery-server - url = https://github.com/SpineEventEngine/delivery-server.git [submodule "config"] path = config url = https://github.com/SpineEventEngine/config.git @@ -49,6 +46,9 @@ [submodule "money"] path = money url = https://github.com/SpineEventEngine/money.git +[submodule "gcloud-jvm"] + path = gcloud-jvm + url = https://github.com/SpineEventEngine/gcloud-jvm.git [submodule ".agents/shared"] path = .agents/shared url = https://github.com/SpineEventEngine/agents.git diff --git a/README.md b/README.md index a4d2bd9..0ee3dcf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,116 @@ # summit -The repository for automation of cross-repository works + +The meta-repository for automating cross-repository work across the [Spine SDK][spine-org]. + +`summit` is a Git superproject: it assembles the Spine SDK repositories as submodules +in a single working tree, so agents and the shared `config`/CI tooling can act across +the whole SDK at once. It ships no code and has no build of its own — its content is the +pinned commits of the submodules below, plus the shared agent tooling under `.agents/`. + +## Repository layout + +The submodules are pinned to fixed commits, giving a reproducible snapshot of the +SDK. They are grouped below by function, not by strict dependency order. + +### Shared infrastructure + +| Submodule | Role | +|-----------|------| +| [`config`][config] | Dependencies and build configurations shared among subprojects | + +The shared agent tooling — skills, scripts, and guidelines — lives in the +[`agents`][agents] repository, mounted at `.agents/shared`. Unlike the submodules +listed here, it floats to the tip of `master` rather than a pinned commit. + +### Foundation & utilities + +| Submodule | Role | +|-----------|------| +| [`base-libraries`][base-libraries] | The framework's base types and utilities | +| [`reflect`][reflect] | Utilities for working with reflection in Java and Kotlin projects | +| [`logging`][logging] | Fluent logging API for Kotlin projects | +| [`testlib`][testlib] | Testing utilities for Spine SDK development and users | + +### Domain & value types + +| Submodule | Role | +|-----------|------| +| [`base-types`][base-types] | Popular value object types and associated code | +| [`change`][change] | Data types and utilities for changes and mismatches in data values | +| [`time`][time] | Protobuf-based date/time types and utilities | +| [`money`][money] | Currency and money data types and operations | + +### Compiler & code generation + +| Submodule | Role | +|-----------|------| +| [`compiler`][compiler] | The Spine Compiler — extendable Protobuf compilation | +| [`tool-base`][tool-base] | Common code for development tools | +| [`ProtoTap`][ProtoTap] | Utilities for tapping `protoc` output | +| [`validation`][validation] | Library and Compiler plugins for generating custom validation code | +| [`core-jvm-compiler`][core-jvm-compiler] | Plugins of the CoreJvm library for the Spine Compiler | + +### Framework core + +| Submodule | Role | +|-----------|------| +| [`core-jvm`][core-jvm] | The JVM-based implementation of the Spine framework core | + +### Storage & runtime + +| Submodule | Role | +|-----------|------| +| [`jdbc-storage`][jdbc-storage] | Support for storage in JDBC-compliant databases | +| [`gcloud-jvm`][gcloud-jvm] | Support for Spine-based Kotlin and Java apps on Google Cloud | + +## Getting started + +Clone with all submodules in one step: + +```bash +git clone --recursive https://github.com/SpineEventEngine/summit.git +``` + +If you cloned without `--recursive`, or you are working in a fresh `git worktree` or +a shallow checkout, the submodules start uninitialised and the `.agents` symlinks +dangle. Bootstrap them with: + +```bash +./init-submodules # materialise the config-managed submodules at their pinned commits +./config/pull # float the shared submodules and copy in the shared files +``` + +`./init-submodules` runs automatically at the start of a Claude Code session. See +[`AGENTS.md`](AGENTS.md) for the full bootstrap chain and the rationale behind it. + +## Working across repositories + +`summit` is where cross-repository work happens: coordinated agent sessions and the +shared `config` tooling propagate changes — dependency bumps, CI workflows, agent +guidelines — across the SDK from one place. Agent orientation, safety rules, and the +available skills are described in [`AGENTS.md`](AGENTS.md). + +## License + +`summit`, like the rest of the Spine SDK, is distributed under the +[Apache License 2.0](LICENSE). + +[spine-org]: https://github.com/SpineEventEngine +[agents]: https://github.com/SpineEventEngine/agents +[config]: https://github.com/SpineEventEngine/config +[base-libraries]: https://github.com/SpineEventEngine/base-libraries +[reflect]: https://github.com/SpineEventEngine/reflect +[logging]: https://github.com/SpineEventEngine/logging +[testlib]: https://github.com/SpineEventEngine/testlib +[base-types]: https://github.com/SpineEventEngine/base-types +[change]: https://github.com/SpineEventEngine/change +[time]: https://github.com/SpineEventEngine/time +[money]: https://github.com/SpineEventEngine/money +[compiler]: https://github.com/SpineEventEngine/compiler +[tool-base]: https://github.com/SpineEventEngine/tool-base +[ProtoTap]: https://github.com/SpineEventEngine/ProtoTap +[validation]: https://github.com/SpineEventEngine/validation +[core-jvm-compiler]: https://github.com/SpineEventEngine/core-jvm-compiler +[core-jvm]: https://github.com/SpineEventEngine/core-jvm +[jdbc-storage]: https://github.com/SpineEventEngine/jdbc-storage +[gcloud-jvm]: https://github.com/SpineEventEngine/gcloud-jvm diff --git a/delivery-server b/delivery-server deleted file mode 160000 index 27aef68..0000000 --- a/delivery-server +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 27aef68d77c9b40c19f2f0dd253e351363f76377 diff --git a/docs/project.md b/docs/project.md index 0fdaffc..1177208 100644 --- a/docs/project.md +++ b/docs/project.md @@ -1,18 +1,33 @@ - - -# Project: +# Project: summit ## Overview -*One paragraph: what this repo is, what problem it solves, and its role in the -Spine SDK organisation.* +`summit` is a Git superproject (a meta-repository) that assembles the Spine SDK +repositories as submodules in a single working tree. It exists to automate +cross-repository work across the SDK: coordinated agent sessions and the shared +`config`/CI machinery act over many repositories at once. `summit` ships no code and +has no build of its own — its content is the pinned commits of the submodules it +aggregates, plus the shared agent tooling under `.agents/`. ## Architecture -*Role in the org: library / tool / Gradle plugin / application. -Key patterns, public API boundaries, and constraints specific to this repo.* +Role in the organisation: a **coordination superproject** — not a library, tool, +Gradle plugin, or application. + +- **Submodules.** The SDK repositories listed in `.gitmodules` are pinned to fixed + commits, giving a reproducible snapshot of the whole SDK. The shared + `.agents/shared` submodule is the exception: it declares a tracked `branch` and + floats to the tip of `master`, so shared skills, scripts, and guidelines stay + current with no file churn in consumer pull requests. +- **Bootstrapping.** A fresh `git worktree` or shallow checkout starts with the + submodules uninitialised, so the `.agents` symlinks dangle. Run `./init-submodules` + to materialise the config-managed submodules at their pinned commits, then + `./config/pull` to float the shared submodules and copy the shared files in. Claude + Code runs `./init-submodules` automatically via a `SessionStart` hook. +- **Not a JVM build.** `summit` has no Gradle build, coding style, or tests of its + own, so the shared JVM requirements in `.agents/guidelines/jvm-project.md` do not + govern this repository. The aggregated repositories are JVM (Kotlin/Java) projects + and are each subject to that guideline in their own right. - + diff --git a/gcloud-jvm b/gcloud-jvm new file mode 160000 index 0000000..f4ade19 --- /dev/null +++ b/gcloud-jvm @@ -0,0 +1 @@ +Subproject commit f4ade19d8bf7666447f068607426475cda485afe From 0d28ba6af5f0cf16088cc117c12cc014fc678875 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 22 Jul 2026 01:02:57 +0100 Subject: [PATCH 02/10] docs: add the repo-by-repo proofread workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summit-owned tooling for running the `proofread` skill across the SDK repos one at a time, ending in a PR: - proofread-repo — the deterministic mechanics (config/pull, branch, bump, reports, sentinel-gated push + PR); idempotent and re-runnable. - docs/rollout/proofread.md — the agent-driven playbook (sweep + pre-PR). - docs/rollout/proofread-pr-body.md — the PR body template. - docs/rollout/proofread-fanout.workflow.js — a Workflow sketch for the parallel proofread sweep. Referenced from docs/project.md so a fresh session can find it. Co-Authored-By: Claude Opus 4.8 --- docs/project.md | 11 ++ docs/rollout/proofread-fanout.workflow.js | 91 +++++++++++++ docs/rollout/proofread-pr-body.md | 27 ++++ docs/rollout/proofread.md | 87 +++++++++++++ proofread-repo | 148 ++++++++++++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 docs/rollout/proofread-fanout.workflow.js create mode 100644 docs/rollout/proofread-pr-body.md create mode 100644 docs/rollout/proofread.md create mode 100755 proofread-repo diff --git a/docs/project.md b/docs/project.md index 1177208..1146353 100644 --- a/docs/project.md +++ b/docs/project.md @@ -31,3 +31,14 @@ Gradle plugin, or application. + +## Cross-repository workflows + +Repeatable, parameterised procedures for acting across the SDK repos live under +[`docs/rollout/`](rollout/). Each pairs a repo-owned script (the deterministic +mechanics) with an agent-driven playbook (the judgement steps): + +- [`rollout/proofread.md`](rollout/proofread.md) — run the `proofread` skill across a + repo end-to-end (bump → build → sweep → pre-PR → PR), driven by the + [`proofread-repo`](../proofread-repo) script, with an optional + [`proofread-fanout.workflow.js`](rollout/proofread-fanout.workflow.js) for the sweep. diff --git a/docs/rollout/proofread-fanout.workflow.js b/docs/rollout/proofread-fanout.workflow.js new file mode 100644 index 0000000..d3439da --- /dev/null +++ b/docs/rollout/proofread-fanout.workflow.js @@ -0,0 +1,91 @@ +// proofread-fanout.workflow.js — DRAFT sketch of step 2 (the proofread sweep) as a +// deterministic fan-out. *** Not wired up; the Workflow tool requires opt-in. *** +// +// Invoke from the calling session: +// Workflow({ scriptPath: "docs/rollout/proofread-fanout.workflow.js", +// args: { repo: "base-libraries", files: [ ...repo-relative prose paths... ] } }) +// (Or move it to .claude/workflows/proofread-fanout.js to invoke it by name — if that +// directory is confirmed summit-local and not distributed by ./config/pull.) +// +// The CALLER pre-scopes `files` — `git ls-files` of *.kt/*.kts/*.java/*.proto/*.md minus +// build/, buildSrc/, .idea/, .claude/, .junie/, .github/, the config-distributed Markdown, +// and the generated docs/dependencies/ reports — because the Workflow runtime has NO +// filesystem access. This script only chunks and fans out. After it returns, the caller +// AUDITS with whitespace visible (docs/rollout/proofread.md step 2) and commits. Agents +// edit DISJOINT files, so no worktree isolation is needed. + +export const meta = { + name: 'proofread-fanout', + description: 'Fan the proofread sweep across a repo\'s prose files, one agent per chunk', + phases: [{ title: 'Proofread', detail: 'one proofreader per ~40-file chunk' }], +} + +// Structured report each proofreader returns (validated at the tool-call layer). +const REPORT = { + type: 'object', + additionalProperties: false, + properties: { + filesChanged: { type: 'integer' }, + changes: { + type: 'array', + items: { + type: 'object', additionalProperties: false, + required: ['file', 'topic', 'before', 'after'], + properties: { + file: { type: 'string' }, line: { type: 'integer' }, + topic: { type: 'string' }, before: { type: 'string' }, after: { type: 'string' }, + }, + }, + }, + skipped: { + type: 'array', + items: { + type: 'object', additionalProperties: false, + required: ['file', 'topic', 'reason'], + properties: { file: { type: 'string' }, topic: { type: 'string' }, reason: { type: 'string' } }, + }, + }, + }, + required: ['filesChanged', 'changes', 'skipped'], +} + +const repo = args.repo +const files = args.files || [] +const CHUNK = 40 +const chunks = [] +for (let i = 0; i < files.length; i += CHUNK) chunks.push(files.slice(i, i + CHUNK)) + +log(`proofread ${files.length} files in ${repo} across ${chunks.length} chunks`) +phase('Proofread') + +// One proofreader per chunk, all concurrent (runtime caps at ~cores-2 at a time). +// parallel() is the right call here: a single stage whose results we aggregate. +const results = await parallel(chunks.map((chunk, i) => () => + agent( + [ + `Proofread ONLY the files listed below in the repo at ${repo} (paths are repo-relative).`, + `First read the catalog .agents/guidelines/english-style.md IN FULL — it is the sole`, + `authority on what counts as an error and when to leave text alone. Bias: a missed error`, + `is cheaper than a wrong fix — skip anything not clearly correct and record it in "skipped".`, + ``, + `Edit PROSE ONLY: comments in .kt/.kts/.java/.proto (KDoc/Javadoc/line/block) and body`, + `text in .md. NEVER touch identifiers, keywords, string literals, annotations, doc-link`, + `targets like [Type], copyright headers, or machine-read directives. Keep edits minimal.`, + `Do NOT run git, builds, or commits — only read and Edit the listed files.`, + ``, + `Files:`, + ...chunk, + ].join('\n'), + { label: `proofread:${i}`, phase: 'Proofread', schema: REPORT } + ) +)) + +const ok = results.filter(Boolean) // a died/refused agent resolves to null +return { + repo, + filesScanned: files.length, + chunks: chunks.length, + filesChanged: ok.reduce((n, r) => n + (r.filesChanged || 0), 0), + changes: ok.flatMap(r => r.changes || []), + skipped: ok.flatMap(r => r.skipped || []), +} diff --git a/docs/rollout/proofread-pr-body.md b/docs/rollout/proofread-pr-body.md new file mode 100644 index 0000000..8685386 --- /dev/null +++ b/docs/rollout/proofread-pr-body.md @@ -0,0 +1,27 @@ +## Summary + +Repo-wide English proofread — grammar, spelling, punctuation, articles, restrictive +`which`/`that`, verb forms in API summaries, and verb complementation (`allow`/`enable` ++ gerund) — across KDoc, Javadoc, Protobuf doc comments, and Markdown. + +**Prose only:** no executable code, identifiers, string literals, or doc-link targets +were changed. + +## Commits + +- **Update shared agent tooling** — floated `.agents/shared` to current via `./config/pull`. +- **Bump version** — snapshot increment required by the versioning policy. +- **Update dependency reports** — `docs/dependencies/` refreshed for the new version; + the report diff is version-only (no dependency changes). +- **Proofread comments and documentation** — the prose fixes. + +## Verification + +- `./gradlew clean build dokkaGenerate` passes — compile, tests, and Dokka/KDoc link + checks are all green. +- Reviewed with the repository's own reviewers (`review-docs`, `spine-code-review`, + `kotlin-engineer`). + + diff --git a/docs/rollout/proofread.md b/docs/rollout/proofread.md new file mode 100644 index 0000000..b6fef98 --- /dev/null +++ b/docs/rollout/proofread.md @@ -0,0 +1,87 @@ +# Repo-by-repo proofread rollout + +A parameterised procedure for running the `proofread` skill across the Spine SDK +repositories from `summit`, one repo at a time, ending in a pull request. + +The deterministic mechanics live in the repo-owned [`proofread-repo`](../../proofread-repo) +script; the two judgement steps — the proofread sweep and the pre-PR review — are +agent-driven and described below. Run the four steps in order for a given `` +(e.g. `base-libraries`). + +> **Why a script *and* a playbook?** The interventions the first run needed +> (`JAVA_HOME`, `./config/pull` ordering, flaky dependency reports) were +> deterministic mechanics, not judgement — so they live in the script, where they +> can't be re-interpreted. Only the proofread and the review genuinely need an +> agent. + +## 0. Prerequisites (once per machine) + +- `JAVA_HOME`: `proofread-repo` exports it for its own builds, but the **agent-run** + builds (step 1's edge-case bump and step 3's pre-pr) run in separate shells that do + **not** inherit it — so a durable `export JAVA_HOME="$(/usr/libexec/java_home -v 21)"` + in your shell profile is the real fix. Without it the Gradle Doctor plugin + hard-fails every build. +- `gh auth status` shows a token with `repo` + `workflow` scope. + +## 1. Prep (mechanical) — `./proofread-repo prep ` + +Cuts `proofread-sweep` off the latest `master`, floats the repo's `.agents/shared` +to current via `./config/pull` (committed on its own, so the repo has the current +`english-style` catalog and `proofread` skill), bumps the snapshot version, then +regenerates `docs/dependencies/` with a clean build and commits it verbatim — so the +reports reflect any dependency-pin updates `config/pull` brought in as well as the +bump. No agent judgement. + +The bump handles the common snapshot case (`+1`). For a **release-line version** or a +`version.gradle.kts` still using `by extra(...)` (which needs migration), `prep` stops +and asks you to run the `bump-version` skill first, then re-run `./proofread-repo prep +`. Every step is idempotent, so the re-run picks up where it left off. + +## 2. Proofread sweep (agent) + +**Scope.** `git ls-files` of project-owned prose — `*.kt`, `*.kts`, `*.java`, +`*.proto`, `*.md`. **Exclude** (not project-owned, or not prose): `build/`, +`.gradle/`, `buildSrc/`, `.idea/`, `.claude/`, `.junie/`, `.github/`, `AGENTS.md`, +`CLAUDE.md`, `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, and the **generated** +`docs/dependencies/` reports. + +**Fan out.** Split the file list into ~40-file chunks and run one proofreader per +chunk. Each reads `.agents/guidelines/english-style.md` (present after step 1) and +edits **prose only** — comments in source, body in Markdown — never identifiers, +string literals, doc-link targets (`[Type]`), or machine-read directives. Bias: +*a missed error is cheaper than a wrong fix*; skip ambiguous cases. See +[`proofread-fanout.workflow.js`](proofread-fanout.workflow.js) for a sketch of this +step as a saved Workflow — the fan-out as one deterministic call. + +**Audit before committing — do NOT rely on `git diff --ignore-all-space`.** A +`PostToolUse` formatter hook (`sanitize-source-code.sh`) strips trailing whitespace +file-wide after each edit. That is house style everywhere *except* inside +whitespace-sensitive **test string literals**, where it silently corrupts fixtures +(this broke a `StringsSpec` trim test on the first run, caught only by the build + +reviewers). So: inspect `git diff` **with** whitespace, and restore any stripped +trailing whitespace inside string literals with `sed` via Bash — the hook fires on +`Edit`/`Write`/`MultiEdit` only, so a Bash edit is not re-stripped. Then commit. + +## 3. Pre-PR (agent) — run the `pre-pr` skill + +Version gate (already satisfied), `./gradlew clean build dokkaGenerate`, and the +reviewers (`review-docs`, `spine-code-review`, `kotlin-engineer`). Apply their +Must-fixes; apply the clear Should-fixes that are genuine proofread misses. On PASS +it writes the `.git/pre-pr.ok` sentinel that gates PR creation. + +## 4. Ship (mechanical) — `./proofread-repo ship ` + +Verifies the sentinel matches HEAD, discards any post-build report noise, pushes +`proofread-sweep`, and opens the PR from +[`proofread-pr-body.md`](proofread-pr-body.md). + +## Cost & caveats + +- A full run is **expensive** — a dozen proofreader subagents, **two clean builds** + (`prep` regenerates the reports and verifies the bump; `pre-pr` re-verifies after + the sweep), and three reviewers per repo. Budget accordingly. Because the sweep + touches `.proto`, `pre-pr` runs a *clean* build per policy; an incremental build + would suffice for doc-only proto edits and is a worthwhile refinement. +- If `./config/pull` updates dependency pins, that simply flows through: the + regenerated reports reflect reality and the proofread lands on top of them. +- `proofread-repo` uses macOS `sed -i ''`; adjust for Linux runners. diff --git a/proofread-repo b/proofread-repo new file mode 100755 index 0000000..57b0b13 --- /dev/null +++ b/proofread-repo @@ -0,0 +1,148 @@ +#!/usr/bin/env bash +# +# proofread-repo — deterministic mechanics for the summit repo-by-repo proofread +# workflow. *** DRAFT — not wired into any hook. *** +# +# Owns only the parts that must NOT be re-interpreted each run (the environmental +# fixes that bit us on the first run: JAVA_HOME, config/pull ordering, and +# generating authoritative dependency reports via a clean build). The two +# judgement steps — the proofread sweep and the pre-PR review — are agent-driven +# and run BETWEEN `prep` and `ship`. See docs/rollout/proofread.md. +# +# Re-runnable: every step is idempotent, so a run interrupted midway — e.g. when +# `prep` bails to the bump-version skill for an edge case — resumes cleanly on a +# second `./proofread-repo prep `. +# +# Usage: +# ./proofread-repo prep # config/pull, branch, bump, regenerate reports +# ./proofread-repo ship # verify pre-pr sentinel, push, open the PR +# +# Note: uses macOS `sed -i ''`; adjust for Linux runners. +# +set -euo pipefail + +MODE="${1:?usage: proofread-repo }" +REPO="${2:?usage: proofread-repo }" +SUMMIT="$(cd "$(dirname "$0")" && pwd)" +DIR="$SUMMIT/$REPO" +BASE="master" +BRANCH="proofread-sweep" + +[ -d "$DIR/.git" ] || { echo "!! no initialised submodule at $DIR"; exit 1; } + +# --- Fix #1: JAVA_HOME. Without it the Gradle Doctor plugin hard-fails every +# build. Agent-run skill builds (bump-version, pre-pr) need it too, so a durable +# `export JAVA_HOME=...` in your shell profile is the real cross-cutting fix; this +# line only covers the script's own builds. +export JAVA_HOME="${JAVA_HOME:-$(/usr/libexec/java_home -v 21 2>/dev/null || true)}" +[ -n "${JAVA_HOME:-}" ] || { echo "!! JAVA_HOME unset and no JDK 21 found"; exit 1; } + +cd "$DIR" + +version_of() { sed -nE 's/.*versionToPublish"?,?[[:space:]]*"?([0-9A-Za-z.-]+)".*/\1/p' | head -1; } + +# True when the branch already carries a change to relative to base. +branch_touched() { ! git diff --quiet "origin/$BASE...HEAD" -- "$1" 2>/dev/null; } + +ensure_branch() { + [ "$(git rev-parse --abbrev-ref HEAD)" = "$BRANCH" ] && return 0 # already here (re-run) + git fetch --quiet origin "$BASE" + git checkout -q "$BASE" + git pull --ff-only --quiet origin "$BASE" + git switch -q -c "$BRANCH" 2>/dev/null || git switch -q "$BRANCH" +} + +pull_shared() { + # Fix #2: float shared tooling FIRST (brings the current english-style catalog + # + proofread skill) plus any config-distributed updates; commit as its own + # change. Skip if this branch already carries that commit (re-run safety). + git log --format=%s "origin/$BASE..HEAD" | grep -q '^Update shared agent tooling' \ + && { echo "-- shared tooling already pulled on this branch — skipping"; return 0; } + ./config/pull + if [ -n "$(git status --porcelain)" ]; then + git add -A # config/pull output is trusted; secret-scan hook is the backstop + git commit -q -m "Update shared agent tooling and config (./config/pull)" + fi +} + +bump_version() { + local f="version.gradle.kts" + [ -f "$f" ] || { echo "-- no $f — bump N/A"; return 0; } + branch_touched "$f" && { echo "-- already bumped on this branch — skipping"; return 0; } + + # Defer edge cases to the `bump-version` skill (agent): a deprecated + # `by extra(...)` delegate needing migration, or a non-snapshot/release version + # whose increment is not a simple +1. The skill also builds and commits the + # reports, so a re-run of `prep` afterwards no-ops through the rest. + if grep -qE 'versionToPublish.*by[[:space:]]+extra\(' "$f"; then + echo "!! $f uses 'by extra(...)' — run the bump-version skill, then: ./proofread-repo prep $REPO"; exit 3 + fi + local cur; cur="$(version_of < "$f")" + if ! printf '%s' "$cur" | grep -qE 'SNAPSHOT\.[0-9]+$'; then + echo "!! '$cur' is not a snapshot line — run the bump-version skill, then: ./proofread-repo prep $REPO"; exit 3 + fi + + # Common case: snapshot +1, preserving zero-padding. + local pre suf w next + pre="${cur%.*}"; suf="${cur##*.}"; w="${#suf}" + next="$pre.$(printf "%0${w}d" "$((10#$suf + 1))")" + sed -i '' "s/${cur}/${next}/" "$f" + git commit -q -m "Bump version -> \`${next}\`" -- "$f" + echo "-- bumped $cur -> $next" +} + +generate_reports() { + [ -d docs/dependencies ] || return 0 + branch_touched docs/dependencies && { echo "-- reports already updated on this branch — skipping build"; return 0; } + # Fix #3: regenerate for real (reflects config/pull dep-pin updates AND the bump); + # a *clean* build is authoritative — a warm build can emit stale cached values. + # This build also verifies the bump compiles. + ./gradlew clean build dokkaGenerate --console=plain + if [ -n "$(git status --porcelain docs/dependencies/)" ]; then + git add docs/dependencies/ + git commit -q -m "Update dependency reports" + fi +} + +prep() { + ensure_branch + pull_shared + bump_version + generate_reports + cat < commit the prose fixes + 3. Run the pre-pr skill -> reviewers + writes .git/pre-pr.ok +Then: ./proofread-repo ship $REPO +EOF +} + +ship() { + local gitdir head s_head s_status + gitdir="$(git rev-parse --absolute-git-dir)" + head="$(git rev-parse HEAD)" + s_head="$(sed -n 's/^head=//p' "$gitdir/pre-pr.ok" 2>/dev/null || true)" + s_status="$(sed -n 's/^status=//p' "$gitdir/pre-pr.ok" 2>/dev/null || true)" + [ "$s_status" = "PASS" ] && [ "$s_head" = "$head" ] \ + || { echo "!! no PASS pre-pr sentinel for HEAD $head — run the pre-pr skill first"; exit 1; } + + git checkout -- docs/dependencies/ 2>/dev/null || true # drop any post-build report noise + + # Re-run safety: if a PR already exists, just push any new commits to it. + if gh pr view "$BRANCH" --json url >/dev/null 2>&1; then + git push -q origin "$BRANCH" + echo "-- PR already open: $(gh pr view "$BRANCH" --json url --jq .url)" + return 0 + fi + git push -u origin "$BRANCH" + gh pr create --base "$BASE" --head "$BRANCH" \ + --title "Proofread comments and documentation" \ + --body-file "$SUMMIT/docs/rollout/proofread-pr-body.md" +} + +case "$MODE" in + prep) prep ;; + ship) ship ;; + *) echo "usage: proofread-repo "; exit 2 ;; +esac From bc66663d31f2132cdebcdd8ad701c9c1a320948e Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 22 Jul 2026 02:00:52 +0100 Subject: [PATCH 03/10] chore: add the agents repo as a top-level submodule Mount SpineEventEngine/agents at `agents` (pinned, no tracked branch) as a dedicated automation target, distinct from the floating `.agents/shared` tooling mount. This lets the repo-by-repo automation target the agents repo like the other SDK submodules. Co-Authored-By: Claude Opus 4.8 --- .gitmodules | 3 +++ agents | 1 + 2 files changed, 4 insertions(+) create mode 160000 agents diff --git a/.gitmodules b/.gitmodules index 598dfea..7682bb6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -55,3 +55,6 @@ branch = master update = merge ignore = all +[submodule "agents"] + path = agents + url = https://github.com/SpineEventEngine/agents.git diff --git a/agents b/agents new file mode 160000 index 0000000..2369ab8 --- /dev/null +++ b/agents @@ -0,0 +1 @@ +Subproject commit 2369ab816bb5d0feee562bfd6395b0b2852a3a9d From b99197d259ec887acab97e289342a54fc569805f Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 22 Jul 2026 02:07:51 +0100 Subject: [PATCH 04/10] docs: harden the proofread fan-out Workflow (validated on base-types) Fixes found by actually running the sketch: - Parse `args` whether the harness delivers it as a string or an object; the string case made `args.files` undefined -> 0 files, 0 agents, silent no-op. - Take absolute `catalog` and `files` paths plus a tunable `chunkSize`, since the Workflow runtime has no filesystem access and can't resolve repo-relative paths. - Exclude `.agents/` from the prose scope (old-layout repos commit the shared guidelines there). Validated by a live run against base-types: 33 files, 3 parallel proofreaders, 14 fixes, prose-only. Co-Authored-By: Claude Opus 4.8 --- docs/rollout/proofread-fanout.workflow.js | 43 +++++++++++++---------- docs/rollout/proofread.md | 2 +- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/docs/rollout/proofread-fanout.workflow.js b/docs/rollout/proofread-fanout.workflow.js index d3439da..81d516b 100644 --- a/docs/rollout/proofread-fanout.workflow.js +++ b/docs/rollout/proofread-fanout.workflow.js @@ -3,21 +3,24 @@ // // Invoke from the calling session: // Workflow({ scriptPath: "docs/rollout/proofread-fanout.workflow.js", -// args: { repo: "base-libraries", files: [ ...repo-relative prose paths... ] } }) -// (Or move it to .claude/workflows/proofread-fanout.js to invoke it by name — if that -// directory is confirmed summit-local and not distributed by ./config/pull.) +// args: { repo: "base-types", +// catalog: "/abs/.agents/guidelines/english-style.md", +// files: [ ...ABSOLUTE prose file paths... ], +// chunkSize: 40 } }) // -// The CALLER pre-scopes `files` — `git ls-files` of *.kt/*.kts/*.java/*.proto/*.md minus -// build/, buildSrc/, .idea/, .claude/, .junie/, .github/, the config-distributed Markdown, -// and the generated docs/dependencies/ reports — because the Workflow runtime has NO -// filesystem access. This script only chunks and fans out. After it returns, the caller -// AUDITS with whitespace visible (docs/rollout/proofread.md step 2) and commits. Agents -// edit DISJOINT files, so no worktree isolation is needed. +// The CALLER pre-scopes `files` (ABSOLUTE paths) and passes the catalog's ABSOLUTE +// path, because the Workflow runtime has NO filesystem access — it can neither list +// files nor resolve repo-relative paths. Scope = `git ls-files` of +// *.kt/*.kts/*.java/*.proto/*.md minus build/, buildSrc/, .idea/, .claude/, .junie/, +// .github/, .agents/, the config-distributed Markdown, and the generated +// docs/dependencies/ reports. This script only chunks and fans out. After it +// returns, the caller AUDITS with whitespace visible (docs/rollout/proofread.md +// step 2) and commits. Agents edit DISJOINT files — no worktree isolation needed. export const meta = { name: 'proofread-fanout', description: 'Fan the proofread sweep across a repo\'s prose files, one agent per chunk', - phases: [{ title: 'Proofread', detail: 'one proofreader per ~40-file chunk' }], + phases: [{ title: 'Proofread', detail: 'one proofreader per file chunk' }], } // Structured report each proofreader returns (validated at the tool-call layer). @@ -49,13 +52,17 @@ const REPORT = { required: ['filesChanged', 'changes', 'skipped'], } -const repo = args.repo -const files = args.files || [] -const CHUNK = 40 +// The Workflow harness may hand `args` in as a JSON string rather than an object; +// accept either so `args.files` can't silently read as undefined (0 files, 0 agents). +const A = typeof args === 'string' ? JSON.parse(args) : (args || {}) +const repo = A.repo +const catalog = A.catalog +const files = A.files || [] +const CHUNK = A.chunkSize || 40 const chunks = [] for (let i = 0; i < files.length; i += CHUNK) chunks.push(files.slice(i, i + CHUNK)) -log(`proofread ${files.length} files in ${repo} across ${chunks.length} chunks`) +log(`proofread ${files.length} files in ${repo} across ${chunks.length} chunk(s)`) phase('Proofread') // One proofreader per chunk, all concurrent (runtime caps at ~cores-2 at a time). @@ -63,10 +70,10 @@ phase('Proofread') const results = await parallel(chunks.map((chunk, i) => () => agent( [ - `Proofread ONLY the files listed below in the repo at ${repo} (paths are repo-relative).`, - `First read the catalog .agents/guidelines/english-style.md IN FULL — it is the sole`, - `authority on what counts as an error and when to leave text alone. Bias: a missed error`, - `is cheaper than a wrong fix — skip anything not clearly correct and record it in "skipped".`, + `Proofread ONLY the files listed below (ABSOLUTE paths); they belong to ${repo}.`, + `First read the catalog at ${catalog} IN FULL — it is the sole authority on what`, + `counts as an error and when to leave text alone. Bias: a missed error is cheaper`, + `than a wrong fix — skip anything not clearly correct and record it in "skipped".`, ``, `Edit PROSE ONLY: comments in .kt/.kts/.java/.proto (KDoc/Javadoc/line/block) and body`, `text in .md. NEVER touch identifiers, keywords, string literals, annotations, doc-link`, diff --git a/docs/rollout/proofread.md b/docs/rollout/proofread.md index b6fef98..d593622 100644 --- a/docs/rollout/proofread.md +++ b/docs/rollout/proofread.md @@ -41,7 +41,7 @@ and asks you to run the `bump-version` skill first, then re-run `./proofread-rep **Scope.** `git ls-files` of project-owned prose — `*.kt`, `*.kts`, `*.java`, `*.proto`, `*.md`. **Exclude** (not project-owned, or not prose): `build/`, -`.gradle/`, `buildSrc/`, `.idea/`, `.claude/`, `.junie/`, `.github/`, `AGENTS.md`, +`.gradle/`, `buildSrc/`, `.idea/`, `.claude/`, `.junie/`, `.github/`, `.agents/`, `AGENTS.md`, `CLAUDE.md`, `CODE_OF_CONDUCT.md`, `CONTRIBUTING.md`, and the **generated** `docs/dependencies/` reports. From f62b9270b62fb4c8b884f3aec10e490de298c171 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 22 Jul 2026 16:21:07 +0100 Subject: [PATCH 05/10] Update base-libraries and base-types to their merged master Point summit at the merge commits: base-libraries #954 (7a05857) and base-types #54 (0f2898b), now that both proofread PRs have landed. Co-Authored-By: Claude Opus 4.8 --- base-libraries | 2 +- base-types | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base-libraries b/base-libraries index 76b2d00..7a05857 160000 --- a/base-libraries +++ b/base-libraries @@ -1 +1 @@ -Subproject commit 76b2d003f8e5711a50741bbd0b016302f399e82d +Subproject commit 7a05857b2adc68dc2f9b28a03ae3073e7c3e9df3 diff --git a/base-types b/base-types index ee191de..0f2898b 160000 --- a/base-types +++ b/base-types @@ -1 +1 @@ -Subproject commit ee191de26a712f0ab318ee8e794929f8e7a89dbe +Subproject commit 0f2898be841a4f0f92497dd597ab04e5216218ba From 0ce48c8229b410f64f62a6e82cadba5d99fde5a2 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Wed, 22 Jul 2026 16:59:20 +0100 Subject: [PATCH 06/10] docs: apply review-docs findings Address the APPROVE-WITH-CHANGES items from the pre-PR documentation review: - README: document the pinned top-level `agents/` submodule (added on this branch) alongside the floating `.agents/shared` mount, so both checkouts of the tooling repo are explained. - Reflow widowed lines in `proofread.md` and `proofread-pr-body.md`. - Collapse double spaces after sentence periods in the `proofread-repo` comments and the `proofread-fanout.workflow.js` header. - Minor terminology/backtick consistency in `docs/project.md` and `proofread.md`. Prose and comments only; no behavioural change to the script or Workflow. --- README.md | 5 ++++- docs/project.md | 6 +++--- docs/rollout/proofread-fanout.workflow.js | 8 ++++---- docs/rollout/proofread-pr-body.md | 8 ++++---- docs/rollout/proofread.md | 11 +++++------ proofread-repo | 12 ++++++------ 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 0ee3dcf..162016e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,10 @@ SDK. They are grouped below by function, not by strict dependency order. The shared agent tooling — skills, scripts, and guidelines — lives in the [`agents`][agents] repository, mounted at `.agents/shared`. Unlike the submodules -listed here, it floats to the tip of `master` rather than a pinned commit. +listed here, that mount floats to the tip of `master` rather than a pinned commit. +The same repository is also wired in as a pinned top-level submodule at `agents/`, +so cross-repository automation can run against the tooling repo itself, just as it +does against the SDK repositories above. ### Foundation & utilities diff --git a/docs/project.md b/docs/project.md index 1146353..9a9ad97 100644 --- a/docs/project.md +++ b/docs/project.md @@ -5,7 +5,7 @@ `summit` is a Git superproject (a meta-repository) that assembles the Spine SDK repositories as submodules in a single working tree. It exists to automate cross-repository work across the SDK: coordinated agent sessions and the shared -`config`/CI machinery act over many repositories at once. `summit` ships no code and +`config`/CI machinery act across many repositories at once. `summit` ships no code and has no build of its own — its content is the pinned commits of the submodules it aggregates, plus the shared agent tooling under `.agents/`. @@ -29,12 +29,12 @@ Gradle plugin, or application. govern this repository. The aggregated repositories are JVM (Kotlin/Java) projects and are each subject to that guideline in their own right. - ## Cross-repository workflows -Repeatable, parameterised procedures for acting across the SDK repos live under +Repeatable, parameterised procedures for acting across the SDK repositories live under [`docs/rollout/`](rollout/). Each pairs a repo-owned script (the deterministic mechanics) with an agent-driven playbook (the judgement steps): diff --git a/docs/rollout/proofread-fanout.workflow.js b/docs/rollout/proofread-fanout.workflow.js index 81d516b..e556739 100644 --- a/docs/rollout/proofread-fanout.workflow.js +++ b/docs/rollout/proofread-fanout.workflow.js @@ -1,5 +1,5 @@ // proofread-fanout.workflow.js — DRAFT sketch of step 2 (the proofread sweep) as a -// deterministic fan-out. *** Not wired up; the Workflow tool requires opt-in. *** +// deterministic fan-out. *** Not wired up; the Workflow tool requires opt-in. *** // // Invoke from the calling session: // Workflow({ scriptPath: "docs/rollout/proofread-fanout.workflow.js", @@ -10,12 +10,12 @@ // // The CALLER pre-scopes `files` (ABSOLUTE paths) and passes the catalog's ABSOLUTE // path, because the Workflow runtime has NO filesystem access — it can neither list -// files nor resolve repo-relative paths. Scope = `git ls-files` of +// files nor resolve repo-relative paths. Scope = `git ls-files` of // *.kt/*.kts/*.java/*.proto/*.md minus build/, buildSrc/, .idea/, .claude/, .junie/, // .github/, .agents/, the config-distributed Markdown, and the generated -// docs/dependencies/ reports. This script only chunks and fans out. After it +// docs/dependencies/ reports. This script only chunks and fans out. After it // returns, the caller AUDITS with whitespace visible (docs/rollout/proofread.md -// step 2) and commits. Agents edit DISJOINT files — no worktree isolation needed. +// step 2) and commits. Agents edit DISJOINT files — no worktree isolation needed. export const meta = { name: 'proofread-fanout', diff --git a/docs/rollout/proofread-pr-body.md b/docs/rollout/proofread-pr-body.md index 8685386..655e029 100644 --- a/docs/rollout/proofread-pr-body.md +++ b/docs/rollout/proofread-pr-body.md @@ -4,8 +4,8 @@ Repo-wide English proofread — grammar, spelling, punctuation, articles, restri `which`/`that`, verb forms in API summaries, and verb complementation (`allow`/`enable` + gerund) — across KDoc, Javadoc, Protobuf doc comments, and Markdown. -**Prose only:** no executable code, identifiers, string literals, or doc-link targets -were changed. +**Prose only:** no executable code, identifiers, string literals, or doc-link +targets were changed. ## Commits @@ -19,8 +19,8 @@ were changed. - `./gradlew clean build dokkaGenerate` passes — compile, tests, and Dokka/KDoc link checks are all green. -- Reviewed with the repository's own reviewers (`review-docs`, `spine-code-review`, - `kotlin-engineer`). +- Reviewed with the repository's own reviewers (`review-docs`, + `spine-code-review`, `kotlin-engineer`).