Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3673156
docs(challenges): define quality and visual review matrix
triggeredcode Oct 14, 2026
bda5b1d
fix(cache): enforce exact LRU contract in public harness
triggeredcode Oct 14, 2026
8908edb
docs(cache): clarify constant-time recency structure
triggeredcode Oct 14, 2026
2192095
fix(cache): enforce medium public hit-rate floor
triggeredcode Oct 14, 2026
e52aa39
docs(cache): show LRU state transitions
triggeredcode Oct 14, 2026
1a61e1b
docs(chunk): illustrate frame-local reads
triggeredcode Oct 14, 2026
03b6453
docs(scheduler): show non-preemptive job timeline
triggeredcode Oct 14, 2026
767f0b1
docs(queue): show lease and requeue transitions
triggeredcode Oct 14, 2026
79644c2
docs(gate): visualize token-bucket budget
triggeredcode Oct 14, 2026
fee994a
docs(journal): show durable frame frontier
triggeredcode Oct 14, 2026
2b84ebc
docs(link): trace lost ACK recovery
triggeredcode Oct 14, 2026
de2d9e5
docs(lsm): illustrate overlap closure
triggeredcode Oct 14, 2026
4c69211
docs(stream): show watermark boundary
triggeredcode Oct 14, 2026
b7b8aa9
docs(gate): mark public scoring metadata consistently
triggeredcode Oct 14, 2026
c2e54eb
docs(challenges): record tested behavior and release gaps
triggeredcode Oct 14, 2026
9012847
docs(challenges): align examples and ranking language
triggeredcode Oct 14, 2026
0664b1b
docs(challenges): record production submission verification
triggeredcode Oct 14, 2026
90d2afb
feat: separate learner scaffolds from public baselines
triggeredcode Oct 15, 2026
dfb8fae
docs: clarify scaffold and baseline quality gates
triggeredcode Oct 15, 2026
61dfb9d
fix: align public harness protocol versions with manifests
triggeredcode Oct 15, 2026
9eba17f
docs: record scaffold and protocol submission checks
triggeredcode Oct 15, 2026
a6c61a9
docs: describe current local challenge integration
triggeredcode Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,28 @@

This repository contains independently versioned, public systems-engineering
challenges for the Rough Stack platform. Each challenge owns its scenario, contestant
interface, starter, deterministic simulator, public tests, smoke benchmark,
baseline, and public metric contract.
interface, learner scaffold, deterministic simulator, public tests, smoke
benchmark, public baseline, and metric contract.

The Rough Stack platform is maintained separately. Challenge packages depend on
versioned contracts; the platform consumes validated, immutable challenge bundles
and does not import challenge source code.
versioned contracts. Today, a local platform checkout validates and reads a
separate challenge checkout from disk. Published immutable bundles are a future
distribution format, not a requirement for running or contributing locally.

The current manifest filename and protocol fields retain the `arena` name for
compatibility with the pre-release platform. They will change only through a
versioned contract migration.

Official workloads, hidden cases, exploit tests, reference implementations, and
calibration data are intentionally absent from this repository.
Official workloads, hidden cases, exploit tests, private reference
implementations, and calibration data are intentionally absent from this
repository. Public baseline implementations remain visible for reproducibility.

Each package's manifest names two different source files. `submission.starter`
is the incomplete scaffold shown in the browser. `submission.entrypoint` is
the file replaced by submitted source inside a temporary execution workspace;
the repository copy is also the tested public baseline. Keeping these separate
lets learners start with a genuine problem without removing the baseline used
for public smoke and feasibility checks.

## Verification

Expand All @@ -30,11 +39,15 @@ Changed manifests must also pass the Rough Stack platform validator. Every smoke
benchmark must emit one valid result object and reproduce the same canonical
result when repeated with the same seed.

## Initial build order
## Local platform integration

