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
16 changes: 9 additions & 7 deletions .agents/_TOC.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Table of Contents

1. [Quick Reference Card](quick-reference-card.md)
2. [Project overview](project-overview.md)
2. [JVM project requirements](jvm-project.md) — language, build, and review checklist shared by all JVM repos
3. [Coding guidelines](coding-guidelines.md)
4. [Documentation & comments](documentation-guidelines.md)
5. [Documentation tasks](documentation-tasks.md)
Expand All @@ -13,9 +13,11 @@
11. [Advanced safety rules](advanced-safety-rules.md)
12. [Refactoring guidelines](refactoring-guidelines.md)
13. [Common tasks](common-tasks.md)
14. [Java to Kotlin conversion](skills/java-to-kotlin/SKILL.md)
15. [Dependency update](skills/dependency-update/SKILL.md)
16. [Documentation review](skills/review-docs/SKILL.md)
17. [Pre-PR checklist](skills/pre-pr/SKILL.md)
18. [Kotlin code review](skills/kotlin-review/SKILL.md)
19. [Dependency audit](skills/dependency-audit/SKILL.md)
14. [Team memory](memory/MEMORY.md)
15. [Task plans](tasks/README.md)
16. [Java to Kotlin conversion](skills/java-to-kotlin/SKILL.md)
17. [Dependency update](skills/dependency-update/SKILL.md)
18. [Documentation review](skills/review-docs/SKILL.md)
19. [Pre-PR checklist](skills/pre-pr/SKILL.md)
20. [Kotlin code review](skills/kotlin-review/SKILL.md)
21. [Dependency audit](skills/dependency-audit/SKILL.md)
2 changes: 2 additions & 0 deletions .agents/coding-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
- **Generic parameters** over explicit variable types (`val list = mutableList<Dependency>()`)
- **Java interop annotations** only when needed (`@file:JvmName`, `@JvmStatic`)
- **Kotlin DSL** for Gradle files
- **Kotlin Protobuf DSL** (`myMessage { field = value }`) over Java builder chains

### ❌ Avoid
- Mutable data structures
- Java-style verbosity (builders with setters)
- Java Protobuf builders in Kotlin code (`newBuilder()`, `toBuilder()`) unless interop requires them
- Redundant null checks (`?.let` misuse)
- Using `!!` unless clearly justified
- Type names in variable names (`userObject`, `itemList`)
Expand Down
5 changes: 5 additions & 0 deletions .agents/documentation-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
- When using TODO comments, follow the format on the [dedicated page][todo-comments].
- File and directory names should be formatted as code.

## Protobuf file headers
- In `.proto` files, a multi-paragraph documentation header must end with a
trailing empty comment line (`//`).
- Single-paragraph headers do not require the trailing empty comment line.

## Avoid widows, runts, orphans, or rivers

Agents should **AVOID** text flow patters illustrated
Expand Down
37 changes: 37 additions & 0 deletions .agents/jvm-project.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# JVM Project Requirements

General requirements for all JVM projects in the Spine SDK organisation.
Repo-specific `project.md` files link here and add their own context.

## Language and build

- **Languages**: Kotlin (primary), Java (secondary).
- **Build**: Gradle with Kotlin DSL.
- **Static analysis**: detekt, ErrorProne, Checkstyle, PMD.
- **Testing**: JUnit 5, Kotest Assertions, Codecov.

## Code review checklist

**Correctness and safety**
- Code compiles and passes static analysis (detekt, ErrorProne, Checkstyle, PMD).
- No reflection or unsafe code unless explicitly approved in scope.
- No analytics, telemetry, or tracking code.
- No blocking calls inside coroutines.

**Kotlin/Java style**
- Kotlin idioms preferred: extension functions, `when` expressions, data/sealed
classes, immutable data structures.
- No `!!` unless provably safe. No unchecked casts.
- No mutable state without justification.
- No string duplication — use constants.

**Tests**
- New or changed functionality must include tests.
- Use stubs, not mocks.
- Prefer [Kotest assertions][kotest-assertions] over JUnit or Google Truth.

**Versioning**
- If the repo has `version.gradle.kts`, every PR must include a version bump.
Flag the absence as a required change.

[kotest-assertions]: https://kotest.io/docs/assertions/assertions.html
17 changes: 17 additions & 0 deletions .agents/memory/MEMORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Team memory index

One line per memory. Scan at the start of every session.
See [README.md](README.md) for the format and routing rules.

## Feedback (validated patterns & corrections)

- [copilot-review-request](feedback/copilot-review-request.md) — GraphQL `requestReviews` with `botIds: ["BOT_kgDOCnlnWA"]`; REST endpoint silently no-ops on re-requests.

## Project (durable context & rationale)

*(no entries yet)*

## Reference (external systems)

- [cache-warm-window](reference/cache-warm-window.md) — How prompt cache entries are shared between sibling-repo sessions and how to maximise overlap.
- [anthropic-api-caching](reference/anthropic-api-caching.md) — Pattern and pricing for adding prompt caching to any direct Anthropic API call.
89 changes: 89 additions & 0 deletions .agents/memory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Team memory — `.agents/memory/`

