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
15 changes: 10 additions & 5 deletions .agent-instructions/solidstats/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ is present and readable:

If any file is missing or unreadable, stop product work and restore the complete
bundle with the canonical installer. Do not continue from partial instructions,
infer missing routing, or substitute another memory store. Contract freshness
is managed by the repository rollout; do not perform a remote update check at
task start.
infer missing routing, or substitute another store for SolidStats memory.
Contract freshness is managed by the repository rollout; do not perform a
remote update check at task start.

## Skills First

Expand Down Expand Up @@ -171,8 +171,13 @@ means no repository-bound archive).

The main agent owns the contract-defined recall and closure capture for the
top-level task. Specialists and subagents receive filtered context and must not
independently query or mutate SolidStats memory. Never substitute a generic,
personal, VocalClub, or flat-global memory store.
independently query or mutate SolidStats memory. Do not substitute another store
for SolidStats project memory. Independently relevant sources follow their own
contracts.

Select relevant recall by task subject, including external or cross-project
work, under the source memory contract. Keep recall sources, knowledge owners,
and the scope of repository rules distinct as defined in `MEMORY.md`.

The native GSD MemPalace capability is deliberately disabled. `GSD.md` keeps
SolidStats memory active through coordinator-owned recall and semantic closure;
Expand Down
2 changes: 1 addition & 1 deletion .agent-instructions/solidstats/CONTRACT_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.0
1.3.1
9 changes: 5 additions & 4 deletions .agent-instructions/solidstats/GSD.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ semantics.

## Coordinator-owned recall

The main GSD coordinator runs the federated recall from `MEMORY.md` at most
The main GSD coordinator runs the thematic recall from `MEMORY.md` at most
once per top-level GSD task:

- before discussion questions for discuss-oriented entry points;
Expand All @@ -55,7 +55,7 @@ planning or execution, do not recall again. A resumed or compacted task keeps
the same top-level ownership if the provenance-bearing context is still
available.

Run the initial wing searches in the first tool batch after repository and
Run the initial thematic search in the first tool batch after repository and
contract routing is known. Fold relevant, verified facts into the discussion
and owner-native `CONTEXT.md` when discussion owns that artifact. For other
entry points, pass a compact memory context block directly to the relevant
Expand Down Expand Up @@ -83,5 +83,6 @@ the generic MemPalace curator.
## Failure behavior

If `solidstats_memory` is unavailable, follow the one-retry and primary-evidence
fallback contract in `MEMORY.md`. GSD continues; it must not use a different
palace, generic CLI, flat memory, or local outbox.
fallback contract in `MEMORY.md`. GSD continues from current primary evidence;
it must not substitute another store, generic CLI, flat memory, or local outbox
for SolidStats project memory.
110 changes: 67 additions & 43 deletions .agent-instructions/solidstats/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,24 @@ canonical `config/repositories.tsv` manifest. The rendered companion
`AGENTS.md` in each repository declares that repository's primary active wing
and primary archive wing.

Select useful memory by the task's subject, including external and cross-project
tasks, independently of the current directory, chat, or destination of the result.
Keep three boundaries separate: the source used for recall, the owner of new
knowledge, and the scope in which source instructions apply. Reading SolidStats
memory does not make an external repository a manifest consumer or apply all
SolidStats repository rules to it.

Before external recall, load this canonical contract from
`solid-stats/agent-instructions/shared/MEMORY.md` and apply its existing access,
recall, subagent, capture, and outage gates. Each source owner's contract
exclusively governs its memory lifecycle; a generic contract must not fill its
silent parts or substitute another lifecycle.

## Instance and authority boundary

- Use only the MCP server named `solidstats_memory` for SolidStats memory.
- Never use a generic `mempalace`, `mempalace_personal`, `vocalclub_memory`,
flat global memory, or a local outbox as a substitute.
- Do not substitute another store, flat memory, or a local outbox for SolidStats
project memory. Other relevant sources remain governed by their own contracts.
- The shared bearer token does not provide personal attribution or per-tool
authorization. Treat every mutation as privileged.
- Current user instructions and applicable repository instructions have the
Expand Down Expand Up @@ -98,30 +111,25 @@ memory. A nested workflow does not create a second memory lifecycle.

If `solidstats_memory` is unavailable, retry one safe read once later in the
same task, continue from current primary evidence, and warn in the final
handoff. Never fall back to another palace, flat memory, or a local outbox.

## Federated recall

Unfiltered top-k search is forbidden. Run separate wing-filtered searches with
the same short, identifier-heavy query in every initial call. Keep task
background in the tool's context field rather than the embedded query.

For a role-primary repository, initial candidate budgets are:

1. up to 5 results from its primary active role wing;
2. up to 3 results from `common`;
3. up to 2 results from each other active role wing;
4. up to 2 results from the current repository's primary archive wing;
5. up to 2 results from a foreign archive only after current evidence proves
the dependency and promotes that archive.

For a `common`-primary repository, search `common` for up to 5 candidates and
each of the four role wings for up to 2. Supporting repositories have no
primary archive.

