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
26 changes: 26 additions & 0 deletions .clue/id-ledger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,32 @@ events:
- {id: CH-044, kind: numeric, state: retired, prefix: CH, component: "44"}
- {id: CH-044-open-questions, kind: opaque, state: retired}
- {id: CH-044-tasks, kind: opaque, state: retired}
- {id: CH-045, kind: numeric, state: reserved, prefix: CH, component: "45"}
- {id: TASKS-001, kind: numeric, state: reserved, prefix: TASKS, component: "1"}
- {id: OQ-001, kind: numeric, state: reserved, prefix: OQ, component: "1"}
- {id: CH-045, kind: numeric, state: live, prefix: CH, component: "45"}
- {id: TASKS-001, kind: numeric, state: live, prefix: TASKS, component: "1"}
- {id: OQ-001, kind: numeric, state: live, prefix: OQ, component: "1"}
- {id: RDA-001, kind: numeric, state: reserved, prefix: RDA, component: "1"}
- {id: RDA-002, kind: numeric, state: reserved, prefix: RDA, component: "2"}
- {id: RDA-003, kind: numeric, state: reserved, prefix: RDA, component: "3"}
- {id: RDA-004, kind: numeric, state: reserved, prefix: RDA, component: "4"}
- {id: RBC-005, kind: numeric, state: reserved, prefix: RBC, component: "5"}
- {id: RDA-001, kind: numeric, state: live, prefix: RDA, component: "1"}
- {id: RDA-002, kind: numeric, state: live, prefix: RDA, component: "2"}
- {id: RDA-003, kind: numeric, state: live, prefix: RDA, component: "3"}
- {id: RDA-004, kind: numeric, state: live, prefix: RDA, component: "4"}
- {id: RDA-005, kind: numeric, state: reserved, prefix: RDA, component: "5"}
- {id: RDA-005, kind: numeric, state: live, prefix: RDA, component: "5"}
- {id: RDA-006, kind: numeric, state: reserved, prefix: RDA, component: "6"}
- {id: RDA-007, kind: numeric, state: reserved, prefix: RDA, component: "7"}
- {id: RDA-008, kind: numeric, state: reserved, prefix: RDA, component: "8"}
- {id: RDA-009, kind: numeric, state: reserved, prefix: RDA, component: "9"}
- {id: RDA-006, kind: numeric, state: live, prefix: RDA, component: "6"}
- {id: RDA-007, kind: numeric, state: live, prefix: RDA, component: "7"}
- {id: RDA-008, kind: numeric, state: live, prefix: RDA, component: "8"}
- {id: RDA-009, kind: numeric, state: live, prefix: RDA, component: "9"}
- {id: RBC-005, kind: numeric, state: live, prefix: RBC, component: "5"}
high-water:
- {id: ADR-047, kind: numeric, state: reserved, prefix: ADR, component: "47"}
- {id: AN-001, kind: numeric, state: reserved, prefix: AN, component: "1"}
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

### 🔧 Changes

- Documentation (Rumble):
- Added the canonical APS and rankings guide covering active bot versions, behavior epochs, update cadence, publication freshness, and immutable cumulative month-end snapshots.
- Bot API (.NET, TypeScript):
- `X`, `Y`, `Direction`, `GunDirection`, and `RadarDirection` now fall back to the bot's initial position when read before the first turn of a game, which is what the Java and Python Bot APIs already did. They still throw a `BotException` when no initial position is available.
- Bot API (Python):
Expand Down
2 changes: 1 addition & 1 deletion docs/capabilities/CAP-014-rumble-bot-catalog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ reversal-cost: low

Provide a community-owned, source-only catalog of eligible Tank Royale Rumble bots, so authors can submit bots through reviewable pull requests and battle contributors can retrieve precisely the reviewed source that they run.

The capability is implemented in the external `robocode-dev/rumble-bots` repository. It adopts the Tank Royale booter convention, validates submissions in portable Python, and publishes a generated versioned catalog. Criteria remain draft until their external automated evidence is tagged and registered under P-001/M-002.
The capability is implemented in the external `robocode-dev/rumble-bots` repository. It adopts the Tank Royale booter convention, validates submissions in portable Python, and publishes a generated versioned catalog after a bot pull request is merged. `rumble-data` checks that catalog hourly, publishing a new bot or version while skipping ranking work for identical content. Criteria remain draft until their external automated evidence is registered in this corpus.
10 changes: 10 additions & 0 deletions docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,14 @@ Feature: rumble-bot-catalog — Rumble bot catalog
When the generated catalog is synchronized for ranked clients
Then the team entry carries both member identities in `teamMembers` while individual entries carry an empty list
And generation rejects a missing, inactive, unknown, or nested team member