Validated patterns, durable project context, and pointers to external
systems. Checked into git so the whole team — and any agent working in
this repo — benefits from accumulated knowledge.

This complements Claude Code's built-in per-developer auto-memory:
team-shareable knowledge lives here; personal preferences and ephemeral
state live in the auto-memory.

## Layout

.agents/memory/
├── MEMORY.md # Index — scan at start of every session
├── README.md # This file — read when adding/updating memories
├── feedback/ # Validated patterns & corrections
├── project/ # Durable project context & rationale
└── reference/ # External systems & resources

One file per memory. Filename = the memory's kebab-case slug.

## File format

---
name: tests-no-db-mocks
description: One-line summary — used to surface relevance, so be specific.
metadata:
type: feedback # feedback | project | reference
since: 2026-05-19 # date added (ISO)
---

<one-paragraph rule or fact>

**Why:** <reason — incident, constraint, team convention>

**How to apply:** <when this kicks in; what to do or avoid>

Related: [[other-memory-slug]]

`Why:` and `How to apply:` are required for `feedback` and `project`
memories — they let future readers judge edge cases. `reference`
memories may be shorter (link + one-line purpose).

Link related memories with `[[slug]]` (the target file's `name:`).

## Routing — repo vs. auto-memory

| Kind of fact | Goes to |
|---|---|
| Personal preference, role, style | auto-memory (`user`) |
| Personal habit feedback | auto-memory (`feedback`) |
| Team coding/test/PR rule | **`feedback/`** |
| Durable project rationale | **`project/`** |
| Ephemeral project state (freezes, OOO, deadlines) | auto-memory (`project`) — would rot in git |
| Team-shared external resource | **`reference/`** |
| Personal external resource | auto-memory (`reference`) |

**Litmus test:** *would a teammate joining the project next month benefit
from knowing this?* If no, it belongs in auto-memory.

## Write protocol

1. Write the file **uncommitted** in the working tree.
2. **Surface the change** in the same turn so the human can review.
3. **Do not auto-commit** memory edits as part of an unrelated PR — memory
changes should be reviewable on their own.
4. **Correct in place** when an existing memory turns out wrong; `git blame`
carries the history.
5. **Propose deletion explicitly** when a memory has gone stale, rather
than silently editing it out.

## Updating the index

After adding or removing a memory file, update `MEMORY.md`. One line under
the matching section:

- [slug](category/slug.md) — description from frontmatter

Keep the index short — long descriptions belong in the file body.

## Anti-patterns — do not store

- Anything derivable from the code (module structure, paths, conventions
visible in source). Use `grep` / `Read`.
- Recent-activity summaries or PR lists — `git log` is authoritative.
- Fix recipes for specific bugs — the commit message belongs in the commit.
- Anything already documented in `.agents/` reference docs — keep one
source of truth.
- Personal preferences (see routing).
Empty file.
35 changes: 35 additions & 0 deletions .agents/memory/feedback/copilot-review-request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: copilot-review-request
description: How to request or re-request a Copilot PR review programmatically — GraphQL botIds is the only reliable path
metadata:
type: feedback
since: 2026-05-25
---

Use the GraphQL `requestReviews` mutation with `botIds` for both initial
requests and re-requests:

```bash
gh api graphql -f query='
mutation {
requestReviews(input: {
pullRequestId: "PR_NODE_ID",
botIds: ["BOT_kgDOCnlnWA"]
}) {
pullRequest { id number }
}
}'
```

- `PR_NODE_ID`: `gh api repos/SpineEventEngine/REPO/pulls/NUMBER --jq '.node_id'`
- `BOT_kgDOCnlnWA`: fixed node ID for the Copilot PR reviewer bot (stable)

**Why:** The REST endpoint (`POST .../requested_reviewers` with
`reviewers[]=Copilot`) silently no-ops on re-requests — it only works for
the first-ever request on a PR. The GraphQL `userIds` field also fails
because Copilot is a Bot, not a User. `botIds` is the correct field and
works for both initial and re-requests.

**How to apply:** Any time a Copilot review needs to be requested or
re-requested, use the GraphQL mutation above. Do not use the REST endpoint
or `@copilot review` comments.
Empty file added .agents/memory/project/.gitkeep
Empty file.
Empty file.
52 changes: 52 additions & 0 deletions .agents/memory/reference/anthropic-api-caching.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: anthropic-api-caching
description: Pattern and pricing for adding prompt caching to any direct Anthropic API call.
metadata:
type: reference
since: 2026-05-24
---

Use this when adding a direct Anthropic API call (GitHub Actions workflow,
script, or tool) that sends a stable system prompt.

**Add `cache_control` to the system message block:**

```python
system=[{
"type": "text",
"text": "<stable system prompt — skill definition, shared instructions, etc.>",
"cache_control": {"type": "ephemeral", "ttl": "1h"}
}]
```

Use `ttl: "1h"` for any caller whose requests are spaced more than 5 minutes
apart (GitHub Actions jobs, scheduled tasks, skill invocations). Use the
default 5-minute TTL only for tight interactive loops.

**Pricing (input tokens):**

| Operation | Cost multiplier |
|---|---|
| Cache write (5-min TTL) | 1.25× base input price |
| Cache write (1-hour TTL) | 2× base input price |
| Cache read (any TTL) | 0.1× base input price |

A single cache hit within the TTL window recovers the write premium. Multiple
hits within the hour make the 2× write cost negligible.

**Place stable content before dynamic content.** Cache breakpoints apply to
everything *before* the `cache_control` marker. Dynamic per-request content
(user query, file diff, current date) must come after the last breakpoint.

**Monitor hits via the usage object:**
```python
print(response.usage.cache_read_input_tokens) # 0 on miss, >0 on hit
print(response.usage.cache_creation_input_tokens) # tokens written to cache
```

**Future:** once direct API calls exist in this org, consider a cache pre-warm
job triggered on push to `master` — calls the API with `max_tokens: 0` and
`cache_control: {ttl: "1h"}` so the first session after a config change
hits rather than writes.

Related: [[cache-warm-window]]
33 changes: 33 additions & 0 deletions .agents/memory/reference/cache-warm-window.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: cache-warm-window
description: How prompt cache entries are shared between sibling-repo sessions and how to maximise overlap.
metadata:
type: reference
since: 2026-05-24
---

Claude Code sessions share a prompt cache entry when they send byte-identical
content within the cache TTL window. Because `migrate` copies `CLAUDE.md` and
`.agents/` verbatim, any two sessions on the same config version share the
same cache slot — provided they fall within the TTL.

**TTL in effect for Console OAuth users:**
- Default: **5 minutes** (applies to all non-subscription auth)
- With `ENABLE_PROMPT_CACHING_1H=1` in `~/.claude/settings.json`: **1 hour**

Developers must have `ENABLE_PROMPT_CACHING_1H=1` set, otherwise the
window is too short for cross-session hits to occur reliably.
This setting will work ONLY for Claude Code which runs the CLI binary.
It will not work for JetBrains Air or any other IDE plugin which does not
run the Claude Code CLI binary.

**Cache is per Anthropic workspace.** All developers authenticated via the
same Anthropic organisation Console org share the same cache pool. Do not
create separate Console workspaces per developer — that would isolate their
cache entries.

**Practical impact:** Realistic concurrency is 1–2 sessions at a time. The
first session after a config change pays the cache-write cost; any session
starting within the next hour (with 1H TTL) reads from cache at 0.1× cost.

Related: [[anthropic-api-caching]]
7 changes: 0 additions & 7 deletions .agents/project-overview.md

This file was deleted.

33 changes: 33 additions & 0 deletions .agents/project.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Project: Spine Compiler

## Overview

Spine Compiler is a collection of tools for generating quality domain models
from Protobuf definitions. It is part of the Spine SDK organisation and powers
code generation across Spine-based projects, turning `.proto` files into rich
domain types with validation, factories, and other model conveniences.

## Architecture

**Role**: Library + Gradle plugin + Protobuf compiler plugin.

The repo is a multi-module Gradle build (`rootProject.name = "spine-compiler"`)
with these modules:

- `api`, `api-tests` — public compiler API and its tests.
- `backend` — core code-generation engine.
- `params` — parameter/configuration model passed to the compiler.
- `cli` — command-line entry point.
- `protoc-plugin` — `protoc` plugin that invokes the compiler.
- `jvm` — JVM-specific code-generation support.
- `gradle-api`, `gradle-plugin` — Gradle integration. `gradle-plugin` is
published separately from the rest of the modules.
- `test-env`, `testlib` — shared test fixtures and utilities.

Module artifacts are published under `io.spine.tools` (see
[`dependencies.md`](../dependencies.md) for the published coordinates). Public
API boundaries live in `api` and `gradle-api`; downstream Spine repos depend
on these.

Read [`.agents/jvm-project.md`](jvm-project.md) for build stack, coding style,
tests, and versioning.
18 changes: 18 additions & 0 deletions .agents/project.template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!-- Template — copy to a sibling repo's .agents/project.md and fill in the
sections below. In the config repo itself this file is a template only. -->

# Project: <name>

## Overview

*One paragraph: what this repo is, what problem it solves, and its role in the
Spine SDK organisation.*

## Architecture

*Role in the org: library / tool / Gradle plugin / application.
Key patterns, public API boundaries, and constraints specific to this repo.*

<!-- JVM projects: uncomment the line below after seeding this file.
Read [`.agents/jvm-project.md`](jvm-project.md) for build stack, coding style, tests, and versioning.
-->
12 changes: 5 additions & 7 deletions .agents/quick-reference-card.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# 📝 Quick Reference Card

```
🔑 Key Information:
- Kotlin/Java project with CQRS architecture
- Follow coding guidelines in Spine Event Engine docs
- Always include tests with code changes
- Version bump required for all PRs
```
🚫 **Do not write to git history** (commit/push/tag/rebase/merge/cherry-pick/reset/`gh pr merge`) without explicit authorization. See
[`safety-rules.md`](safety-rules.md) → *Commits and history-writing*.
Authorization comes only from a skill's `## Commit authorization`
section or from the user's current prompt — never from prior turns or
memory.
Loading
Loading