These are discovery budgets, not quotas for working context. Search every
active wing exactly once during initial discovery, but keep only relevant
candidates with usable provenance.
handoff. Do not substitute another palace, flat memory, or a local outbox for
SolidStats project memory.

## Thematic recall and coverage

Default to a short thematic search across the whole selected SolidStats palace,
including active and archive wings. Use identifiers from the task and keep
background in the tool's context field rather than the embedded query. Where
the exposed schema permits, 20 candidates is a reasonable initial limit;
increase it adaptively within a bounded search when useful context is missing.
This is candidate discovery, not permission to dump the corpus.

Wing filters are optional refinements for noise or suspected misses, not
mandatory federation across every active wing or an advance promotion gate.
Choose refinements by usefulness to the subject, independently of repository
ownership. For example, if the initial 20 results are all historical archive
leads, refine into the relevant active wing or room and adjust the bounded
limit to check current semantic context. Keep only useful candidates with
usable provenance; neither a full result limit nor a miss proves coverage.

For every candidate that may influence the task:

Expand All @@ -135,42 +143,53 @@ For every candidate that may influence the task:
Explicit tunnels, temporal KG facts, and diaries are not part of SolidStats
recall. Do not query or create them.

## Evidence-seeded expansion
## Evidence-seeded refinement

Seed the first queries from identifiers already present in the request: issue
keys, branch or commit names, endpoints, entities, services, exact errors, or
symptoms. Use the same identifiers in every initial active-wing search.

Promote an active wing or foreign archive only when a relevant drawer or a
verified current source proves the dependency. Follow-up query terms may come
only from:
symptoms. Follow-up query terms may come only from:

- the user request;
- a relevant fetched drawer;
- a verified current primary source.

A promoted active wing has no fixed follow-up limit. Continue while new results
change the task model; stop when they repeat, become irrelevant, or add no new
verified identifiers. Promotion lasts only for the current top-level task.
Refine the query, bounded limit, or wing/room scope while results change the
task model; stop when they repeat, become irrelevant, or add no useful context.
Check coverage when a new substantive topic appears or relevant context is lost
after compaction. Reuse complete applicable findings instead of querying every
reply. Archive leads remain historical and require current verification;
their visibility in search never makes them current authority.

## Scoped miss fallback

A semantic search miss is not proof that memory is absent. For the primary
wing, `common`, the primary archive, and every promoted scope:
A semantic search miss is not proof that memory is absent. For likely relevant
scopes, including active or archive wings as useful:

1. retry with an alternate query seeded from current evidence;
2. inspect that wing's rooms;
3. list a bounded set of drawers in the likely wing and room;
4. fetch plausible drawers by exact ID;
5. report no relevant memory only after these scoped checks fail.

Do not widen an unpromoted foreign archive after a miss.
Do not enumerate unrelated wings or dump the corpus to manufacture coverage.

## Source scope and knowledge destination

SolidStats project knowledge stays with its project owner even when another
project or a skill uses it. Reading another source does not transfer ownership
or make that source's repository rules apply here. This contract governs only
SolidStats memory; other sources and their knowledge owners follow their own
contracts, including access and capture authority.

For example, an external skill-design task may read a relevant SolidStats
convention under this contract without applying SolidStats Git rules to the
skill repository. The SolidStats-specific convention stays here.

## Durable capture gate

Before the first final handoff that closes a completed top-level task, classify
its verified semantic conclusions. Capture only knowledge useful beyond the
task:
its verified semantic conclusions. Capture only SolidStats project knowledge
useful beyond the task:

- an accepted decision;
- an API, data, parser, queue, or integration contract;
Expand Down Expand Up @@ -262,13 +281,18 @@ records may remain unpromoted.
## Acceptance invariants

- `solidstats_memory` is the only SolidStats MCP namespace.
- Personal and VocalClub memory remain isolated.
- Initial recall searches all five active wings with the accepted budgets.
- Archive lookup stays scoped, evidence-promoted, and read-only.
- Other stores do not substitute for SolidStats project memory; their own
contracts govern independently relevant sources.
- Recall follows the subject across the selected palace with bounded adaptive
limits; wing filters refine noise or misses rather than mandate federation.
- External recall loads this source contract without importing repository rules.
- Archive lookup remains historical, verified against current sources, and read-only.
- Relevant drawers are fetched and source-checked before use.
- Semantic miss fallback is bounded and wing-scoped.
- Tunnels, KG, diary, raw GSD artifacts, and agent wings are absent.
- Durable capture writes one verified fact once; no conclusion means no write.
- Recall sources, knowledge owners, and instruction scopes remain distinct;
SolidStats project knowledge stays with its project owner.
- Corrections require exact curator preview, approval, mutation, and read-back.
- UAT creates no permanent data.
- Every consumer repository carries the same accepted contract version.
35 changes: 23 additions & 12 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

[Русский](README.md) · **English**

