Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions .greptile/config.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
{
"labels": true,
"commentOnChanges": true,
"ignorePatterns": [
"docs/BUNDLE_SPEC.md",
"docs/DESIGN_CHALLENGE.md",
"docs/PRISM.md",
"docs/external-miner/relearn*.md",
"docs/external-miner/proof-tbench.md"
]
"triggerOnDrafts": true,
"autoReview": ["open", "push"],
"statusCheck": true,
"statusCommentsEnabled": true,
"ignorePatterns": "docs/BUNDLE_SPEC.md\ndocs/DESIGN_CHALLENGE.md\ndocs/PRISM.md\ndocs/external-miner/relearn*.md\ndocs/external-miner/proof-tbench.md"
}
11 changes: 9 additions & 2 deletions .greptile/rules.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# Cortex review rules

Cortex is a Python Bittensor research subnet with exactly two live challenges:
`bounty` at 2,000 basis points and `proof` at 8,000. The trust-root sum is always
10,000. Design, Prism and Relearn are historical only.
`bounty` at 3,000 basis points and `proof` at 7,000 under algorithm 2. The
owner-signed legacy 2,000/8,000 profile retains algorithm 1. The trust-root sum
is always 10,000; the new profile requires challenge-document version >=2.
Design, Prism and Relearn are historical only.

- Preserve frozen SCALE encodings, Merkle construction, aggregation and every
`base-*-v1` signature preimage. Cross-language vectors must remain green.
Algorithm 2 counts each valid Bounty report once, distributes proportionally,
scales its 30% share by min(total_valid/10, 1), and burns unused/quarantined
mass. The total includes only the signed expected participant population.
Never allow an algorithm 1 body under the new profile or activate before
the owner-signed epoch; historical seals and journals stay immutable.
- Preserve existing `BASE_*` names and deployed compatibility paths. New master
settings may add the matching `CORTEX_*` alias but conflicting values fail.
- Missing or unknown image digests, offers, baselines, topics, keys, feeds and
Expand Down
17 changes: 12 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ canonical documentation instead of duplicating runbooks.
Cortex is an autonomous research subnet on Bittensor. It has exactly two live
challenge IDs:

| Challenge | Share | Purpose |
| Challenge | Algorithm 2 share | Purpose |
| --- | ---: | --- |
| `bounty` | 2,000 bps | useful vulnerability reports, scored from the CortexLM/backend public feed |
| `proof` | 8,000 bps | operator-created research topics evaluated by Cortex's recursive language-model engine |
| `bounty` | 3,000 bps | useful vulnerability reports, scored from the CortexLM/backend public feed |
| `proof` | 7,000 bps | operator-created research topics evaluated by Cortex's recursive language-model engine |

The sum is always 10,000 basis points. Design, Prism and Relearn are retired
products. Their frozen specifications and historical miner pointers remain for
The sum is always 10,000 basis points. The owner-signed legacy 2,000/8,000
profile retains algorithm 1. The 3,000/7,000 profile requires challenge-document
version >=2 and algorithm 2; activation is an offline owner ceremony. Design,
Prism and Relearn are retired products. Their frozen specifications and historical miner pointers remain for
compatibility; no active code, service, trust-root row or leaf may register
them.