@RBC-005 @draft
Scenario: Hourly catalog polling publishes only changed reviewed content
Test-type: Integration
Given the normalized local catalog and the reviewed source catalog
When the scheduled synchronization checks the source
Then a changed bot or version is stored and regenerated into current rankings
And identical content is not rewritten or aggregated
And, when no independent publication state changed, no commit or deployment occurs
And catalog and result writers cannot overlap their publication sections
```
2 changes: 1 addition & 1 deletion docs/capabilities/CAP-014-rumble-bot-catalog/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ The catalog schema is additive within a schema version: readers ignore fields th

## External evidence

The external `robocode-dev/rumble-bots` repository holds the implementation and focused integration tests for RBC-001 through RBC-003 at merged commit `c735e6ff4`. [rumble-bots#3](https://github.com/robocode-dev/rumble-bots/pull/3) at `d58e6b5` adds RBC-004 positive and negative evidence for TwinDuel membership, including rejection of malformed catalog entries. Run `python -m unittest discover -s tests -v` and `scripts/validate_bot.py --root . --owner flemming-n-larsen --smoke` in that repository to reproduce the evidence. During P-001/M-002, those tests will receive their RBC purpose tags and this criteria artifact can become active without changing the criterion meanings.
The external `robocode-dev/rumble-bots` repository holds the implementation and focused integration tests for RBC-001 through RBC-003 at merged commit `c735e6ff4`. [rumble-bots#3](https://github.com/robocode-dev/rumble-bots/pull/3) at `d58e6b5` adds RBC-004 positive and negative evidence for TwinDuel membership. Merged [rumble-data#12](https://github.com/robocode-dev/rumble-data/pull/12) adds RBC-005 evidence that normalized unchanged polls are not rewritten or aggregated and that changed bot/version catalogs enter the serialized publication path. Run each external repository's Python test suite to reproduce the evidence; criteria remain draft here until the external evidence can be registered in this corpus.
2 changes: 1 addition & 1 deletion docs/capabilities/CAP-015-rumble-result-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ reversal-cost: low

Provide an auditable, machine-written record of ranked Tank Royale Rumble battles, so contributors can submit results without write access and everyone can reproduce the leaderboard and match advice from immutable facts.

The capability is implemented in the external `robocode-dev/rumble-data` repository. Its portable Python scripts validate issue-ops batches, append accepted facts, derive projections, and serve the static dashboard. Criteria remain draft until their external automated evidence is registered under P-001/M-002.
The capability is implemented in the external `robocode-dev/rumble-data` repository. Its portable Python scripts validate issue-ops batches, append accepted facts, derive cumulative active-version projections, publish meaningful ranking freshness, and preserve immutable month-end dashboard snapshots. Criteria remain draft until their external automated evidence is registered in this corpus.
33 changes: 33 additions & 0 deletions docs/capabilities/CAP-015-rumble-result-data/criteria.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,37 @@ Feature: rumble-result-data — Rumble result data
Then `1v1` and `melee` admit only the pinned number of distinct active individual entries
And `twinduel` admits exactly two distinct active teams whose catalog members are active individuals, expand to the pinned participant count, and have disjoint member identities
And validation rejects a team in an individual game type, an individual in TwinDuel, or a result whose catalog membership, eligibility, or member disjointness is invalid

@RDA-006 @draft
Scenario: APS gives each distinct pairing equal weight within the active ranking epoch
Test-type: Integration
Given eligible facts for the current behavior version and the catalog's active bot versions
When a game type's leaderboard is generated
Then repeated battles are averaged within their exact participant pairing and APS is 100 times the mean of those pairing averages
And each pairing has equal weight regardless of its battle count
And a superseded participant or another behavior version does not contribute, while an active version with no samples has APS zero

@RDA-007 @draft
Scenario: Publication freshness changes only when current ranking data changes
Test-type: Integration
Given a current leaderboard and its recorded ranking-tree hash and publication time
When publication regenerates or reconciles the current leaderboard
Then a changed ranking tree advances `lastUpdatedAt`
And identical ranking output, deployment, or snapshot creation preserves the previous time

@RDA-008 @draft
Scenario: The first writer after a UTC month boundary preserves immutable cumulative history
Test-type: Integration
Given the current cumulative leaderboard and its month cursor
When a serialized writer first runs in a later UTC month
Then it copies current leaderboard and bot-detail JSON byte for byte for every completed month before accepting new input
And it never resets the live ranking or alters an existing snapshot

@RDA-009 @draft
Scenario: A dashboard viewer can distinguish current rankings from read-only monthly history
Test-type: E2E
Given current and archived leaderboard data listed in the publication history manifest
When a viewer selects Current or a completed month and a game type
Then the dashboard loads the corresponding leaderboard and bot details
And it shows the ranking update time and identifies an archived month as read-only
```
8 changes: 5 additions & 3 deletions docs/capabilities/CAP-015-rumble-result-data/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ An issue-ops submission is one fenced JSON batch envelope with `schemaVersion`,