TypeScript backend and source of truth for **Solid Stats** — game statistics for the
[Solid Games](https://sg.zone) (ArmA 3) community. It owns the HTTP API, business state in
PostgreSQL, canonical player identity, Steam sign-in, moderation, parser job orchestration,
and the statistics and bounty calculation.
TypeScript backend and source of truth for **Solid Stats** — game statistics
for the [Solid Games](https://sg.zone) (ArmA 3) community. It owns the HTTP API,
business state in PostgreSQL, canonical player identity, Steam sign-in,
moderation, parser job orchestration, and the statistics and bounty calculation.

Part of a multi-repo platform: raw replay discovery lives in `replays-fetcher`, OCAP parsing
in `replay-parser-2`, the web interface in `web`, and runtime/operations in `infrastructure`.
server-2 is the integration layer where they meet.
Part of a multi-repo platform: raw replay discovery lives in `replays-fetcher`,
OCAP parsing in `replay-parser-2`, the web interface in `web`, and
runtime/operations in `infrastructure`. server-2 is the integration layer
where they meet.

> Solid Stats is built end to end by AI agents via the
> [GSD](https://github.com/open-gsd/gsd-core) process. Development outside GSD is outside the process.
> [GSD](https://github.com/open-gsd/gsd-core) process.
> Development outside GSD is outside the process.

## Quick start

Expand All @@ -23,13 +25,22 @@ docker compose up -d postgres rabbitmq minio minio-create-bucket
pnpm run dev
```

PostgreSQL listens on host port `15432`, RabbitMQ on `5673` (management `15673`): these
non-standard ports avoid clashes with common local services. Before committing, run the
`pnpm run verify` gate (format, lint, types, tests, OpenAPI contract, boundaries).
PostgreSQL listens on host port `15432`, RabbitMQ on `5673` (management `15673`):
these non-standard ports avoid clashes with common local services. Before
committing, run the `pnpm run verify` gate (format, lint, types, tests, OpenAPI
contract, boundaries).

MinIO and `mc` are built from pinned upstream commits in
`docker/minio.Dockerfile`; the first startup downloads Go dependencies and
compiles both binaries. This follows
[MinIO's source-only distribution](https://github.com/minio/minio#source-only-distribution)
(checked 2026-10-24). To rebuild after changing the pinned versions, run
`docker compose build minio minio-create-bucket`.

## Documentation

- docs/backend-reference.md — runtime surfaces, contract policy, statistics, auth, DB schema
- docs/backend-reference.md — runtime surfaces, contract policy, statistics,
auth, DB schema
- docs/deployment.md · docs/backup-restore.md — deployment and recovery
- docs/api-compatibility.md — the OpenAPI contract and type generation for `web`
- .planning/ — product context, milestone, roadmap, state (GSD)
Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@ PostgreSQL слушает на хост-порте `15432`, RabbitMQ — на `
с локальными сервисами. Перед коммитом гоняйте гейт `pnpm run verify`
(формат, линт, типы, тесты, контракт OpenAPI, границы).

MinIO и `mc` собираются из закреплённых коммитов upstream в
`docker/minio.Dockerfile`; первый запуск требует загрузки Go-зависимостей
и компиляции. Это соответствует
[переходу MinIO на распространение исходников](https://github.com/minio/minio#source-only-distribution)
(проверено 2026-10-24). Для пересборки после изменения закреплённых версий:
`docker compose build minio minio-create-bucket`.

## Документация

- docs/backend-reference.md — рантайм-поверхности, политика контракта, статистика, auth, схема БД
- docs/backend-reference.md — рантайм-поверхности, политика контракта,
статистика, auth, схема БД
- docs/deployment.md · docs/backup-restore.md — деплой и восстановление
- docs/api-compatibility.md — контракт OpenAPI и генерация типов для `web`
- .planning/ — продуктовый контекст, milestone, роадмап, состояние (GSD)
Expand Down
10 changes: 8 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ services:
retries: 12

minio:
image: quay.io/minio/minio:latest
build:
context: ./docker
dockerfile: minio.Dockerfile
target: minio
command: server /data --console-address :9001
environment:
MINIO_ROOT_USER: solid
Expand All @@ -43,7 +46,10 @@ services:
retries: 12

minio-create-bucket:
image: quay.io/minio/mc:latest
build:
context: ./docker
dockerfile: minio.Dockerfile
target: mc
depends_on:
minio:
condition: service_healthy
Expand Down
17 changes: 17 additions & 0 deletions docker/minio.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM golang:1.24.13-alpine3.23 AS build
ENV CGO_ENABLED=0 GOTOOLCHAIN=local

# MinIO RELEASE.2025-09-07T16-13-09Z and mc RELEASE.2025-08-13T08-35-41Z.
RUN go install -trimpath github.com/minio/minio@07c3a429bfed433e49018cb0f78a52145d4bedeb \
&& go install -trimpath github.com/minio/mc@7394ce0dd2a80935aded936b09fa12cbb3cb8096

FROM alpine:3.23.2 AS runtime
RUN apk add --no-cache ca-certificates curl

FROM runtime AS minio
COPY --from=build /go/bin/minio /usr/local/bin/minio
ENTRYPOINT ["minio"]

FROM runtime AS mc
COPY --from=build /go/bin/mc /usr/local/bin/mc
ENTRYPOINT ["mc"]
Loading