Expand Down Expand Up @@ -88,6 +90,11 @@ Follow [the trust-root ceremony](docs/how-to/trust-root.md).
- Scores come only from `BOUNTY_BACKEND_PUBLIC_URL`. Never add an offline live
scorer. On feed failure, cover every expected participant with
`NoScore(ChallengeInternal)` so the Bounty share burns without blocking Proof.
- Under algorithm 2, each valid report contributes one point regardless of severity.
Reward authors proportionally; Bounty pays `0.30 * min(total_valid / 10, 1)`.
Count cumulative published reports only for the expected participant set.
Burn unused or unmapped mass to UID0; never increase Proof or surviving
challenge shares. Keep algorithm 1 and its frozen vectors unchanged.
- A public API, quota or scoring change must update
`docs/external-miner/bounty.md` in the same change.

Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Owner-activated algorithm 2: each valid Bounty report earns one point, all
authors share proportionally, and ten valid reports unlock its full 30% of
emission. Proof retains 70%; unused Bounty mass burns to UID0. The legacy
signed 20/80 profile, algorithm 1 and historical sealed bytes remain intact.
Activation requires coordinated gateway/validator upgrades and an offline
owner signature over the new profile and epoch.
- Bounty-only launch mode with a revision-pinned, fully paginated CortexLM
backend feed, bounded public writes and readiness checks that fail closed.
- Validator production preflight, resilient bounded master/validator Bittensor RPC failover and
Expand Down Expand Up @@ -48,6 +54,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Historical bundle-root lookup retains accepted trust profiles across rotation
and restart; current weights still require the current profile. The unsigned
activation template requires an explicit epoch before it can be signed.
- Bounty reconstructs a backend-capped leaderboard from the complete report
snapshot, avoiding a permanent burn after the public log exceeds 1,000 hotkeys.
- Bounty adjudication rejects missing or misplaced severity, and external
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Cortex research subnet: Bounty and agentic Proof on Bittensor.

The Python implementation runs the gateway and both challenges on a master,
verifies sealed rewards in independent validators, and isolates research work
in Firecracker guests. Bounty receives 20% of emission; Proof receives 80%.
in Firecracker guests. Algorithm 2 assigns up to 30% of emission to Bounty
and 70% to Proof; activating it requires a new owner-signed trust root.
Proof uses Cortex's own recursive language-model engine with persistent memory,
context compaction and bounded tool execution.