The first public implementation slice is `cache-pressure-easy`. The remaining
families are added one at a time after the preceding challenge passes tests,
determinism checks, and the platform manifest validator.
Clone this repository beside `roughstack/web-platform` and follow the
[web-platform local setup](https://github.com/roughstack/web-platform#running-it).
The platform's `BYTEARENA_ARENA_ROOTS` setting should point to this repository's
`challenges/` directory. Its opt-in real-run check submits the easy-cache public
baseline and learner scaffold to the local Docker runner. Public baselines are
practice feasibility witnesses; the generated arenas do not yet provide ranked
scores or multi-language submissions.

## Contributing and security

Expand Down
3 changes: 2 additions & 1 deletion challenges/cache-pressure-easy/arena.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: bytearena.dev/v1
kind: Arena
metadata:
id: cache-pressure-easy
version: 1.0.0
version: 1.0.1
title: Cache Pressure
visibility: public
mode: practice
Expand All @@ -11,6 +11,7 @@ metadata:
submission:
language: go
entrypoint: starter/cache.go
starter: learner/starter.go
interface: bytearena.cache.Cache/v1
build:
command: ["go", "test", "./challenges/cache-pressure-easy/..."]
Expand Down
84 changes: 81 additions & 3 deletions challenges/cache-pressure-easy/harness/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package harness

import (
"bytes"
"fmt"
"strconv"

"github.com/roughstack/challenges/challenges/cache-pressure-easy/contract"
Expand All @@ -11,7 +12,7 @@ import (

const (
ArenaID = "cache-pressure-easy"
ArenaVersion = "1.0.0"
ArenaVersion = "1.0.1"
WorkloadID = "public-smoke-v1"
valueBytes = 96
)
Expand Down Expand Up @@ -62,8 +63,8 @@ func DefaultPublicConfig() PublicConfig {
}

// Evaluate runs a policy-independent request stream against a contestant cache.
func Evaluate(seed uint64, config PublicConfig, factory contract.Factory) Result {
result := Result{
func Evaluate(seed uint64, config PublicConfig, factory contract.Factory) (result Result) {
result = Result{
ProtocolVersion: 1,
ArenaID: ArenaID,
ArenaVersion: ArenaVersion,
Expand All @@ -75,8 +76,29 @@ func Evaluate(seed uint64, config PublicConfig, factory contract.Factory) Result
WorkloadID: WorkloadID,
},
}
defer func() {
if recovered := recover(); recovered != nil {
result.Verdict = "fail"
result.Violations = append(result.Violations, fmt.Sprintf("contestant panicked: %v", recovered))
}
}()
if factory == nil {
result.Verdict = "fail"
result.Violations = append(result.Violations, "cache factory is nil")
return result
}
if violation := validateCacheContract(seed, factory); violation != "" {
result.Verdict = "fail"
result.Violations = append(result.Violations, violation)
return result
}

cache := factory(config.CapacityBytes)
if cache == nil {
result.Verdict = "fail"
result.Violations = append(result.Violations, "cache factory returned nil")
return result
}
versions := make(map[uint64]uint64)
operations := workload.Generate(workload.Config{
Seed: seed,
Expand Down Expand Up @@ -140,6 +162,62 @@ func Evaluate(seed uint64, config PublicConfig, factory contract.Factory) Result
return result
}

// validateCacheContract uses a fresh, small instance to check exact LRU
// semantics independently of the larger performance workload. Otherwise a
// cache that always misses could pass while implementing none of the contract.
func validateCacheContract(seed uint64, factory contract.Factory) string {
unit := contract.AccountedBytes([]byte{1})
cache := factory(2 * unit)
if cache == nil {
return "cache factory returned nil during contract check"
}
a, b, c := seed+1, seed+2, seed+3
first := []byte{0x11}
cache.Put(a, first, contract.RequestMeta{})
first[0] = 0xff
cache.Put(b, []byte{0x22}, contract.RequestMeta{})
if cache.UsedBytes() != 2*unit {
return "cache must admit and exactly account for two fitting entries"
}
value, ok := cache.Get(a, contract.RequestMeta{})
if !ok || !bytes.Equal(value, []byte{0x11}) {
return "cache must return the stored value without aliasing the input"
}
value[0] = 0xee
value, ok = cache.Get(a, contract.RequestMeta{})
if !ok || !bytes.Equal(value, []byte{0x11}) {
return "cache Get must return an owned copy"
}
cache.Put(c, []byte{0x33}, contract.RequestMeta{})
if _, ok := cache.Get(b, contract.RequestMeta{}); ok {
return "cache must evict the least recently used entry"
}
for key, want := range map[uint64]byte{a: 0x11, c: 0x33} {
value, ok = cache.Get(key, contract.RequestMeta{})
if !ok || !bytes.Equal(value, []byte{want}) {
return "cache evicted or changed a more recent entry"
}
}
cache.Delete(a)
if _, ok := cache.Get(a, contract.RequestMeta{}); ok || cache.UsedBytes() != unit {
return "cache Delete must remove the key and release its accounted bytes"
}
cache.Put(c, make([]byte, 2*unit), contract.RequestMeta{})
value, ok = cache.Get(c, contract.RequestMeta{})
if !ok || !bytes.Equal(value, []byte{0x33}) || cache.UsedBytes() != unit {
return "oversized replacement must leave the resident value intact"
}
zero := factory(0)
if zero == nil {
return "cache factory returned nil for zero capacity"
}
zero.Put(a, []byte{0x11}, contract.RequestMeta{})
if _, ok := zero.Get(a, contract.RequestMeta{}); ok || zero.UsedBytes() != 0 {
return "zero-capacity cache must not admit entries"
}
return ""
}

func backingValue(seed, key, version uint64) []byte {
value := make([]byte, valueBytes)
state := seed ^ rotateLeft(key, 17) ^ rotateLeft(version, 41)
Expand Down
37 changes: 37 additions & 0 deletions challenges/cache-pressure-easy/harness/harness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,48 @@ package harness
import (
"encoding/json"
"reflect"
"strings"
"testing"

"github.com/roughstack/challenges/challenges/cache-pressure-easy/contract"
"github.com/roughstack/challenges/challenges/cache-pressure-easy/starter"
)

type neverAdmitCache struct{}

func (neverAdmitCache) Get(uint64, contract.RequestMeta) ([]byte, bool) { return nil, false }
func (neverAdmitCache) Put(uint64, []byte, contract.RequestMeta) {}
func (neverAdmitCache) Delete(uint64) {}
func (neverAdmitCache) UsedBytes() uint64 { return 0 }

type ignoreDeleteCache struct{ contract.Cache }

func (ignoreDeleteCache) Delete(uint64) {}

func TestEvaluateRejectsCachesThatDoNotImplementTheContract(t *testing.T) {
tests := []struct {
name string
factory contract.Factory
want string
}{
{"never admits", func(uint64) contract.Cache { return neverAdmitCache{} }, "admit"},
{"ignores delete", func(capacity uint64) contract.Cache {
return ignoreDeleteCache{starter.NewCache(capacity)}
}, "Delete"},
{"nil cache", func(uint64) contract.Cache { return nil }, "nil"},
{"nil factory", nil, "nil"},
{"panicking factory", func(uint64) contract.Cache { panic("broken") }, "panicked"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := Evaluate(17, DefaultPublicConfig(), test.factory)
if result.Verdict != "fail" || len(result.Violations) == 0 || !strings.Contains(result.Violations[0], test.want) {
t.Fatalf("expected %q failure, got %+v", test.want, result)
}
})
}
}

func TestEvaluateIsDeterministicAndWithinCapacity(t *testing.T) {
config := DefaultPublicConfig()
first := Evaluate(^uint64(0), config, starter.NewCache)
Expand Down
30 changes: 30 additions & 0 deletions challenges/cache-pressure-easy/learner/starter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Package starter is the learner-facing scaffold. The verified public
// implementation lives at the manifest entrypoint and is not prefilled here.
package starter

import "github.com/roughstack/challenges/challenges/cache-pressure-easy/contract"

type cache struct {
capacity uint64
// TODO: track stored values, their accounted sizes, and recency.
}

func NewCache(capacityBytes uint64) contract.Cache {
return &cache{capacity: capacityBytes}
}

func (c *cache) Get(key uint64, meta contract.RequestMeta) ([]byte, bool) {
panic("TODO: return a private copy and update recency on a hit")
}

func (c *cache) Put(key uint64, value []byte, meta contract.RequestMeta) {
panic("TODO: enforce the exact byte budget and LRU eviction")
}

func (c *cache) Delete(key uint64) {
panic("TODO: remove the entry and its accounting")
}

func (c *cache) UsedBytes() uint64 {
panic("TODO: report the charged bytes, including metadata")
}
30 changes: 14 additions & 16 deletions challenges/cache-pressure-easy/statement.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,17 @@
"kind": "figure",
"label": "FIG 1",
"illustration": {
"id": "systems.flow",
"id": "systems.snapshot",
"props": {
"label": "A cache read path",
"nodes": [
{ "label": "Request", "detail": "Get key 7" },
{ "label": "Cache", "detail": "Look up and refresh recency", "tone": "accent" },
{ "label": "Backing store", "detail": "Read only on a miss", "tone": "warning" },
{ "label": "Caller", "detail": "Receive an owned copy", "tone": "signal" }
],
"edges": ["lookup", "miss", "fill + return"]
"title": "Oldest on the left · newest on the right",
"rows": [
{ "label": "After two puts", "cells": [{ "label": "A", "detail": "oldest", "tone": "warning" }, { "label": "B", "detail": "newest", "tone": "accent" }] },
{ "label": "Get A", "cells": [{ "label": "B", "detail": "oldest", "tone": "warning" }, { "label": "A", "detail": "newest", "tone": "signal" }], "note": "A hit changes order without fetching from the backing store." },
{ "label": "Put C", "cells": [{ "label": "A", "detail": "oldest", "tone": "accent" }, { "label": "C", "detail": "newest", "tone": "signal" }], "note": "B leaves because it was least recently used." }
]
}
},
"caption": "A hit skips the backing store. A miss fetches once, admits the value if it fits, and returns a copy."
"caption": "One hit changes the eviction decision. This two-entry example illustrates order; real capacity counts each value's bytes plus metadata."
},
{
"kind": "callout",
Expand All @@ -37,9 +35,9 @@
},
{
"kind": "example",
"input": "capacity = 2 entries\nPut(A), Put(B), Get(A), Put(C)",
"output": "recency: C → A\nevicted: B",
"explain": "`Get(A)` makes A newest. When C arrives, B is the oldest entry, so B leaves. Use a map for lookup plus an ordered recency list for constant-time movement."
"input": "capacity = 66 bytes (two 1-byte values, each charged 32 metadata bytes)\nPut(A, 1B), Put(B, 1B), Get(A), Put(C, 1B)",
"output": "newest → oldest: C, A\nevicted: B",
"explain": "`Get(A)` makes A newest. When C arrives, B is the oldest entry, so B leaves. A map from keys to nodes in a doubly linked list gives constant-time lookup, recency updates, and eviction."
},
{
"kind": "constraints",
Expand All @@ -55,14 +53,14 @@
"items": [
{ "title": "Make accounting exact", "md": "Centralize each entry's charged size and update it on insert, replacement, and eviction." },
{ "title": "Separate lookup from order", "md": "Use one structure to find a key and another to move that entry to the newest position." },
{ "title": "Optimize after correctness", "md": "A linear list can pass semantics; constant-time recency maintenance improves `metadata_work`." }
{ "title": "Optimize after correctness", "md": "A linear list can pass semantics; a map plus linked list improves actual lookup and update time. The public `metadata_work` counter does not measure that internal time." }
]
},
{
"kind": "callout",
"tone": "note",
"title": "What the score is saying",
"md": "Fewer `backing_reads` means the policy retained useful data. Lower `metadata_work` means the same decisions required less bookkeeping. Correctness is always the gate."
"title": "What the metrics say",
"md": "`backing_reads` counts misses on the public trace. `metadata_work` counts harness-visible calls and accounting checks; it does not measure the time your internal recency structure takes. Correctness is the gate; this practice challenge is not ranked yet."
}
]
}
5 changes: 4 additions & 1 deletion challenges/cache-pressure-medium/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ protection against scan pollution.
budget at peak occupancy. Lower means the cache exploited its budget more fully;
it is a soft signal alongside the hit-rate and cost metrics.

Correctness gates scoring. Public smoke output is reproducible but unofficial;
The default public workload also requires a request hit rate of at least 4000
basis points (40%). This rejects a never-admit policy without requiring one
particular eviction or admission algorithm. Correctness gates scoring. Public
smoke output is reproducible but unofficial;
normalization and calibration belong to the platform and private judge.

## Verify
Expand Down
3 changes: 2 additions & 1 deletion challenges/cache-pressure-medium/arena.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: bytearena.dev/v1
kind: Arena
metadata:
id: cache-pressure-medium
version: 1.0.0
version: 1.0.1
title: Cache Pressure
visibility: public
mode: practice
Expand All @@ -11,6 +11,7 @@ metadata:
submission:
language: go
entrypoint: starter/cache.go
starter: learner/starter.go
interface: bytearena.cache.Cache/v1
build:
command: ["go", "test", "./challenges/cache-pressure-medium/..."]
Expand Down
Loading
Loading