From fe49ce24c2bdd7e4e82ced8121c59bc33c8eb56c Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 12:46:10 +0200 Subject: [PATCH 01/11] docs(CH-031): propose Rumble client completion --- .clue/id-ledger.yaml | 13 ++++- .../open-questions.md | 11 +++++ .../CH-031-complete-rumble-client/proposal.md | 47 +++++++++++++++++++ .../CH-031-complete-rumble-client/tasks.md | 25 ++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 changes/CH-031-complete-rumble-client/open-questions.md create mode 100644 changes/CH-031-complete-rumble-client/proposal.md create mode 100644 changes/CH-031-complete-rumble-client/tasks.md diff --git a/.clue/id-ledger.yaml b/.clue/id-ledger.yaml index c0f684d5d..d23449fc3 100644 --- a/.clue/id-ledger.yaml +++ b/.clue/id-ledger.yaml @@ -4,7 +4,7 @@ counters: ARCH: "26" C: "4" CAP: "17" - CH: "30" + CH: "31" G: "1" GTD: "1" IDR: "4" @@ -640,6 +640,17 @@ entries: - id: CH-030-tasks kind: opaque state: live + - id: CH-031 + kind: numeric + state: live + prefix: CH + component: "31" + - id: CH-031-open-questions + kind: opaque + state: live + - id: CH-031-tasks + kind: opaque + state: live - id: G-001 kind: numeric state: live diff --git a/changes/CH-031-complete-rumble-client/open-questions.md b/changes/CH-031-complete-rumble-client/open-questions.md new file mode 100644 index 000000000..886314ea9 --- /dev/null +++ b/changes/CH-031-complete-rumble-client/open-questions.md @@ -0,0 +1,11 @@ +--- +id: CH-031-open-questions +type: open-questions +status: open +links: [CH-031] +title: Open questions for CH-031 +--- + +# CH-031 — Open questions + +No blocking questions are open. CAP-016, ADR-043, ADR-044, ADR-046, IDR-004, and the published `rumble-bots` and `rumble-data` contracts govern implementation. Any incompatible external contract or need for a credential-bearing live test becomes a blocking question and stops the change before that external side effect. diff --git a/changes/CH-031-complete-rumble-client/proposal.md b/changes/CH-031-complete-rumble-client/proposal.md new file mode 100644 index 000000000..768d5184b --- /dev/null +++ b/changes/CH-031-complete-rumble-client/proposal.md @@ -0,0 +1,47 @@ +--- +id: CH-031 +type: change +status: open +links: [P-003, M-008, CAP-016] +title: Complete the Rumble client locally +--- + +# CH-031 — Complete the Rumble client locally + +## What + +Complete `robocode-dev/rumble-client` so a registered contributor can synchronize one reviewed Rumble snapshot, select and execute pinned battles through the locally built Battle Runner, retain replay-bound result evidence, durably journal completed ranked results, and submit acknowledged issue-ops batches without repository-content write access. + +## Why + +P-003/M-008 is the next unfinished Rumble milestone. Configuration, ranked synchronization, selection, bot-cache preparation, and runtime packaging already exist in the external client, while battle execution, durable result handling, submission, and end-to-end evidence remain unfinished. BR-049 is merged and may be consumed from a local Tank Royale build, so development no longer depends on a public Tank Royale release. + +## Route + +Recommended route: full. This change completes accepted CAP-016 behavior and binds cross-repository acceptance evidence for M-008. Discovery would change the route only if the external client already satisfies and evidences all RCL criteria, reducing the work to evidence reconciliation. + +## Plan + +Serves [P-003/M-008](../../docs/plans/P-003-rumble.md) and supersedes the incomplete implementation references to CH-012 and CH-030 without changing the accepted RCL criterion meanings. + +## Scope + +- Verify and complete the existing RCL-001 through RCL-003 configuration, synchronization, cache, and seeded-selection paths. +- Add a reproducible local Tank Royale dependency path so client development and CI can consume the merged Runner BR-049 API without publishing Tank Royale. +- Implement strict ranked/practice separation, full-round Battle Runner execution, complete result transcription, and replay retention for RCL-004 and RCL-005. +- Implement append-only journaling, epoch quarantine, receipt-driven retry, and bounded Issues-only submission for RCL-006 and RCL-007. +- Complete the multi-runtime execution and network-boundary evidence for RCL-008. +- Prove RCL-009 through an automated clean-install flow spanning the client and result-data ingestion contracts. +- Digest verified external evidence into CAP-016 and P-003 only after the M-008 exit criterion is demonstrably met. + +## Non-goals + +- Publishing Tank Royale 1.2.0 or any other release solely to support client development. +- Changing Rumble game behavior, the Runner public API, the accepted result envelope, or `rumble-data` ingestion semantics unless a blocking incompatibility is first recorded and approved. +- Granting repository-content, branch, release, package, Pages, fact, or projection write access to a client credential. +- Central services, centrally stored replay files, persistent secrets, or fork-pull-request result transport. +- Completing the separate M-009 user-documentation milestone. + +## Compatibility + +Local development uses the merged Runner source while ranked distribution remains gated on an immutable released Runner artifact. Ranked execution fails closed on unsupported schemas, inconsistent snapshots, source-hash or identity mismatches, incomplete battles, and behavior-version incompatibility. Practice mode has no path to ranked journal or submission state. diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md new file mode 100644 index 000000000..f1203ab87 --- /dev/null +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -0,0 +1,25 @@ +--- +id: CH-031-tasks +type: tasks +status: open +links: [CH-031] +title: Task breakdown for CH-031 +--- + +# CH-031 — Tasks + +- [x] Reserve CH-031 and branch from the accepted tip of `main` +- [x] Inventory merged `rumble-client` work and confirm the local Runner development path +- [x] Capture the completion proposal and full-route scope +- [ ] Commit and push the proposal, then open the required draft PR before implementation +- [ ] Verify and complete RCL-001 configuration validation before side effects +- [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation +- [ ] Verify and complete RCL-003 seeded ranked selection for all V1 game types +- [ ] Implement and test local BR-049 Runner dependency substitution for development and CI +- [ ] Implement and test RCL-004 and RCL-005 mode separation, full-round execution, result transcription, and replay evidence +- [ ] Implement and test RCL-006 append-only journaling, epoch quarantine, and receipt-driven retry +- [ ] Implement and test RCL-007 bounded Issues-only submission without repository-content access +- [ ] Complete and test RCL-008 multi-runtime execution and the container network boundary +- [ ] Implement and test RCL-009 automated clean-install ingestion into immutable `rumble-data` facts +- [ ] Reconcile external evidence, CAP-016 status, stale CH-012 references, and P-003/M-008 bookkeeping + From 7f64e007b0a0d3064e81125cc2c7012e466a848c Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 12:46:25 +0200 Subject: [PATCH 02/11] docs(CH-031): record proposal publication --- changes/CH-031-complete-rumble-client/tasks.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index f1203ab87..c457752e5 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -11,7 +11,7 @@ title: Task breakdown for CH-031 - [x] Reserve CH-031 and branch from the accepted tip of `main` - [x] Inventory merged `rumble-client` work and confirm the local Runner development path - [x] Capture the completion proposal and full-route scope -- [ ] Commit and push the proposal, then open the required draft PR before implementation +- [x] Commit and push the proposal, then open the required draft PR before implementation - [ ] Verify and complete RCL-001 configuration validation before side effects - [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation - [ ] Verify and complete RCL-003 seeded ranked selection for all V1 game types @@ -22,4 +22,3 @@ title: Task breakdown for CH-031 - [ ] Complete and test RCL-008 multi-runtime execution and the container network boundary - [ ] Implement and test RCL-009 automated clean-install ingestion into immutable `rumble-data` facts - [ ] Reconcile external evidence, CAP-016 status, stale CH-012 references, and P-003/M-008 bookkeeping - From 510db35b29159d159feaa9202648d88e208ed73b Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 12:52:11 +0200 Subject: [PATCH 03/11] docs(CH-031): correct Runner dependency coordinate --- changes/CH-031-complete-rumble-client/tasks.md | 1 + .../decisions/IDR-004-rumble-client-battle-runner-dependency.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index c457752e5..ed8743566 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -12,6 +12,7 @@ title: Task breakdown for CH-031 - [x] Inventory merged `rumble-client` work and confirm the local Runner development path - [x] Capture the completion proposal and full-route scope - [x] Commit and push the proposal, then open the required draft PR before implementation +- [x] Correct IDR-004 to the actual `dev.robocode.tankroyale:robocode-tankroyale-runner` coordinate - [ ] Verify and complete RCL-001 configuration validation before side effects - [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation - [ ] Verify and complete RCL-003 seeded ranked selection for all V1 game types diff --git a/docs/decisions/IDR-004-rumble-client-battle-runner-dependency.md b/docs/decisions/IDR-004-rumble-client-battle-runner-dependency.md index 434c38774..12794a9e3 100644 --- a/docs/decisions/IDR-004-rumble-client-battle-runner-dependency.md +++ b/docs/decisions/IDR-004-rumble-client-battle-runner-dependency.md @@ -16,7 +16,7 @@ CAP-016 requires the Rumble client to execute pinned battles through the Battle ## Decision -During development, `robocode-dev/rumble-client` may consume the merged BR-049 implementation from a local Tank Royale build. Before the client is distributed for ranked use, it pins the first released `dev.robocode.tankroyale:robocode-tank-royale-runner` version that provides the BR-049 behavior-version precondition. +During development, `robocode-dev/rumble-client` may consume the merged BR-049 implementation from a local Tank Royale build. Before the client is distributed for ranked use, it pins the first released `dev.robocode.tankroyale:robocode-tankroyale-runner` version that provides the BR-049 behavior-version precondition. ## Consequences From d4a5c48390f078984524a5f4ba644d4085bb417a Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 12:55:13 +0200 Subject: [PATCH 04/11] docs(CH-031): record Rumble completion blockers --- .../open-questions.md | 20 ++++++++++++++++++- .../CH-031-complete-rumble-client/tasks.md | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/changes/CH-031-complete-rumble-client/open-questions.md b/changes/CH-031-complete-rumble-client/open-questions.md index 886314ea9..045fc7757 100644 --- a/changes/CH-031-complete-rumble-client/open-questions.md +++ b/changes/CH-031-complete-rumble-client/open-questions.md @@ -8,4 +8,22 @@ title: Open questions for CH-031 # CH-031 — Open questions -No blocking questions are open. CAP-016, ADR-043, ADR-044, ADR-046, IDR-004, and the published `rumble-bots` and `rumble-data` contracts govern implementation. Any incompatible external contract or need for a credential-bearing live test becomes a blocking question and stops the change before that external side effect. +## TwinDuel catalog and result identity + +Status: blocking. + +The client selector treats the engine pin's `participants: 4` as four distinct catalog entries. Battle Runner instead expects two team entries that each expand to two bot processes, and `rumble-data` validates two `isTeam: true` result entries. The catalog contract carries no team marker or expanded participant count, so the client cannot select a valid TwinDuel battle from published metadata before booting untrusted code. + +Should CH-031 expand the `rumble-bots` and `rumble-data` contracts with explicit team metadata and revise selection accordingly, or should TwinDuel execution be deferred through a new criterion and plan door? + +Recommendation: add explicit immutable team metadata because TwinDuel is already accepted as a V1 ranked game type; silently treating four individual bots as two teams would corrupt selection and result identity. + +## Live completion evidence + +Status: blocking. + +The public synchronized catalog currently contains one active Python bot. It cannot produce even a `1v1` ranked battle, does not contain the Java, .NET, Python, and TypeScript boundary assumed by RCL-008, and cannot support the clean-install submission required by RCL-009. A literal RCL-009 proof also requires a registered client identity, an Issues-only credential, and authorization to create a live issue whose workflow writes accepted facts to `rumble-data`. + +Should CH-031 expand and populate the public prerequisites and perform an authorized live submission, or should it deliver hermetic client evidence while leaving RCL-008, RCL-009, and M-008 incomplete for a later full change? + +Recommendation: split live ecosystem population and credential-bearing proof into a later full change; complete the client against hermetic cross-repository fixtures now, but do not claim RCL-008, RCL-009, or M-008 complete until the public prerequisites exist. diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index ed8743566..69841931d 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -17,6 +17,7 @@ title: Task breakdown for CH-031 - [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation - [ ] Verify and complete RCL-003 seeded ranked selection for all V1 game types - [ ] Implement and test local BR-049 Runner dependency substitution for development and CI +- [ ] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation - [ ] Implement and test RCL-004 and RCL-005 mode separation, full-round execution, result transcription, and replay evidence - [ ] Implement and test RCL-006 append-only journaling, epoch quarantine, and receipt-driven retry - [ ] Implement and test RCL-007 bounded Issues-only submission without repository-content access From 3a15e14551d2da03916791a114d0332f6e278936 Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 13:23:46 +0200 Subject: [PATCH 05/11] docs(CH-031): bind team-aware completion split --- .clue/id-ledger.yaml | 79 ++++++++++++++++++- .../open-questions.md | 12 +-- .../CH-031-complete-rumble-client/proposal.md | 19 ++--- .../CH-031-complete-rumble-client/tasks.md | 13 +-- .../CAP-014-rumble-bot-catalog/criteria.md | 8 ++ .../CAP-014-rumble-bot-catalog/design.md | 4 +- .../CAP-016-rumble-client/criteria.md | 10 ++- .../CAP-016-rumble-client/design.md | 2 +- ...umble-catalog-publishes-team-membership.md | 25 ++++++ docs/decisions/README.md | 1 + 10 files changed, 147 insertions(+), 26 deletions(-) create mode 100644 docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md diff --git a/.clue/id-ledger.yaml b/.clue/id-ledger.yaml index d23449fc3..b305de93d 100644 --- a/.clue/id-ledger.yaml +++ b/.clue/id-ledger.yaml @@ -1,5 +1,5 @@ counters: - ADR: "46" + ADR: "47" AN: "1" ARCH: "26" C: "4" @@ -11,6 +11,8 @@ counters: LOG: "1" P: "3" PDR: "12" + RBC: "4" + RCL: "10" TNP: "3" entries: - id: ADR-001 @@ -243,6 +245,11 @@ entries: state: live prefix: ADR component: "46" + - id: ADR-047 + kind: numeric + state: live + prefix: ADR + component: "47" - id: AN-001 kind: numeric state: live @@ -761,6 +768,76 @@ entries: state: live prefix: PDR component: "12" + - id: RBC-001 + kind: numeric + state: live + prefix: RBC + component: "1" + - id: RBC-002 + kind: numeric + state: live + prefix: RBC + component: "2" + - id: RBC-003 + kind: numeric + state: live + prefix: RBC + component: "3" + - id: RBC-004 + kind: numeric + state: live + prefix: RBC + component: "4" + - id: RCL-001 + kind: numeric + state: live + prefix: RCL + component: "1" + - id: RCL-002 + kind: numeric + state: live + prefix: RCL + component: "2" + - id: RCL-003 + kind: numeric + state: retired + prefix: RCL + component: "3" + - id: RCL-004 + kind: numeric + state: live + prefix: RCL + component: "4" + - id: RCL-005 + kind: numeric + state: live + prefix: RCL + component: "5" + - id: RCL-006 + kind: numeric + state: live + prefix: RCL + component: "6" + - id: RCL-007 + kind: numeric + state: live + prefix: RCL + component: "7" + - id: RCL-008 + kind: numeric + state: live + prefix: RCL + component: "8" + - id: RCL-009 + kind: numeric + state: live + prefix: RCL + component: "9" + - id: RCL-010 + kind: numeric + state: live + prefix: RCL + component: "10" - id: TNP-001 kind: numeric state: retired diff --git a/changes/CH-031-complete-rumble-client/open-questions.md b/changes/CH-031-complete-rumble-client/open-questions.md index 045fc7757..5229e9424 100644 --- a/changes/CH-031-complete-rumble-client/open-questions.md +++ b/changes/CH-031-complete-rumble-client/open-questions.md @@ -10,20 +10,20 @@ title: Open questions for CH-031 ## TwinDuel catalog and result identity -Status: blocking. +Status: answered. -The client selector treats the engine pin's `participants: 4` as four distinct catalog entries. Battle Runner instead expects two team entries that each expand to two bot processes, and `rumble-data` validates two `isTeam: true` result entries. The catalog contract carries no team marker or expanded participant count, so the client cannot select a valid TwinDuel battle from published metadata before booting untrusted code. +The client selector treats the engine pin's `participants: 4` as four distinct catalog entries. Battle Runner instead expects two team entries that each expand to two bot processes, and `rumble-data` validates two `isTeam: true` result entries. The design already settles the shape: `docs/design/rumble/bot-submission.md` states that a team entry has exactly two `teamMembers`, the booter starts both member bots, and ranking is based on the team result reported by the server. That shape was never carried into the accepted RBC-001 acceptance criterion or the generated `bots/index.json` entry, both of which enumerate only per-bot fields, so the client cannot select a valid TwinDuel battle from published metadata before booting untrusted code. -Should CH-031 expand the `rumble-bots` and `rumble-data` contracts with explicit team metadata and revise selection accordingly, or should TwinDuel execution be deferred through a new criterion and plan door? +Should CH-031 promote the design's `teamMembers` shape into the `rumble-bots` and `rumble-data` contracts and revise selection accordingly, or should TwinDuel execution be deferred through a new criterion and plan door? -Recommendation: add explicit immutable team metadata because TwinDuel is already accepted as a V1 ranked game type; silently treating four individual bots as two teams would corrupt selection and result identity. +Answer: approved by Flemming N. Larsen on 2026-08-30 in the Codex conversation. CH-031 promotes the existing `teamMembers` shape into the synchronized catalog contract and revises selection accordingly. ADR-047 records the durable decision. ## Live completion evidence -Status: blocking. +Status: answered. The public synchronized catalog currently contains one active Python bot. It cannot produce even a `1v1` ranked battle, does not contain the Java, .NET, Python, and TypeScript boundary assumed by RCL-008, and cannot support the clean-install submission required by RCL-009. A literal RCL-009 proof also requires a registered client identity, an Issues-only credential, and authorization to create a live issue whose workflow writes accepted facts to `rumble-data`. Should CH-031 expand and populate the public prerequisites and perform an authorized live submission, or should it deliver hermetic client evidence while leaving RCL-008, RCL-009, and M-008 incomplete for a later full change? -Recommendation: split live ecosystem population and credential-bearing proof into a later full change; complete the client against hermetic cross-repository fixtures now, but do not claim RCL-008, RCL-009, or M-008 complete until the public prerequisites exist. +Answer: approved by Flemming N. Larsen on 2026-08-30 in the Codex conversation. CH-031 completes the client against hermetic cross-repository fixtures. Public catalog population, credential-bearing submission proof, RCL-008, RCL-009, and completion of M-008 remain for a later full change. diff --git a/changes/CH-031-complete-rumble-client/proposal.md b/changes/CH-031-complete-rumble-client/proposal.md index 768d5184b..151d63023 100644 --- a/changes/CH-031-complete-rumble-client/proposal.md +++ b/changes/CH-031-complete-rumble-client/proposal.md @@ -10,33 +10,34 @@ title: Complete the Rumble client locally ## What -Complete `robocode-dev/rumble-client` so a registered contributor can synchronize one reviewed Rumble snapshot, select and execute pinned battles through the locally built Battle Runner, retain replay-bound result evidence, durably journal completed ranked results, and submit acknowledged issue-ops batches without repository-content write access. +Complete the locally testable `robocode-dev/rumble-client` path so it can synchronize one reviewed Rumble snapshot, select and execute pinned battles through the locally built Battle Runner, retain replay-bound result evidence, durably journal completed ranked results, and prepare acknowledged issue-ops batches without repository-content write access. ## Why -P-003/M-008 is the next unfinished Rumble milestone. Configuration, ranked synchronization, selection, bot-cache preparation, and runtime packaging already exist in the external client, while battle execution, durable result handling, submission, and end-to-end evidence remain unfinished. BR-049 is merged and may be consumed from a local Tank Royale build, so development no longer depends on a public Tank Royale release. +P-003/M-008 is the next unfinished Rumble milestone. Configuration, ranked synchronization, selection, bot-cache preparation, and runtime packaging already exist in the external client, while battle execution, durable result handling, and submission remain unfinished. BR-049 is merged and may be consumed from a local Tank Royale build, so development no longer depends on a public Tank Royale release. The public bot population and credential-bearing live submission needed to complete M-008 are deliberately deferred. ## Route -Recommended route: full. This change completes accepted CAP-016 behavior and binds cross-repository acceptance evidence for M-008. Discovery would change the route only if the external client already satisfies and evidences all RCL criteria, reducing the work to evidence reconciliation. +Recommended route: full. This change adds the cross-repository team catalog contract and implements accepted CAP-016 behavior through hermetic evidence. Discovery would change the route only if the catalog already carried immutable team membership and the external client already satisfied the locally provable RCL criteria. ## Plan -Serves [P-003/M-008](../../docs/plans/P-003-rumble.md) and supersedes the incomplete implementation references to CH-012 and CH-030 without changing the accepted RCL criterion meanings. +Serves [P-003/M-008](../../docs/plans/P-003-rumble.md) without completing it. It supersedes incomplete implementation references to CH-012 and CH-030, promotes the existing TwinDuel team design into the catalog contract, and replaces the incorrect draft RCL-003 selection meaning with RCL-010. ## Scope -- Verify and complete the existing RCL-001 through RCL-003 configuration, synchronization, cache, and seeded-selection paths. +- Verify and complete RCL-001, RCL-002, and the RCL-010 configuration, synchronization, cache, and team-aware seeded-selection paths. +- Add immutable `teamMembers` metadata to the generated and synchronized catalog contracts, with focused RBC-004 evidence. - Add a reproducible local Tank Royale dependency path so client development and CI can consume the merged Runner BR-049 API without publishing Tank Royale. - Implement strict ranked/practice separation, full-round Battle Runner execution, complete result transcription, and replay retention for RCL-004 and RCL-005. - Implement append-only journaling, epoch quarantine, receipt-driven retry, and bounded Issues-only submission for RCL-006 and RCL-007. -- Complete the multi-runtime execution and network-boundary evidence for RCL-008. -- Prove RCL-009 through an automated clean-install flow spanning the client and result-data ingestion contracts. -- Digest verified external evidence into CAP-016 and P-003 only after the M-008 exit criterion is demonstrably met. +- Test execution, journaling, and submission against hermetic cross-repository fixtures without claiming live public ingestion. +- Digest verified external evidence into CAP-014 through CAP-016 while leaving RCL-008, RCL-009, and P-003/M-008 incomplete. ## Non-goals - Publishing Tank Royale 1.2.0 or any other release solely to support client development. +- Populating the public catalog across all supported runtimes or performing a credential-bearing live result submission. - Changing Rumble game behavior, the Runner public API, the accepted result envelope, or `rumble-data` ingestion semantics unless a blocking incompatibility is first recorded and approved. - Granting repository-content, branch, release, package, Pages, fact, or projection write access to a client credential. - Central services, centrally stored replay files, persistent secrets, or fork-pull-request result transport. @@ -44,4 +45,4 @@ Serves [P-003/M-008](../../docs/plans/P-003-rumble.md) and supersedes the incomp ## Compatibility -Local development uses the merged Runner source while ranked distribution remains gated on an immutable released Runner artifact. Ranked execution fails closed on unsupported schemas, inconsistent snapshots, source-hash or identity mismatches, incomplete battles, and behavior-version incompatibility. Practice mode has no path to ranked journal or submission state. +Local development uses the merged Runner source while ranked distribution remains gated on an immutable released Runner artifact. `teamMembers` is an additive catalog field that defaults to an empty list for individual bots; TwinDuel requires two active team entries with exactly two active members each. Ranked execution fails closed on unsupported schemas, inconsistent snapshots, source-hash or identity mismatches, incomplete battles, and behavior-version incompatibility. Practice mode has no path to ranked journal or submission state. diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index 69841931d..8a000878a 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -15,12 +15,13 @@ title: Task breakdown for CH-031 - [x] Correct IDR-004 to the actual `dev.robocode.tankroyale:robocode-tankroyale-runner` coordinate - [ ] Verify and complete RCL-001 configuration validation before side effects - [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation -- [ ] Verify and complete RCL-003 seeded ranked selection for all V1 game types -- [ ] Implement and test local BR-049 Runner dependency substitution for development and CI -- [ ] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation +- [ ] Promote immutable TwinDuel membership into the catalog contracts and add RBC-004 evidence +- [ ] Replace retired RCL-003 with RCL-010 team-aware seeded ranked selection evidence for all V1 game types +- [x] Implement and test local BR-049 Runner dependency substitution for development and CI +- [x] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation - [ ] Implement and test RCL-004 and RCL-005 mode separation, full-round execution, result transcription, and replay evidence - [ ] Implement and test RCL-006 append-only journaling, epoch quarantine, and receipt-driven retry - [ ] Implement and test RCL-007 bounded Issues-only submission without repository-content access -- [ ] Complete and test RCL-008 multi-runtime execution and the container network boundary -- [ ] Implement and test RCL-009 automated clean-install ingestion into immutable `rumble-data` facts -- [ ] Reconcile external evidence, CAP-016 status, stale CH-012 references, and P-003/M-008 bookkeeping +- [-] Complete and test RCL-008 multi-runtime execution and the container network boundary — deferred by the approved split until the public catalog contains every supported runtime +- [-] Implement and test RCL-009 automated clean-install ingestion into immutable `rumble-data` facts — deferred by the approved split until a registered identity and Issues-only credential are authorized for live proof +- [ ] Reconcile external evidence, CAP-014 through CAP-016 status, stale CH-012 references, and P-003/M-008 bookkeeping without marking M-008 complete diff --git a/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md b/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md index ac4d1f844..d4a9b1cb1 100644 --- a/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md +++ b/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md @@ -35,4 +35,12 @@ Feature: rumble-bot-catalog — Rumble bot catalog When an unregistered account submits that name or an owner changes its source without increasing its version Then validation rejects the submission And an approved version increase supersedes the old active version without deleting its historical record + + @RBC-004 @draft + Scenario: A TwinDuel team is published with immutable member identities + Test-type: Integration + Given a valid TwinDuel team entry names exactly two distinct active member bots + 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 missing, duplicate, inactive, or unknown team members ``` diff --git a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md index 6ac4fc9cd..2c806857e 100644 --- a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md +++ b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md @@ -16,9 +16,9 @@ The external `rumble-bots` repository is the authoritative source of reviewed bo `bots/index.json` is generated after accepted changes and is never edited by contributors. Its top-level object contains a positive integer `schemaVersion`, an ISO-8601 `generatedAt` timestamp, the immutable generating Git `commit`, and a `bots` array. -Each bot entry contains `name`, `version`, `platform`, `path`, `sourceHash`, `owner`, `authors`, `addedAt`, and `status`. `sourceHash` uses the `sha256:` form and covers the source tree that clients run. Only `status: active` entries are eligible for matchmaking; `superseded`, `retired`, and `disqualified` entries remain historical metadata. +Each bot entry contains `name`, `version`, `platform`, `path`, `sourceHash`, `owner`, `authors`, `addedAt`, and `status`. It also contains `teamMembers`, an immutable list of catalog identities written as `name version`; the list is empty for an individual bot and contains exactly two distinct active individual identities for a TwinDuel team. `sourceHash` uses the `sha256:` form and covers the entry's source tree, while the member identities let clients obtain and verify every source tree the team executes. Only `status: active` entries are eligible for matchmaking; `superseded`, `retired`, and `disqualified` entries remain historical metadata. -The catalog schema is additive within a schema version: readers ignore fields they do not understand, while a breaking structural change requires a new `schemaVersion`. A client verifies the source-tree hash after obtaining the cataloged source and must reject a mismatch. +The catalog schema is additive within a schema version: readers ignore fields they do not understand, while a breaking structural change requires a new `schemaVersion`. Readers treat an absent `teamMembers` field as an empty list for compatibility. A client verifies every selected entry's source-tree hash after obtaining the cataloged source and must reject a mismatch. ## External evidence diff --git a/docs/capabilities/CAP-016-rumble-client/criteria.md b/docs/capabilities/CAP-016-rumble-client/criteria.md index c081159cd..0020dd85a 100644 --- a/docs/capabilities/CAP-016-rumble-client/criteria.md +++ b/docs/capabilities/CAP-016-rumble-client/criteria.md @@ -28,7 +28,7 @@ Feature: rumble-client — Local ranked and practice battle client Then the client follows the canonical location and accepts one mutually consistent snapshot with supported schemas, an active registered client ID, an immutable catalog commit, and advice for every selected game type And it refuses ranked execution when a required document is missing, unsupported, inconsistent, or fails its declared source identity - @RCL-003 @draft + @RCL-003 @retired Scenario: Ranked selection turns published advice into a valid battle Test-type: Unit Given a validated snapshot contains active bots and matchmaking advice for `1v1`, `twinduel`, or `melee` @@ -36,6 +36,14 @@ Feature: rumble-client — Local ranked and practice battle client Then it selects the pinned number of distinct active participants, preferring advised pairings involving configured own bots before other high-priority advice And it treats advice as non-exclusive and can select a valid fallback battle when no advised pairing is available + @RCL-010 @draft + Scenario: Ranked selection turns published advice into a valid executable battle + Test-type: Unit + Given a validated snapshot contains active individual bots, active TwinDuel teams with two active members, and matchmaking advice + When the client selects a ranked `1v1`, `twinduel`, or `melee` battle with a recorded random seed + Then it selects the pinned number of distinct individual entries or two distinct team entries whose expanded members equal the pinned participant count + And it prefers advised pairings involving configured own entries before selecting a valid seeded fallback + @RCL-004 @draft Scenario: Ranked and practice modes cannot mix result state Test-type: Integration diff --git a/docs/capabilities/CAP-016-rumble-client/design.md b/docs/capabilities/CAP-016-rumble-client/design.md index a8657f0c4..f1a132015 100644 --- a/docs/capabilities/CAP-016-rumble-client/design.md +++ b/docs/capabilities/CAP-016-rumble-client/design.md @@ -18,7 +18,7 @@ One versioned configuration selects `ranked` or `practice`, the initial bot and A ranked session begins from the configured data repository's `wellknown/rumble.json` and follows its canonical location. From one data-repository revision it reads `engine.json`, `catalog.json`, `clients/.json`, and `matchmaking/matches_needed-.json` for each selected game type. The client rejects unknown schema versions, an unregistered client ID, unsupported game types, inconsistent projections, or a catalog whose declared source commit cannot identify the reviewed source in [CAP-014](../CAP-014-rumble-bot-catalog/README.md). -The accepted snapshot pins all ranked work in the session. Cached bot source is addressed by the catalog's immutable `sourceCommit` and each entry's `sourceHash`; a hash disagreement rejects the bot before execution. Matchmaking files are advice rather than reservations, so seeded selection may safely fall back to other active catalog participants while preserving the engine pin's participant count. +The accepted snapshot pins all ranked work in the session. Cached bot source is addressed by the catalog's immutable `sourceCommit` and each entry's `sourceHash`; a hash disagreement rejects the bot before execution. Individual entries have no team members. A TwinDuel team entry names exactly two distinct active individual catalog identities in `teamMembers`, and cache preparation obtains and verifies the team entry plus both member source trees. Matchmaking files are advice rather than reservations, so seeded selection may safely fall back to other eligible entries. `1v1` and `melee` select distinct individuals; `twinduel` selects two distinct team entries whose expanded member count equals the engine pin's participant count. ## Execution and mode boundary diff --git a/docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md b/docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md new file mode 100644 index 000000000..ddf2b6efd --- /dev/null +++ b/docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md @@ -0,0 +1,25 @@ +--- +id: ADR-047 +type: decision +status: verified +links: [CAP-014, CAP-015, CAP-016, ARCH-022, P-003] +title: Rumble catalog publishes immutable team membership +author: agent +accepted-by: Flemming N. Larsen (2026-08-30, Codex conversation) +--- + +# ADR-047 — Rumble catalog publishes immutable team membership + +## Context + +The V1 engine pin counts the four bot processes in a TwinDuel battle, while Battle Runner starts two team entries and result ingestion receives two team results. The catalog previously identified only individual entry fields, so a client could not distinguish two valid teams from four unrelated bots before starting untrusted code. ARCH-022 already defines a TwinDuel team as an entry with exactly two `teamMembers`. + +## Decision + +The generated bot catalog publishes `teamMembers` as immutable catalog identities. Individual entries use an empty list. A TwinDuel team names exactly two distinct active individual entries, and catalog generation rejects missing, duplicate, inactive, unknown, or nested team members. Readers treat an absent field as an empty list for schema-version-one compatibility. + +Ranked TwinDuel selection chooses two distinct active team entries and verifies that their expanded member count equals the engine pin. Cache preparation obtains and verifies the team entry and every member source tree before Battle Runner starts them. Individual game types select only entries without team members. + +## Consequences + +Selection, source preparation, execution identity, and result validation share one explicit team model. Existing individual-only catalogs remain readable, but they cannot satisfy TwinDuel selection until team entries are published. diff --git a/docs/decisions/README.md b/docs/decisions/README.md index 821b8b280..8ea4244b0 100644 --- a/docs/decisions/README.md +++ b/docs/decisions/README.md @@ -71,4 +71,5 @@ Writing guidelines: be specific (technical detail, not concepts); show your work - [PDR-010 — Design records use the architecture type](PDR-010-design-record-typing.md) · `inferred` — The corpus needs one vocabulary for documents that describe system structure, including the debugging guide and health reports. - [PDR-011 — Empty extracted specifications create no capability](PDR-011-empty-extraction-directory.md) · `inferred` — The `browser-sample-bots` OpenSpec directory contained no requirements to preserve. - [PDR-012 — Typed decision records replace the legacy decision log](PDR-012-typed-decision-record-carrier.md) · `inferred` — The legacy decision log mixed architecture, process, implementation, and routine history in one carrier that obscured the enduring subject of each choice. +- [ADR-047 — Rumble catalog publishes immutable team membership](ADR-047-rumble-catalog-publishes-team-membership.md) · `verified` — The V1 engine pin counts the four bot processes in a TwinDuel battle, while Battle Runner starts two team entries and result ingestion receives two team results. From b152fd9d0532abe4bfa12e11c18470791fe50804 Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 13:33:24 +0200 Subject: [PATCH 06/11] docs(CH-031): preserve repeated team member slots --- changes/CH-031-complete-rumble-client/tasks.md | 2 +- docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md | 4 ++-- docs/capabilities/CAP-014-rumble-bot-catalog/design.md | 2 +- docs/capabilities/CAP-016-rumble-client/criteria.md | 2 +- docs/capabilities/CAP-016-rumble-client/design.md | 2 +- .../ADR-047-rumble-catalog-publishes-team-membership.md | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index 8a000878a..fe00462fd 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -15,7 +15,7 @@ title: Task breakdown for CH-031 - [x] Correct IDR-004 to the actual `dev.robocode.tankroyale:robocode-tankroyale-runner` coordinate - [ ] Verify and complete RCL-001 configuration validation before side effects - [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation -- [ ] Promote immutable TwinDuel membership into the catalog contracts and add RBC-004 evidence +- [x] Promote immutable TwinDuel membership into the catalog contracts and add RBC-004 evidence - [ ] Replace retired RCL-003 with RCL-010 team-aware seeded ranked selection evidence for all V1 game types - [x] Implement and test local BR-049 Runner dependency substitution for development and CI - [x] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation diff --git a/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md b/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md index d4a9b1cb1..16b85f280 100644 --- a/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md +++ b/docs/capabilities/CAP-014-rumble-bot-catalog/criteria.md @@ -39,8 +39,8 @@ Feature: rumble-bot-catalog — Rumble bot catalog @RBC-004 @draft Scenario: A TwinDuel team is published with immutable member identities Test-type: Integration - Given a valid TwinDuel team entry names exactly two distinct active member bots + Given a valid TwinDuel team entry names exactly two active member bots 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 missing, duplicate, inactive, or unknown team members + And generation rejects a missing, inactive, unknown, or nested team member ``` diff --git a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md index 2c806857e..ce857312c 100644 --- a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md +++ b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md @@ -16,7 +16,7 @@ The external `rumble-bots` repository is the authoritative source of reviewed bo `bots/index.json` is generated after accepted changes and is never edited by contributors. Its top-level object contains a positive integer `schemaVersion`, an ISO-8601 `generatedAt` timestamp, the immutable generating Git `commit`, and a `bots` array. -Each bot entry contains `name`, `version`, `platform`, `path`, `sourceHash`, `owner`, `authors`, `addedAt`, and `status`. It also contains `teamMembers`, an immutable list of catalog identities written as `name version`; the list is empty for an individual bot and contains exactly two distinct active individual identities for a TwinDuel team. `sourceHash` uses the `sha256:` form and covers the entry's source tree, while the member identities let clients obtain and verify every source tree the team executes. Only `status: active` entries are eligible for matchmaking; `superseded`, `retired`, and `disqualified` entries remain historical metadata. +Each bot entry contains `name`, `version`, `platform`, `path`, `sourceHash`, `owner`, `authors`, `addedAt`, and `status`. It also contains `teamMembers`, an immutable ordered list of catalog identities written as `name version`; the list is empty for an individual bot and contains exactly two active individual identities for a TwinDuel team. A member identity may occur twice because Battle Runner preserves repeated team slots. `sourceHash` uses the `sha256:` form and covers the entry's source tree, while the member identities let clients obtain and verify every source tree the team executes. Only `status: active` entries are eligible for matchmaking; `superseded`, `retired`, and `disqualified` entries remain historical metadata. The catalog schema is additive within a schema version: readers ignore fields they do not understand, while a breaking structural change requires a new `schemaVersion`. Readers treat an absent `teamMembers` field as an empty list for compatibility. A client verifies every selected entry's source-tree hash after obtaining the cataloged source and must reject a mismatch. diff --git a/docs/capabilities/CAP-016-rumble-client/criteria.md b/docs/capabilities/CAP-016-rumble-client/criteria.md index 0020dd85a..90b75c952 100644 --- a/docs/capabilities/CAP-016-rumble-client/criteria.md +++ b/docs/capabilities/CAP-016-rumble-client/criteria.md @@ -39,7 +39,7 @@ Feature: rumble-client — Local ranked and practice battle client @RCL-010 @draft Scenario: Ranked selection turns published advice into a valid executable battle Test-type: Unit - Given a validated snapshot contains active individual bots, active TwinDuel teams with two active members, and matchmaking advice + Given a validated snapshot contains active individual bots, active TwinDuel teams with two member slots backed by active individuals, and matchmaking advice When the client selects a ranked `1v1`, `twinduel`, or `melee` battle with a recorded random seed Then it selects the pinned number of distinct individual entries or two distinct team entries whose expanded members equal the pinned participant count And it prefers advised pairings involving configured own entries before selecting a valid seeded fallback diff --git a/docs/capabilities/CAP-016-rumble-client/design.md b/docs/capabilities/CAP-016-rumble-client/design.md index f1a132015..f51c2a2e7 100644 --- a/docs/capabilities/CAP-016-rumble-client/design.md +++ b/docs/capabilities/CAP-016-rumble-client/design.md @@ -18,7 +18,7 @@ One versioned configuration selects `ranked` or `practice`, the initial bot and A ranked session begins from the configured data repository's `wellknown/rumble.json` and follows its canonical location. From one data-repository revision it reads `engine.json`, `catalog.json`, `clients/.json`, and `matchmaking/matches_needed-.json` for each selected game type. The client rejects unknown schema versions, an unregistered client ID, unsupported game types, inconsistent projections, or a catalog whose declared source commit cannot identify the reviewed source in [CAP-014](../CAP-014-rumble-bot-catalog/README.md). -The accepted snapshot pins all ranked work in the session. Cached bot source is addressed by the catalog's immutable `sourceCommit` and each entry's `sourceHash`; a hash disagreement rejects the bot before execution. Individual entries have no team members. A TwinDuel team entry names exactly two distinct active individual catalog identities in `teamMembers`, and cache preparation obtains and verifies the team entry plus both member source trees. Matchmaking files are advice rather than reservations, so seeded selection may safely fall back to other eligible entries. `1v1` and `melee` select distinct individuals; `twinduel` selects two distinct team entries whose expanded member count equals the engine pin's participant count. +The accepted snapshot pins all ranked work in the session. Cached bot source is addressed by the catalog's immutable `sourceCommit` and each entry's `sourceHash`; a hash disagreement rejects the bot before execution. Individual entries have no team members. A TwinDuel team entry names exactly two active individual catalog identities in `teamMembers`, preserving repeated member slots, and cache preparation obtains and verifies the team entry plus each referenced member source tree. Matchmaking files are advice rather than reservations, so seeded selection may safely fall back to other eligible entries. `1v1` and `melee` select distinct individuals; `twinduel` selects two distinct team entries whose expanded member count equals the engine pin's participant count. ## Execution and mode boundary diff --git a/docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md b/docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md index ddf2b6efd..b0cc31192 100644 --- a/docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md +++ b/docs/decisions/ADR-047-rumble-catalog-publishes-team-membership.md @@ -16,7 +16,7 @@ The V1 engine pin counts the four bot processes in a TwinDuel battle, while Batt ## Decision -The generated bot catalog publishes `teamMembers` as immutable catalog identities. Individual entries use an empty list. A TwinDuel team names exactly two distinct active individual entries, and catalog generation rejects missing, duplicate, inactive, unknown, or nested team members. Readers treat an absent field as an empty list for schema-version-one compatibility. +The generated bot catalog publishes `teamMembers` as immutable catalog identities. Individual entries use an empty list. A TwinDuel team names exactly two active individual entries and preserves repeated member slots, while catalog generation rejects a missing, inactive, unknown, or nested team member. Readers treat an absent field as an empty list for schema-version-one compatibility. Ranked TwinDuel selection chooses two distinct active team entries and verifies that their expanded member count equals the engine pin. Cache preparation obtains and verifies the team entry and every member source tree before Battle Runner starts them. Individual game types select only entries without team members. From f5705356725850c05d90190ee5d1909683de1feb Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 21:05:42 +0200 Subject: [PATCH 07/11] docs(CH-031): add TwinDuel member isolation criterion --- .clue/id-ledger.yaml | 7 ++++++- changes/CH-031-complete-rumble-client/tasks.md | 2 +- docs/capabilities/CAP-016-rumble-client/criteria.md | 8 ++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.clue/id-ledger.yaml b/.clue/id-ledger.yaml index b305de93d..a9307ff2e 100644 --- a/.clue/id-ledger.yaml +++ b/.clue/id-ledger.yaml @@ -12,7 +12,7 @@ counters: P: "3" PDR: "12" RBC: "4" - RCL: "10" + RCL: "11" TNP: "3" entries: - id: ADR-001 @@ -838,6 +838,11 @@ entries: state: live prefix: RCL component: "10" + - id: RCL-011 + kind: numeric + state: live + prefix: RCL + component: "11" - id: TNP-001 kind: numeric state: retired diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index fe00462fd..8dffe3591 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -16,7 +16,7 @@ title: Task breakdown for CH-031 - [ ] Verify and complete RCL-001 configuration validation before side effects - [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation - [x] Promote immutable TwinDuel membership into the catalog contracts and add RBC-004 evidence -- [ ] Replace retired RCL-003 with RCL-010 team-aware seeded ranked selection evidence for all V1 game types +- [ ] Replace retired RCL-003 with RCL-010 and RCL-011 team-aware seeded ranked selection evidence for all V1 game types and non-overlapping TwinDuel members - [x] Implement and test local BR-049 Runner dependency substitution for development and CI - [x] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation - [ ] Implement and test RCL-004 and RCL-005 mode separation, full-round execution, result transcription, and replay evidence diff --git a/docs/capabilities/CAP-016-rumble-client/criteria.md b/docs/capabilities/CAP-016-rumble-client/criteria.md index 90b75c952..ac8802e7f 100644 --- a/docs/capabilities/CAP-016-rumble-client/criteria.md +++ b/docs/capabilities/CAP-016-rumble-client/criteria.md @@ -44,6 +44,14 @@ Feature: rumble-client — Local ranked and practice battle client Then it selects the pinned number of distinct individual entries or two distinct team entries whose expanded members equal the pinned participant count And it prefers advised pairings involving configured own entries before selecting a valid seeded fallback + @RCL-011 @draft + Scenario: TwinDuel teams never face a shared member bot + Test-type: Unit + Given a validated snapshot contains active TwinDuel teams with immutable member identities + When the client selects a ranked TwinDuel battle + Then the two selected team entries have disjoint member identities + And it rejects selection when no two teams can satisfy that condition + @RCL-004 @draft Scenario: Ranked and practice modes cannot mix result state Test-type: Integration From 444ce08355bde9e952e68afda9c06691c184d37e Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 21:26:25 +0200 Subject: [PATCH 08/11] docs(CH-031): bind catalog teams in result validation --- changes/CH-031-complete-rumble-client/proposal.md | 3 ++- changes/CH-031-complete-rumble-client/tasks.md | 1 + docs/capabilities/CAP-015-rumble-result-data/criteria.md | 9 +++++++++ docs/capabilities/CAP-015-rumble-result-data/design.md | 4 +++- docs/capabilities/CAP-016-rumble-client/design.md | 4 ++-- docs/design/rumble/aggregation-and-dashboard.md | 2 ++ 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/changes/CH-031-complete-rumble-client/proposal.md b/changes/CH-031-complete-rumble-client/proposal.md index 151d63023..ec5c696b2 100644 --- a/changes/CH-031-complete-rumble-client/proposal.md +++ b/changes/CH-031-complete-rumble-client/proposal.md @@ -28,6 +28,7 @@ Serves [P-003/M-008](../../docs/plans/P-003-rumble.md) without completing it. It - Verify and complete RCL-001, RCL-002, and the RCL-010 configuration, synchronization, cache, and team-aware seeded-selection paths. - Add immutable `teamMembers` metadata to the generated and synchronized catalog contracts, with focused RBC-004 evidence. +- Bind result-data validation and matchmaking advice to that catalog membership: individual game types admit only active individual entries, while TwinDuel admits only disjoint active teams whose immutable members expand to the engine pin. - Add a reproducible local Tank Royale dependency path so client development and CI can consume the merged Runner BR-049 API without publishing Tank Royale. - Implement strict ranked/practice separation, full-round Battle Runner execution, complete result transcription, and replay retention for RCL-004 and RCL-005. - Implement append-only journaling, epoch quarantine, receipt-driven retry, and bounded Issues-only submission for RCL-006 and RCL-007. @@ -38,7 +39,7 @@ Serves [P-003/M-008](../../docs/plans/P-003-rumble.md) without completing it. It - Publishing Tank Royale 1.2.0 or any other release solely to support client development. - Populating the public catalog across all supported runtimes or performing a credential-bearing live result submission. -- Changing Rumble game behavior, the Runner public API, the accepted result envelope, or `rumble-data` ingestion semantics unless a blocking incompatibility is first recorded and approved. +- Changing Rumble game behavior, the Runner public API, or the accepted result envelope; result-data validation is strengthened through its existing catalog lookup rather than a wire-contract change. - Granting repository-content, branch, release, package, Pages, fact, or projection write access to a client credential. - Central services, centrally stored replay files, persistent secrets, or fork-pull-request result transport. - Completing the separate M-009 user-documentation milestone. diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index 8dffe3591..7c2605c07 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -16,6 +16,7 @@ title: Task breakdown for CH-031 - [ ] Verify and complete RCL-001 configuration validation before side effects - [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation - [x] Promote immutable TwinDuel membership into the catalog contracts and add RBC-004 evidence +- [x] Specify result-data validation and matchmaking eligibility from immutable catalog team membership, and register the RDA-005 external-evidence gap - [ ] Replace retired RCL-003 with RCL-010 and RCL-011 team-aware seeded ranked selection evidence for all V1 game types and non-overlapping TwinDuel members - [x] Implement and test local BR-049 Runner dependency substitution for development and CI - [x] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation diff --git a/docs/capabilities/CAP-015-rumble-result-data/criteria.md b/docs/capabilities/CAP-015-rumble-result-data/criteria.md index 8c8d90311..4b4635a7b 100644 --- a/docs/capabilities/CAP-015-rumble-result-data/criteria.md +++ b/docs/capabilities/CAP-015-rumble-result-data/criteria.md @@ -43,4 +43,13 @@ Feature: rumble-result-data — Rumble result data When a visitor selects a ranked game type Then the dashboard requests its generated leaderboard projection and links each entry to its generated detail shard And it does not require a live application backend + + @RDA-005 @draft + Scenario: Result eligibility is derived from immutable catalog team membership + Test-type: Integration + Given a supported engine pin and a synchronized catalog containing active individual entries and TwinDuel teams with immutable `teamMembers` + When validation processes a ranked result and aggregation prepares matchmaking advice + 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 ``` diff --git a/docs/capabilities/CAP-015-rumble-result-data/design.md b/docs/capabilities/CAP-015-rumble-result-data/design.md index 424c46c7f..8f46d4b2a 100644 --- a/docs/capabilities/CAP-015-rumble-result-data/design.md +++ b/docs/capabilities/CAP-015-rumble-result-data/design.md @@ -16,6 +16,8 @@ The external `robocode-dev/rumble-data` repository owns result storage and proje `engine.json` pins a positive `behaviorVersion`, Tank Royale release and image references, and ranked settings for `1v1`, `twinduel`, and `melee`. `catalog.json` is the synchronized published bot catalog; only its active name-and-version entries can occur in ranked results. A contributor is admitted by a reviewed `clients/.json` registration that declares stable client IDs. +For every result, validation resolves each reported entry against the catalog before accepting or aggregating it. `1v1` and `melee` require the engine pin's exact number of distinct active individual entries, identified by an empty `teamMembers` list. `twinduel` requires exactly two distinct active team entries; each must have exactly two active individual catalog members, the teams' expanded members must equal the pinned participant count, and their member-identity sets must be disjoint. A team is ineligible for an individual game type, and an individual is ineligible for TwinDuel. This catalog lookup binds eligibility and membership without changing the result-envelope wire shape. + An issue-ops submission is one fenced JSON batch envelope with `schemaVersion`, `clientId`, `clientVersion`, and one to sixty result records. Each record includes a UUID `battleId`, completion time, matching nested client identity, behavior version, game type, pinned battle dimensions, and the complete Battle Runner participant result model. The validator checks the contract independently for every record, then normalizes valid records with the submitting account and payload hash. A content-addressed JSON file under `results/raw///` is the authoritative fact; issue bodies are transport, never state. The workflow publishes successful per-result receipts only after accepted facts reach the canonical repository, and an identical retry of an already retained result receives the same successful outcome. ## Projection and moderation contracts @@ -26,4 +28,4 @@ CI serializes ingestion and is the sole writer of facts and projections on `main ## 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. During P-001/M-002, the external tests will receive purpose tags and 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-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. RDA-005 remains draft until that repository adds focused positive and negative validation and advice-generation 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. diff --git a/docs/capabilities/CAP-016-rumble-client/design.md b/docs/capabilities/CAP-016-rumble-client/design.md index f51c2a2e7..3aa2b2265 100644 --- a/docs/capabilities/CAP-016-rumble-client/design.md +++ b/docs/capabilities/CAP-016-rumble-client/design.md @@ -18,7 +18,7 @@ One versioned configuration selects `ranked` or `practice`, the initial bot and A ranked session begins from the configured data repository's `wellknown/rumble.json` and follows its canonical location. From one data-repository revision it reads `engine.json`, `catalog.json`, `clients/.json`, and `matchmaking/matches_needed-.json` for each selected game type. The client rejects unknown schema versions, an unregistered client ID, unsupported game types, inconsistent projections, or a catalog whose declared source commit cannot identify the reviewed source in [CAP-014](../CAP-014-rumble-bot-catalog/README.md). -The accepted snapshot pins all ranked work in the session. Cached bot source is addressed by the catalog's immutable `sourceCommit` and each entry's `sourceHash`; a hash disagreement rejects the bot before execution. Individual entries have no team members. A TwinDuel team entry names exactly two active individual catalog identities in `teamMembers`, preserving repeated member slots, and cache preparation obtains and verifies the team entry plus each referenced member source tree. Matchmaking files are advice rather than reservations, so seeded selection may safely fall back to other eligible entries. `1v1` and `melee` select distinct individuals; `twinduel` selects two distinct team entries whose expanded member count equals the engine pin's participant count. +The accepted snapshot pins all ranked work in the session. Cached bot source is addressed by the catalog's immutable `sourceCommit` and each entry's `sourceHash`; a hash disagreement rejects the bot before execution. Individual entries have no team members. A TwinDuel team entry names exactly two active individual catalog identities in `teamMembers`, preserving repeated member slots, and cache preparation obtains and verifies the team entry plus each referenced member source tree. Matchmaking files are advice rather than reservations, so seeded selection may safely fall back to other eligible entries. `1v1` and `melee` select distinct individuals; `twinduel` selects two distinct team entries whose expanded member count equals the engine pin's participant count and whose member-identity sets are disjoint. ## Execution and mode boundary @@ -44,4 +44,4 @@ The primary distribution is a rebuildable container containing the pinned Tank R ## External evidence -The external repository records focused evidence for RCL-001 through RCL-009. The accepted configuration implementation at `robocode-dev/rumble-client` commit `d19a90e99649f87664785f1dc20b5aa2f42da7d6` provides initial configuration-loader coverage toward RCL-001; RCL-001 remains incomplete until practice mode accepts configuration without a client identity and integration evidence verifies rejection before side effects. Later CH-012 implementation commits must add the remaining evidence before M-008 can complete. During P-001/M-002, those tests will receive their RCL purpose tags and this criteria artifact can become active without changing the criterion meanings. +The external repository records focused evidence for RCL-001, RCL-002, and RCL-004 through RCL-011; retired RCL-003 has no active evidence obligation. The accepted configuration implementation at `robocode-dev/rumble-client` commit `d19a90e99649f87664785f1dc20b5aa2f42da7d6` provides initial configuration-loader coverage toward RCL-001; RCL-001 remains incomplete until practice mode accepts configuration without a client identity and integration evidence verifies rejection before side effects. Later CH-012 implementation commits must add the remaining evidence before M-008 can complete. During P-001/M-002, those tests will receive their RCL purpose tags, and the external-evidence reconciliation set must include RCL-010 and RCL-011 before this criteria artifact can become active without changing the criterion meanings. diff --git a/docs/design/rumble/aggregation-and-dashboard.md b/docs/design/rumble/aggregation-and-dashboard.md index f319a1a21..3968e51af 100644 --- a/docs/design/rumble/aggregation-and-dashboard.md +++ b/docs/design/rumble/aggregation-and-dashboard.md @@ -163,6 +163,8 @@ Averaging per-pairing first means extra samples of one pairing (e.g. from own-bo - The leaderboard ranks only the **latest active version** of each bot (`status: active` in `bots/index.json`, see the submission document). Superseded, retired, and disqualified versions keep their facts and per-version detail shards but leave the ranked table, exactly like a RoboRumble version bump. - Results are partitioned into **epochs by `behaviorVersion`** (the server-owned integer that bumps only on game-observable changes; see the client document's Engine Pinning section). The release version is irrelevant here: a GUI-only release, whatever its semver bump, keeps the behavior version and therefore the epoch. A `behaviorVersion` bump opens a new epoch: the ranked leaderboard is computed from the current epoch only, while old epochs remain browsable archives. This is the honest consequence of "mixed game behavior corrupts comparability": rather than pretending results across behavior versions are comparable, the rumble restarts sampling and lets matchmaking (everything is suddenly under-sampled) rebuild the table quickly. +Before accepting a fact or emitting matchmaking advice, `rumble-data` resolves every entry against the synchronized catalog. `1v1` and `melee` use only distinct active individual entries. TwinDuel uses only pairs of distinct active team entries whose immutable `teamMembers` each resolve to active individuals, expand to the pin's participant count, and are disjoint across the two teams. Any result or proposed pairing that does not meet its game type's eligibility is rejected or omitted, respectively. + ### Matchmaking output `aggregate.py` also regenerates `matchmaking/matches_needed.json`, closing the loop with clients: From 29082d5f4704e9653172ee4d723f4dce5319cda8 Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 22:00:35 +0200 Subject: [PATCH 09/11] docs(CH-031): reconcile external rumble evidence --- changes/CH-031-complete-rumble-client/tasks.md | 14 +++++++------- .../CAP-014-rumble-bot-catalog/design.md | 2 +- .../CAP-015-rumble-result-data/design.md | 2 +- docs/capabilities/CAP-016-rumble-client/design.md | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md index 7c2605c07..e8ed6c447 100644 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ b/changes/CH-031-complete-rumble-client/tasks.md @@ -13,16 +13,16 @@ title: Task breakdown for CH-031 - [x] Capture the completion proposal and full-route scope - [x] Commit and push the proposal, then open the required draft PR before implementation - [x] Correct IDR-004 to the actual `dev.robocode.tankroyale:robocode-tankroyale-runner` coordinate -- [ ] Verify and complete RCL-001 configuration validation before side effects -- [ ] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation +- [x] Verify and complete RCL-001 configuration validation before side effects +- [x] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation - [x] Promote immutable TwinDuel membership into the catalog contracts and add RBC-004 evidence - [x] Specify result-data validation and matchmaking eligibility from immutable catalog team membership, and register the RDA-005 external-evidence gap -- [ ] Replace retired RCL-003 with RCL-010 and RCL-011 team-aware seeded ranked selection evidence for all V1 game types and non-overlapping TwinDuel members +- [x] Replace retired RCL-003 with RCL-010 and RCL-011 team-aware seeded ranked selection evidence for all V1 game types and non-overlapping TwinDuel members - [x] Implement and test local BR-049 Runner dependency substitution for development and CI - [x] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation -- [ ] Implement and test RCL-004 and RCL-005 mode separation, full-round execution, result transcription, and replay evidence -- [ ] Implement and test RCL-006 append-only journaling, epoch quarantine, and receipt-driven retry -- [ ] Implement and test RCL-007 bounded Issues-only submission without repository-content access +- [x] Implement and test RCL-004 and RCL-005 mode separation, full-round execution, result transcription, and replay evidence +- [x] Implement and test RCL-006 append-only journaling, epoch quarantine, and receipt-driven retry +- [x] Implement and test RCL-007 bounded Issues-only submission without repository-content access - [-] Complete and test RCL-008 multi-runtime execution and the container network boundary — deferred by the approved split until the public catalog contains every supported runtime - [-] Implement and test RCL-009 automated clean-install ingestion into immutable `rumble-data` facts — deferred by the approved split until a registered identity and Issues-only credential are authorized for live proof -- [ ] Reconcile external evidence, CAP-014 through CAP-016 status, stale CH-012 references, and P-003/M-008 bookkeeping without marking M-008 complete +- [x] Reconcile external evidence, CAP-014 through CAP-016 status, stale CH-012 references, and P-003/M-008 bookkeeping without marking M-008 complete diff --git a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md index ce857312c..1ea4db6c6 100644 --- a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md +++ b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md @@ -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`. Its 4-test suite and `scripts/validate_bot.py --root . --owner flemming-n-larsen --smoke` check pass; 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`. Draft [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. diff --git a/docs/capabilities/CAP-015-rumble-result-data/design.md b/docs/capabilities/CAP-015-rumble-result-data/design.md index 8f46d4b2a..03af70ea7 100644 --- a/docs/capabilities/CAP-015-rumble-result-data/design.md +++ b/docs/capabilities/CAP-015-rumble-result-data/design.md @@ -28,4 +28,4 @@ CI serializes ingestion and is the sole writer of facts and projections on `main ## 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. RDA-005 remains draft until that repository adds focused positive and negative validation and advice-generation 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-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. Draft [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. 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. diff --git a/docs/capabilities/CAP-016-rumble-client/design.md b/docs/capabilities/CAP-016-rumble-client/design.md index 3aa2b2265..cba33c42a 100644 --- a/docs/capabilities/CAP-016-rumble-client/design.md +++ b/docs/capabilities/CAP-016-rumble-client/design.md @@ -44,4 +44,4 @@ The primary distribution is a rebuildable container containing the pinned Tank R ## External evidence -The external repository records focused evidence for RCL-001, RCL-002, and RCL-004 through RCL-011; retired RCL-003 has no active evidence obligation. The accepted configuration implementation at `robocode-dev/rumble-client` commit `d19a90e99649f87664785f1dc20b5aa2f42da7d6` provides initial configuration-loader coverage toward RCL-001; RCL-001 remains incomplete until practice mode accepts configuration without a client identity and integration evidence verifies rejection before side effects. Later CH-012 implementation commits must add the remaining evidence before M-008 can complete. During P-001/M-002, those tests will receive their RCL purpose tags, and the external-evidence reconciliation set must include RCL-010 and RCL-011 before this criteria artifact can become active without changing the criterion meanings. +Draft [rumble-client#7](https://github.com/robocode-dev/rumble-client/pull/7) at `cec7c8b` holds focused RCL-001, RCL-002, and RCL-004 through RCL-011 evidence; retired RCL-003 has no active evidence obligation. Its tagged integration and unit tests cover configuration before repository access, one validated ranked snapshot, team-aware seeded selection, ranked/practice state separation, Battle Runner execution and replay evidence, durable journaling, and bounded Issues-only submission. Run `./gradlew --no-configuration-cache -PtankRoyaleSource=../tank-royale clean build` in that repository to reproduce the hermetic client and real Runner evidence. RCL-008 and RCL-009 remain deferred by the approved CH-031 split, so P-003/M-008 remains incomplete. During P-001/M-002, the external-evidence reconciliation set must include RCL-010 and RCL-011 before this criteria artifact can become active without changing the criterion meanings. From c63428127ce67a2dc2774d859ccace460ecaff11 Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 22:01:22 +0200 Subject: [PATCH 10/11] docs(CH-031): digest local rumble client completion --- .../open-questions.md | 29 ----------- .../CH-031-complete-rumble-client/proposal.md | 49 ------------------- .../CH-031-complete-rumble-client/tasks.md | 28 ----------- 3 files changed, 106 deletions(-) delete mode 100644 changes/CH-031-complete-rumble-client/open-questions.md delete mode 100644 changes/CH-031-complete-rumble-client/proposal.md delete mode 100644 changes/CH-031-complete-rumble-client/tasks.md diff --git a/changes/CH-031-complete-rumble-client/open-questions.md b/changes/CH-031-complete-rumble-client/open-questions.md deleted file mode 100644 index 5229e9424..000000000 --- a/changes/CH-031-complete-rumble-client/open-questions.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -id: CH-031-open-questions -type: open-questions -status: open -links: [CH-031] -title: Open questions for CH-031 ---- - -# CH-031 — Open questions - -## TwinDuel catalog and result identity - -Status: answered. - -The client selector treats the engine pin's `participants: 4` as four distinct catalog entries. Battle Runner instead expects two team entries that each expand to two bot processes, and `rumble-data` validates two `isTeam: true` result entries. The design already settles the shape: `docs/design/rumble/bot-submission.md` states that a team entry has exactly two `teamMembers`, the booter starts both member bots, and ranking is based on the team result reported by the server. That shape was never carried into the accepted RBC-001 acceptance criterion or the generated `bots/index.json` entry, both of which enumerate only per-bot fields, so the client cannot select a valid TwinDuel battle from published metadata before booting untrusted code. - -Should CH-031 promote the design's `teamMembers` shape into the `rumble-bots` and `rumble-data` contracts and revise selection accordingly, or should TwinDuel execution be deferred through a new criterion and plan door? - -Answer: approved by Flemming N. Larsen on 2026-08-30 in the Codex conversation. CH-031 promotes the existing `teamMembers` shape into the synchronized catalog contract and revises selection accordingly. ADR-047 records the durable decision. - -## Live completion evidence - -Status: answered. - -The public synchronized catalog currently contains one active Python bot. It cannot produce even a `1v1` ranked battle, does not contain the Java, .NET, Python, and TypeScript boundary assumed by RCL-008, and cannot support the clean-install submission required by RCL-009. A literal RCL-009 proof also requires a registered client identity, an Issues-only credential, and authorization to create a live issue whose workflow writes accepted facts to `rumble-data`. - -Should CH-031 expand and populate the public prerequisites and perform an authorized live submission, or should it deliver hermetic client evidence while leaving RCL-008, RCL-009, and M-008 incomplete for a later full change? - -Answer: approved by Flemming N. Larsen on 2026-08-30 in the Codex conversation. CH-031 completes the client against hermetic cross-repository fixtures. Public catalog population, credential-bearing submission proof, RCL-008, RCL-009, and completion of M-008 remain for a later full change. diff --git a/changes/CH-031-complete-rumble-client/proposal.md b/changes/CH-031-complete-rumble-client/proposal.md deleted file mode 100644 index ec5c696b2..000000000 --- a/changes/CH-031-complete-rumble-client/proposal.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -id: CH-031 -type: change -status: open -links: [P-003, M-008, CAP-016] -title: Complete the Rumble client locally ---- - -# CH-031 — Complete the Rumble client locally - -## What - -Complete the locally testable `robocode-dev/rumble-client` path so it can synchronize one reviewed Rumble snapshot, select and execute pinned battles through the locally built Battle Runner, retain replay-bound result evidence, durably journal completed ranked results, and prepare acknowledged issue-ops batches without repository-content write access. - -## Why - -P-003/M-008 is the next unfinished Rumble milestone. Configuration, ranked synchronization, selection, bot-cache preparation, and runtime packaging already exist in the external client, while battle execution, durable result handling, and submission remain unfinished. BR-049 is merged and may be consumed from a local Tank Royale build, so development no longer depends on a public Tank Royale release. The public bot population and credential-bearing live submission needed to complete M-008 are deliberately deferred. - -## Route - -Recommended route: full. This change adds the cross-repository team catalog contract and implements accepted CAP-016 behavior through hermetic evidence. Discovery would change the route only if the catalog already carried immutable team membership and the external client already satisfied the locally provable RCL criteria. - -## Plan - -Serves [P-003/M-008](../../docs/plans/P-003-rumble.md) without completing it. It supersedes incomplete implementation references to CH-012 and CH-030, promotes the existing TwinDuel team design into the catalog contract, and replaces the incorrect draft RCL-003 selection meaning with RCL-010. - -## Scope - -- Verify and complete RCL-001, RCL-002, and the RCL-010 configuration, synchronization, cache, and team-aware seeded-selection paths. -- Add immutable `teamMembers` metadata to the generated and synchronized catalog contracts, with focused RBC-004 evidence. -- Bind result-data validation and matchmaking advice to that catalog membership: individual game types admit only active individual entries, while TwinDuel admits only disjoint active teams whose immutable members expand to the engine pin. -- Add a reproducible local Tank Royale dependency path so client development and CI can consume the merged Runner BR-049 API without publishing Tank Royale. -- Implement strict ranked/practice separation, full-round Battle Runner execution, complete result transcription, and replay retention for RCL-004 and RCL-005. -- Implement append-only journaling, epoch quarantine, receipt-driven retry, and bounded Issues-only submission for RCL-006 and RCL-007. -- Test execution, journaling, and submission against hermetic cross-repository fixtures without claiming live public ingestion. -- Digest verified external evidence into CAP-014 through CAP-016 while leaving RCL-008, RCL-009, and P-003/M-008 incomplete. - -## Non-goals - -- Publishing Tank Royale 1.2.0 or any other release solely to support client development. -- Populating the public catalog across all supported runtimes or performing a credential-bearing live result submission. -- Changing Rumble game behavior, the Runner public API, or the accepted result envelope; result-data validation is strengthened through its existing catalog lookup rather than a wire-contract change. -- Granting repository-content, branch, release, package, Pages, fact, or projection write access to a client credential. -- Central services, centrally stored replay files, persistent secrets, or fork-pull-request result transport. -- Completing the separate M-009 user-documentation milestone. - -## Compatibility - -Local development uses the merged Runner source while ranked distribution remains gated on an immutable released Runner artifact. `teamMembers` is an additive catalog field that defaults to an empty list for individual bots; TwinDuel requires two active team entries with exactly two active members each. Ranked execution fails closed on unsupported schemas, inconsistent snapshots, source-hash or identity mismatches, incomplete battles, and behavior-version incompatibility. Practice mode has no path to ranked journal or submission state. diff --git a/changes/CH-031-complete-rumble-client/tasks.md b/changes/CH-031-complete-rumble-client/tasks.md deleted file mode 100644 index e8ed6c447..000000000 --- a/changes/CH-031-complete-rumble-client/tasks.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -id: CH-031-tasks -type: tasks -status: open -links: [CH-031] -title: Task breakdown for CH-031 ---- - -# CH-031 — Tasks - -- [x] Reserve CH-031 and branch from the accepted tip of `main` -- [x] Inventory merged `rumble-client` work and confirm the local Runner development path -- [x] Capture the completion proposal and full-route scope -- [x] Commit and push the proposal, then open the required draft PR before implementation -- [x] Correct IDR-004 to the actual `dev.robocode.tankroyale:robocode-tankroyale-runner` coordinate -- [x] Verify and complete RCL-001 configuration validation before side effects -- [x] Verify and complete RCL-002 synchronized snapshots and immutable bot-cache validation -- [x] Promote immutable TwinDuel membership into the catalog contracts and add RBC-004 evidence -- [x] Specify result-data validation and matchmaking eligibility from immutable catalog team membership, and register the RDA-005 external-evidence gap -- [x] Replace retired RCL-003 with RCL-010 and RCL-011 team-aware seeded ranked selection evidence for all V1 game types and non-overlapping TwinDuel members -- [x] Implement and test local BR-049 Runner dependency substitution for development and CI -- [x] Resolve the blocking TwinDuel identity and live-evidence scope questions before execution implementation -- [x] Implement and test RCL-004 and RCL-005 mode separation, full-round execution, result transcription, and replay evidence -- [x] Implement and test RCL-006 append-only journaling, epoch quarantine, and receipt-driven retry -- [x] Implement and test RCL-007 bounded Issues-only submission without repository-content access -- [-] Complete and test RCL-008 multi-runtime execution and the container network boundary — deferred by the approved split until the public catalog contains every supported runtime -- [-] Implement and test RCL-009 automated clean-install ingestion into immutable `rumble-data` facts — deferred by the approved split until a registered identity and Issues-only credential are authorized for live proof -- [x] Reconcile external evidence, CAP-014 through CAP-016 status, stale CH-012 references, and P-003/M-008 bookkeeping without marking M-008 complete From af10d7db62af1105b2db0f226bdd6a895786e645 Mon Sep 17 00:00:00 2001 From: "Flemming N. Larsen" Date: Sun, 30 Aug 2026 22:04:29 +0200 Subject: [PATCH 11/11] docs(CH-031): keep external evidence status-neutral --- docs/capabilities/CAP-014-rumble-bot-catalog/design.md | 2 +- docs/capabilities/CAP-015-rumble-result-data/design.md | 2 +- docs/capabilities/CAP-016-rumble-client/design.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md index 1ea4db6c6..65d60f45a 100644 --- a/docs/capabilities/CAP-014-rumble-bot-catalog/design.md +++ b/docs/capabilities/CAP-014-rumble-bot-catalog/design.md @@ -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`. Draft [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, 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. diff --git a/docs/capabilities/CAP-015-rumble-result-data/design.md b/docs/capabilities/CAP-015-rumble-result-data/design.md index 03af70ea7..2d6b12f74 100644 --- a/docs/capabilities/CAP-015-rumble-result-data/design.md +++ b/docs/capabilities/CAP-015-rumble-result-data/design.md @@ -28,4 +28,4 @@ CI serializes ingestion and is the sole writer of facts and projections on `main ## 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. Draft [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. 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-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. 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. diff --git a/docs/capabilities/CAP-016-rumble-client/design.md b/docs/capabilities/CAP-016-rumble-client/design.md index cba33c42a..68ff68bc2 100644 --- a/docs/capabilities/CAP-016-rumble-client/design.md +++ b/docs/capabilities/CAP-016-rumble-client/design.md @@ -44,4 +44,4 @@ The primary distribution is a rebuildable container containing the pinned Tank R ## External evidence -Draft [rumble-client#7](https://github.com/robocode-dev/rumble-client/pull/7) at `cec7c8b` holds focused RCL-001, RCL-002, and RCL-004 through RCL-011 evidence; retired RCL-003 has no active evidence obligation. Its tagged integration and unit tests cover configuration before repository access, one validated ranked snapshot, team-aware seeded selection, ranked/practice state separation, Battle Runner execution and replay evidence, durable journaling, and bounded Issues-only submission. Run `./gradlew --no-configuration-cache -PtankRoyaleSource=../tank-royale clean build` in that repository to reproduce the hermetic client and real Runner evidence. RCL-008 and RCL-009 remain deferred by the approved CH-031 split, so P-003/M-008 remains incomplete. During P-001/M-002, the external-evidence reconciliation set must include RCL-010 and RCL-011 before this criteria artifact can become active without changing the criterion meanings. +[rumble-client#7](https://github.com/robocode-dev/rumble-client/pull/7) at `cec7c8b` holds focused RCL-001, RCL-002, and RCL-004 through RCL-011 evidence; retired RCL-003 has no active evidence obligation. Its tagged integration and unit tests cover configuration before repository access, one validated ranked snapshot, team-aware seeded selection, ranked/practice state separation, Battle Runner execution and replay evidence, durable journaling, and bounded Issues-only submission. Run `./gradlew --no-configuration-cache -PtankRoyaleSource=../tank-royale clean build` in that repository to reproduce the hermetic client and real Runner evidence. RCL-008 and RCL-009 remain deferred by the approved CH-031 split, so P-003/M-008 remains incomplete. During P-001/M-002, the external-evidence reconciliation set must include RCL-010 and RCL-011 before this criteria artifact can become active without changing the criterion meanings.