## Projection and moderation contracts

`scripts/aggregate.py` is a pure function of raw facts and rollups, `catalog.json`, `engine.json`, registrations, `bans.json`, and `exclusions.json`. It emits one versioned leaderboard, pairing-statistics file, matches-needed file, and bot detail shard per game type, plus contributor totals. The projection identifier hashes its relevant inputs. Rankings use only the current `behaviorVersion` epoch and active bot versions.
`scripts/aggregate.py` is a pure function of raw facts and rollups, `catalog.json`, `engine.json`, registrations, `bans.json`, and `exclusions.json`. It emits one versioned leaderboard, pairing-statistics file, matches-needed file, and bot detail shard per game type, plus contributor totals. The projection identifier hashes its relevant inputs. Rankings use only the current `behaviorVersion` epoch and matchups whose complete participant set contains active, game-type-eligible identities. A new active version starts at zero samples, and a matchup containing a superseded identity stops affecting every participant's current APS.

CI serializes ingestion and is the sole writer of facts and projections on `main`. Moderators never rewrite a fact: an exclusion, ban, disqualification, or removed registration only affects the next recomputation. Monthly rollups replace raw files older than three full months on the archive branch after an equivalent projection is verified, retaining the event-sourcing guarantee.
CI serializes result and catalog publication and is the sole writer of facts and projections on `main`. Moderators never rewrite a fact: an exclusion, ban, disqualification, or removed registration only affects the next recomputation. Monthly rollups replace raw files older than three full months on the archive branch after an equivalent projection is verified, retaining the event-sourcing guarantee.

`scripts/publication.py` owns operational metadata and history rather than putting a clock in aggregation. It hashes current leaderboard and bot-detail JSON, advances `lastUpdatedAt` only when that visible tree changes, and snapshots completed UTC months before the first writer reads new input. Snapshots are cumulative, append-only publication records; they do not reset the live ranking and are never rewritten by late results. Changed writer commits explicitly dispatch Pages, with an hourly tree comparison as a missed-deployment fallback.

## External evidence