Expand All @@ -20,6 +21,11 @@ trust root still contains `bounty = 2000` and `proof = 8000`: Proof emits
`ChallengeInternal` absences and its share burns to UID 0. Never renormalize
Bounty to 100%. Production pairing, report intake and adjudication stay in
`CortexLM/backend`; Cortex reads its immutable public scoring snapshots.
Algorithm 2 pays one point per valid report, proportionally across authors;
ten valid reports across expected participants unlock the full Bounty share.
The unsigned [30/70 template](config/challenges-v2.example.toml) changes nothing
until the [trust-root migration](docs/how-to/trust-root.md#activate-proportional-bounty)
is completed on the gateway and validators.

## Installation

Expand Down
17 changes: 17 additions & 0 deletions config/challenges-v2.example.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# UNSIGNED activation template. Replace development public keys, choose the
# next owner document version and activation epoch, then sign offline using
# docs/how-to/trust-root.md. No production activation occurs from this file.
version = 2
introduced_epoch = "CHOOSE_ACTIVATION_EPOCH"

[[challenges]]
id = "bounty"
public_key = "743688a1e1b2848b309205706b4dcae54bffe4233a5d7018053471e1dce45c21"
emission_share_bps = 3000
policy = "all_metagraph_hotkeys"

[[challenges]]
id = "proof"
public_key = "3e7f70f09165e265ab89ab04a4fc91dc0531d54a100c538fb14c6f008421c375"
emission_share_bps = 7000
policy = "all_metagraph_hotkeys"
12 changes: 8 additions & 4 deletions deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,14 @@ service writes is not a valid backup.
## Bounty-only launch

Set `BOUNTY_BACKEND_PUBLIC_URL` to the reviewed HTTPS `CortexLM/backend` origin
and leave `PROOF_VM_ORCHESTRATOR_URL` empty. Keep `proof.key` mounted and keep the
owner-signed trust split at `bounty = 2000`, `proof = 8000`. With no open Proof
topic, the master signs `ChallengeInternal` Proof leaves and that 8000 bps burns
to UID 0; Bounty is never scaled to 100%.
and leave `PROOF_VM_ORCHESTRATOR_URL` empty. Keep `proof.key` mounted. Legacy
deployments retain the signed `bounty = 2000`, `proof = 8000` profile until
[algorithm 2 activation](../docs/how-to/trust-root.md#activate-proportional-bounty)
coordinates the gateway and validators with a signed 3000/7000 profile.
With no open Proof topic, its entire configured share burns to UID0 through
signed `ChallengeInternal` leaves. Algorithm 2 pays up to 30% for Bounty,
proportionally to valid reports with a global ten-report ramp; Bounty is never
scaled to 100%.

Keep `BOUNTY_GATEWAY_URL` empty in CortexLM/backend unless an authenticated,
idempotent delivery contract is deployed. The production dependency for this
Expand Down
4 changes: 3 additions & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Architecture

Cortex has two scoring products: Bounty (2,000 basis points) and Proof (8,000).
Cortex has two scoring products. Algorithm 2 assigns Bounty 3,000 basis points
and Proof 7,000. The owner-signed legacy 2,000/8,000 profile retains algorithm 1;
see [activation](how-to/trust-root.md#activate-proportional-bounty).
The signed trust root fixes their shares. All challenge execution belongs to
the master; validators independently verify sealed bundles and submit weights.

Expand Down
42 changes: 30 additions & 12 deletions docs/BOUNTY.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Bounty operator reference

Bounty rewards useful vulnerability reports about the CortexLM backend. It is
20% of subnet emission. Initial production pairing, intake and adjudication live
up to 30% of subnet emission after
[algorithm 2 activation](how-to/trust-root.md#activate-proportional-bounty).
The legacy owner-signed profile retains its 20% allocation and algorithm 1.
Initial production pairing, intake and adjudication live
in CortexLM/backend. The Python subnet retains the compatibility intake below
and emits signed leaves, but does not export those local rows; the external
CortexLM/backend public feed is the sole scoring source.
Expand Down Expand Up @@ -100,22 +103,37 @@ published report is treated as an unavailable scorer, not as a zero score.

## Score

Scoring uses integer arithmetic only. A contender needs at least three decided
valid/malicious reports, nonnegative net credit, no unpriced valid report, at
least 60% precision, no more than 50% duplicate/already-fixed triage noise, and
strictly better precision than the current champion. Severity weights are 6.25%,
25%, 50% and 100% for trivial through critical.
Algorithm 2 signs each expected hotkey's exact count of `valid` reports as its
raw score. One valid report is one point regardless of severity. There is no
champion, precision gate, minimum author count or triage-noise gate. Invalid,
duplicate and already-fixed reports contribute zero points. Severity remains
required evidence for a valid publication, with no effect on its point value.

An eligible champion receives:
Let `n_i` be author i's valid count and `N = sum(n_i)` over the epoch's expected
participants, selected by the owner-signed policy and sealed metagraph:

```text
1_000_000 * precision_bps * average_severity_bps / 100_000_000
Bounty payout = 0.30 * min(N / 10, 1)
author i payout = 0.30 * n_i / max(10, N)
```

Only one hotkey is champion for the snapshot. A miner with negative net credit
gets `InvalidResponse`; other expected hotkeys get `NotAttempted`. Feed failure
produces `ChallengeInternal` for every expected participant, so the Bounty mass
burns to UID 0 while the bundle remains complete.
Five valid reports distribute 15% of subnet emission; ten or more distribute
30%, proportionally across authors. The remaining Bounty mass burns to UID0;
it never increases Proof's 70%. UID0 and unmapped author allocations also burn
without increasing other authors' allocations. Existing owner/permit submission
constraints are unchanged.

Counts use the complete cumulative report history in one pinned external
publication, with no epoch reset or new rolling window. Only expected hotkeys
enter `N`; historical authors outside the metagraph/policy are excluded.
Validated report IDs and rooted duplicate chains prevent duplicate credit.
An author with zero valid reports gets `NotAttempted`. Feed failure produces
`ChallengeInternal` for every expected participant and burns the Bounty share.

The legacy 2,000/8,000 owner profile retains algorithm 1, including its champion,
precision/severity scoring and signed encodings. A 3,000/7,000 owner profile
requires challenge-document version >=2 and algorithm 2. An algorithm 1 body
under that profile is rejected, even with a valid gateway signature.

## Operational checks

Expand Down
7 changes: 5 additions & 2 deletions docs/OPERATOR_SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ recovery. It complements the [threat model](THREAT_MODEL.md).
documents at the deployment epoch.
- [ ] Bounty and Proof public keys match their mounted signing seeds, and the
gateway public key is different from both.
- [ ] The trust root contains only `bounty = 2000` and `proof = 8000`.
- [ ] The trust root contains only Bounty and Proof: legacy 2000/8000 with
algorithm 1, or 3000/7000 with algorithm 2 and challenge-document version >=2.
Complete [activation](how-to/trust-root.md#activate-proportional-bounty) before
switching profiles; preserve old journals and sealed bytes.
- [ ] Runtime, kernel, rootfs, evaluator and experiment-pack references use
verified SHA-256 digests. No production image uses a floating tag.
- [ ] Empty or unknown pins remain fail-closed; no digest was copied from an
Expand Down Expand Up @@ -51,7 +54,7 @@ recovery. It complements the [threat model](THREAT_MODEL.md).
probe, and a report outage test returns 503 without a row.
- [ ] In Bounty-only mode, `PROOF_VM_ORCHESTRATOR_URL` is empty, no Proof topic
is open, and a completed epoch contains signed `ChallengeInternal` Proof
leaves whose 8000 bps burn to UID 0 without blocking Bounty.
leaves whose 7000 bps (8000 under algorithm 1) burn to UID 0 without blocking Bounty.
- [ ] When Proof is enabled, `/v1/status` reports a valid topic, sealed baseline,
registered runner, pinned image, open inference offer and compatible executor
offer; its failure matrix returns 503 without a scored row.
Expand Down
6 changes: 4 additions & 2 deletions docs/PROOF.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Proof operator reference

Proof is 80% of Cortex emission. An operator supplies a research objective; a
Proof is 70% of Cortex emission under algorithm 2 (80% under the legacy
owner-signed profile). An operator supplies a research objective; a
topic-scoped recursive language-model agent installs its environment, proposes
measurable rules, creates private evaluation material, measures a baseline and
publishes miner documentation. Miners submit code and artifacts against the
Expand Down Expand Up @@ -287,7 +288,8 @@ Proof score is the sum of its topic masses.

When no topic is open, no baseline is sealed or scoring infrastructure is
unavailable, Proof emits `NoScore(ChallengeInternal)` for the expected set. Its
8,000 basis points burn to UID 0 while preserving complete bundle coverage.
7,000 basis points (8,000 under algorithm 1) burn to UID 0 while preserving
complete bundle coverage.

## Readiness and verification

Expand Down
6 changes: 4 additions & 2 deletions docs/external-miner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ reproduction or on-chain payment.

| Challenge | Emission share | Guide |
|-----------|----------------|-------|
| `bounty` | 2000 bps (20%) | [Pair an account and report bugs](bounty.md) |
| `proof` | 8000 bps (80%) | [Discover topics and submit research](proof.md) |
| `bounty` | up to 3000 bps (30%), algorithm 2 | [Pair an account and report bugs](bounty.md) |
| `proof` | 7000 bps (70%), algorithm 2 | [Discover topics and submit research](proof.md) |

The legacy owner-signed profile remains 2000/8000 until
[algorithm 2 activation](../how-to/trust-root.md#activate-proportional-bounty).
These are the only live challenge ids. Proof topics are operator-published,
signed documents discovered through the API, never a built-in catalog. No
particular benchmark, runner, model or topic is promised by this repository.
Expand Down
58 changes: 35 additions & 23 deletions docs/external-miner/bounty.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

# Bounty miner guide

Bounty (`bounty`, 2000 bps) accepts reproducible Cortex product and backend bug
reports associated with your Bittensor hotkey. Install the [Python CLI](README.md)
Bounty (`bounty`, up to 3000 bps under algorithm 2) accepts reproducible Cortex
product and backend bug reports associated with your Bittensor hotkey. Install the [Python CLI](README.md)
and obtain the gateway URL from the subnet operator.

The initial production miner flow pairs and files reports in CortexLM/backend.
Expand Down Expand Up @@ -143,31 +143,43 @@ Stable adjudication, pricing and backlog gates are not retried. A waiting
adjudication backlog with no published report also fails closed instead of
scoring every miner as `NotAttempted`.

| Adjudication | Effect |
|--------------|--------|
| `valid` with severity | Eligible evidence, subject to the scoring gates |
| `valid` without severity | Not creditable; missing severity prevents eligibility |
| `already_fixed_not_prod` | No reward or direct penalty; counts as triage noise |
| `invalid_malicious` | Negative credit; may lead to a burn outcome |
| `duplicate` | No extra reward or direct penalty; counts as triage noise |

Paid score is precision times mean severity impact, subject to champion
displacement and eligibility gates. Precision is priced valid reports divided
by priced valid plus malicious reports. The minimum precision is 6000 bps,
and at least three decided reports are required. Severity levels are
`trivial`, `minor`, `major` and `critical`. Unpriced valid rows cannot be used
to manufacture credit.

The duplicate/already-fixed triage-noise ratio is an **off-score gate**. It is
not multiplied into the visible precision-times-severity score; exceeding
5000 bps rejects eligibility. A high report count is not a substitute for
precision and severity.
| Adjudication | Algorithm 2 points |
|--------------|--------------------|
| `valid` with severity | 1, regardless of severity |
| `valid` without severity | Invalid publication; scoring fails closed |
| `already_fixed_not_prod` | 0 |
| `invalid_malicious` | 0 |
| `duplicate` | 0; the original valid report is counted once |

Every author with valid evidence participates proportionally. There is no
champion, precision gate, minimum of three reports, severity weighting or
triage-noise gate. Severity (`trivial`, `minor`, `major`, `critical`) remains
required publication evidence and does not affect point value.

For `N` valid reports across the epoch's expected participants, the total Bounty
payout is `0.30 * min(N / 10, 1)` of subnet emission. An author with `n` valid
reports gets `0.30 * n / max(10, N)`. Thus five valid reports distribute 15%;
ten or more distribute 30%. Unused mass burns to UID0, never to Proof or other
authors. Proof retains its separate 70% share. An allocation to UID0 or an
unmapped author burns without increasing another author's allocation.

Counts include cumulative published history at one immutable revision, without
an epoch reset or rolling window. The population is the sealed metagraph's
hotkeys selected by the owner-signed participant policy. Historical authors
outside that population do not enter the total. Duplicate and rejected reports
never add points. Chain weights retain the protocol's independent u16 rounding.

`GET /v1/status` exposes the active `scoring_version`, `points_per_valid_report`,
`full_share_reports`, population and window. Algorithm 2 requires the owner-signed
3000/7000 profile and document version >=2. Until the gateway and validators
complete [activation](../how-to/trust-root.md#activate-proportional-bounty),
legacy 2000/8000 deployments retain algorithm 1 and its champion/precision rules.

If the backend is unreadable, unconfigured or inconsistent, report intake
returns `503` without storing a report. Emission pays nobody from Bounty and
covers the expected participant set with `NoScore(ChallengeInternal)` leaves.
The 2000 bps share then burns to uid 0 through normal sealing. There is no
offline scorer or forced simulation path.
The configured Bounty share then burns to uid 0 through normal sealing. There
is no offline scorer or forced simulation path.

Validators independently verify the [sealed bundle](validators.md); they do
not rerun reports or fetch the Bounty feed. See [troubleshooting](troubleshoot.md)
Expand Down
Loading
Loading