The external `robocode-dev/rumble-data` repository holds the implementation and focused suite for RDA-001 through RDA-004. [rumble-data#4](https://github.com/robocode-dev/rumble-data/pull/4) added every-ranked-type matchmaking advice and catalog-synchronization coverage and was accepted at merge commit `18e916e4a381c8108568d7ca77e3e14d88dd4583`; M-007 is complete. [rumble-data#7](https://github.com/robocode-dev/rumble-data/pull/7) at `83e71d4` adds RDA-005 positive and negative validation and advice-generation evidence, including TwinDuel member disjointness while preserving repeated member slots within a team. [rumble-data#10](https://github.com/robocode-dev/rumble-data/pull/10) corrects the GitHub issue-submitter extraction with focused RDA-001 evidence. CH-032 then proved the live path: [rumble-data#11](https://github.com/robocode-dev/rumble-data/issues/11) accepted the client batch, and `f25c02f20e2938545563a0d2a017e53e9a208a7e` published the resulting facts and projections. Run `python -m unittest discover -s tests -v` in that repository to reproduce the evidence. During P-001/M-002, the external-evidence reconciliation set must include RDA-001 through RDA-005 before this criteria artifact can become active without changing the criterion meanings.
The external `robocode-dev/rumble-data` repository holds the implementation and focused suite for RDA-001 through RDA-005, including the accepted live client path. Merged [rumble-data#12](https://github.com/robocode-dev/rumble-data/pull/12) adds RDA-006 through RDA-009 evidence for pairing-first APS, active-version matchup filtering, ranking-tree freshness, immutable rollover, deployment reconciliation, and current/history dashboard selection. Run `python -m unittest discover -s tests -v` in that repository to reproduce the evidence. The criteria remain draft here until the external evidence can be registered in this corpus.
6 changes: 3 additions & 3 deletions docs/design/rumble/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Changes (CH-xxx, via the `clue-delta` loop) should be created in this order; eac
| 2 | `create-rumble-bots-repo` | Define and scaffold the bot submission repository: source-only layout, validation, ownership, slot budget, templates, governance, and generated catalog. | Tank Royale prep |
| 3 | `create-rumble-data-repo` | Define and scaffold the data repository: result inbox, validation, raw facts, aggregation, compaction, matchmaking projections, dashboard, and GitHub Pages publishing. | Tank Royale prep |
| 4 | `create-rumble-client` | Build the ranked/practice client, local journal, replay evidence store, container, and issue-ops submission transport; defer fork-PR submission until `rumble-data` supports it. | `rumble-bots` catalog and `rumble-data` engine/matchmaking files |
| 5 | `publish-rumble-docs` | Publish the user guides, onboarding flow, moderator handbook, FAQ, dashboard participation page, ADRs, and contributor-facing architecture docs. | Interfaces from the previous proposals |
| 5 | `publish-rumble-docs` | Publish the audience guides, canonical rankings reference, dashboard links, governance guidance, and contributor-facing architecture docs. | Interfaces from the previous proposals |

The first proposal is intentionally a Tank Royale preparation change, not a Rumble implementation. It should make the existing engine, schema, Battle Runner, and bot metadata ready for the later repositories without creating those repositories.

Expand All @@ -112,7 +112,7 @@ These directions keep the sub-documents consistent and should be reflected in th

| Direction | Where detailed |
|-----------|----------------|
| **Ruleset and scoring = RoboRumble/LiteRumble, unchanged** (APS primary; Win%, Survival, Vote, NPP/ANPP, KNNPBI, Glicko-2). Battle tested for two decades; do not reinvent. | Aggregation doc |
| **APS uses the RoboRumble/LiteRumble pairing-first principle.** Current output is APS plus battle and pairing counts; unimplemented classic metrics are not part of the current contract. | Aggregation doc |
| **V1 battle types are 1v1, TwinDuel, and Melee.** These follow the popular LiteRumble/RoboRumble categories for the original game. TwinDuel is the 2v2 twin-team format. Mini, micro, nano, and giga categories are out of v1 because bytecode-size limits do not translate cleanly to source-code bots across multiple languages. | Client + aggregation docs |
| **Own-bot priority: yes**, with the self-reported-only marker plus independent confirmation for trust. | Client doc |
| **Engine pinning by `behaviorVersion`.** Release versions stay lockstep across all Tank Royale artifacts (the right model for the product); a separate integer `behaviorVersion`, owned by the server and bumped only on game-observable changes (server physics/scoring/turn processing/RNG plus Bot API behavior), is the compatibility contract. Compatibility, client rollout, and result **epochs** all key on it; releases that do not bump it (e.g. GUI-only) cause no rollout and no epoch reset. Supersedes the earlier patch-vs-minor rule. | Client + aggregation docs |
Expand Down Expand Up @@ -140,7 +140,7 @@ These directions keep the sub-documents consistent and should be reflected in th
| **Documentation is a first-class design area**: published user docs are Markdown under `/web/docs/rumble/`, internal ADRs and architecture descriptions stay under `/docs`, one quickstart exists per audience, error messages link into the published docs, and onboarding friction is budgeted. | User documentation doc |
| **No per-client contribution cap**, matching the classic rumble (verified on the RoboWiki): saturation is handled by the priority mechanism alone; `targetSamplesPerPairing` plays the classic `BATTLESPERBOT` role. | Client + aggregation docs |
| **SPDX `license` field joins the general booter bot config schema** (not rumble-only); implementation lands in the Tank Royale repo when the design leaves draft. | Submission doc |
| **Docs and repos are versioned by the Tank Royale version**: both repos are tagged at every engine pin change; docs always describe the pinned engine, old tags serve old readers. Template bots per platform ship in `rumble-bots`; scoring explanations live in the Rumble FAQ, linked from dashboard column headers. | User documentation doc |
| **Docs and repos are versioned by the Tank Royale version**: both repos are tagged at every engine pin change; docs always describe the pinned engine, old tags serve old readers. The canonical scoring explanation lives at `/rumble/rankings` and is linked from the dashboard. | User documentation doc |

## Game Type References

Expand Down
Loading
Loading