Skip to main content

Overview

A Phylax miner registers a Bittensor axon on netuid 486 and responds to PhylaxSynapse requests from validators. Each request contains a skill bundle to analyse. You run your analysis pipeline on that bundle and return a signed SSSA. The subnet team defines the structural contract for what inputs you receive and what outputs you must produce. Your internal analysis pipeline is entirely your own. That is where you compete.
The reference repo ships a working harness for every skill type. Running the reference harness unmodified earns Tier 1 (Reference) emissions. To earn Tier 2 or Tier 3 you must replace the internal analysis logic with your own implementation.

Requirements

  • Docker 24+ with the compose plugin (docker compose version must work)
  • btcli (install guide)
  • 16 GB RAM, 4 or more CPU cores, 80 GB free disk
  • Inbound TCP port 8091 open to the public internet (validators dial this port)
  • Your shell user in the docker group: sudo usermod -aG docker $USER && newgrp docker

Setup

1

Create Wallet and Register

btcli wallet create --wallet.name miner --wallet.hotkey default
Fund the coldkey with testnet TAO from the Bittensor Discord #faucet channel.
btcli subnet register \
  --netuid 486 \
  --subtensor.network test \
  --wallet.name miner \
  --wallet.hotkey default
Verify:
btcli wallet overview --wallet.name miner --subtensor.network test
2

Install and Configure

curl -fsSL https://raw.githubusercontent.com/praxi-labs/phylax-subnet/main/scripts/install.sh | bash -s miner
Edit ~/phylax/miner/.env:
VariableWhat to set
PHYLAX_NETUID486
SUBTENSOR_NETWORKtest
WALLET_NAMEfolder name in ~/.bittensor/wallets/
WALLET_HOTKEYdefault (or the hotkey you registered)
PHYLAX_SERVER_URLnetwork server URL
PHYLAX_SERVER_HOTKEYpinned server hotkey
If you started the miner before fixing these, docker compose restart is not enough. Env vars are only read at container creation. Run docker compose up -d --force-recreate.
3

Choose Your Skill Types

You decide which skill types to support. No one assigns them. Pick what you have the infrastructure and expertise to do well.
Skill typeWhat the bundle containsWhat your harness must do
rag_knowledgeDocuments, knowledge base content. No code.Content scan. No sandbox. Compute fingerprint, detect hidden instructions, enumerate URLs, find the canary.
declarativeA SKILL.md of natural language instructions. No code.Static text analysis. No sandbox. Compute skill_md_fingerprint, run prompt injection classifier, detect Unicode anomalies, find the canary.
executable_pythonPython source plus dependency manifests.Static analysis + SBOM + Docker sandbox detonation. Emit four base traces plus imports.jsonl. Thread canary through sandbox.
executable_scriptShell scripts.Static shell taint analysis + Docker sandbox detonation. Emit four base traces plus shell_commands.jsonl.
mcp_serverMCP server with handlers and manifest.Two containers (server + your test client). Enumerate and exercise all tools, one invocation carrying the canary. Emit four base traces plus tool_calls.jsonl. Compute mcp_manifest_hash.
agent_compositionComposition manifest orchestrating child skills.Multi container cascading detonation across parent and all children. Emit aggregated base traces plus agent_calls.jsonl. Compute dependency graph hash and transitive risk score.
declarative is mandatory and automatic. The register helper and the server both inject it for you, so you only list the EXTRA types in PHYLAX_SUPPORTED_TYPES. You must declare at least one extra type, and rag_knowledge alone does not count. Valid additions: executable_python, executable_script, mcp_server, agent_composition (or rag_knowledge plus one of those four).
4

Build Your Pipeline

The reference repo ships a working harness for every skill type that earns Tier 1 emissions out of the box. To reach Tier 2 or Tier 3, replace the internals with your own analysis logic.The installer clones the source into ~/phylax/miner/src/. All paths below are relative to that directory.
Skill typeRunner fileSandbox container
rag_knowledgesrc/phylax/harness/rag_knowledge/runner.pynone
declarativesrc/phylax/harness/declarative/runner.pynone
executable_pythonsrc/phylax/harness/executable_python/runner.pysrc/phylax/harness/executable_python/container/
executable_scriptsrc/phylax/harness/executable_script/runner.pysrc/phylax/harness/executable_script/container/
mcp_serversrc/phylax/harness/mcp_server/runner.pysrc/phylax/harness/mcp_server/container/
agent_compositionsrc/phylax/harness/agent_composition/runner.pysrc/phylax/harness/agent_composition/container/
Each runner exposes run(bundle_dir, nonce, canary_id, canary_val). Your replacement must return the same dataclass shape and emit the required trace files into the evidence directory.For runtime types, the container contract:
  • Entrypoint: /harness/run.sh <bundle_path> <nonce>
  • Env vars injected by the runner: CANARY_ID, CANARY_VAL, AGENT_TIMEOUT
  • All required JSONL trace files written to /evidence/ which is bind mounted by the runner
5

Log Into Your Container Registry

Before you build and push, you must be logged into the registry where the image will live. The build helper does not handle this for you. You can use any public registry: Docker Hub, GHCR, Quay, ECR Public.
docker login
Username and password are from hub.docker.com. Free accounts get unlimited public repos. Validators pull anonymously.
The <namespace> in your image tag must match your username on that registry. For example, an image tagged docker.io/alice/phylax-sandbox-python:v1 can only be pushed by the user alice. A mismatched namespace produces push access denied ... insufficient_scope: authorization failed.
6

Build and Tag Your Sandbox Image

The cloned source ships a helper at src/scripts/build-sandbox.sh that handles the build, push, and digest extraction for you.
cd ~/phylax/miner

# Build and push in one go
./src/scripts/build-sandbox.sh executable_python <registry>/<your-username>/phylax-sandbox-python:v1
Replace <registry> with docker.io, ghcr.io, quay.io, etc. Replace <your-username> with your registry username (this must match the account you logged in with in the previous step).The helper prints the registry image and the sha256: digest at the end. Paste both into your .env:
PHYLAX_SANDBOX_IMAGE=docker.io/<your-username>/phylax-sandbox-python:v1
PHYLAX_SANDBOX_DIGEST=sha256:<digest from the helper output>
If you prefer to build manually, the Dockerfile lives at src/phylax/harness/<skill_type>/container/Dockerfile. The build context must be the container/ directory because the Dockerfile uses COPY tracer.py ... relative to itself:
cd ~/phylax/miner/src/phylax/harness/executable_python/container

docker build -t docker.io/<your-username>/phylax-sandbox-python:v1 .
docker push docker.io/<your-username>/phylax-sandbox-python:v1
docker inspect --format='{{index .RepoDigests 0}}' \
  docker.io/<your-username>/phylax-sandbox-python:v1
PHYLAX_SANDBOX_DIGEST must exactly match the image_hash you register in the next step. Validators verify this on every primary submission.
After pushing, verify the image is publicly pullable from any machine that has never seen your registry credentials:
docker logout
docker pull docker.io/<your-username>/phylax-sandbox-python:v1
If this fails, the repo is private and validators will not be able to rerun your sandbox.
7

Register Your Specialization

Validators only route tasks to miners with a current specialization on file. The cloned source ships a helper at src/scripts/register.sh that reads your .env, signs a request with your hotkey, and POSTs it to the server.Run it once after you’ve edited .env, and re-run whenever you change PHYLAX_SUPPORTED_TYPES or rebuild the sandbox image.
cd ~/phylax/miner

# First time only: install the signing dependency
pip3 install --user substrate-interface

# Register
./src/scripts/register.sh
Expected output:
==> POST https://<server>/v1/specialization/register
    hotkey: 5DLAsRvTzGpLTbMEBfFoVgX6vt1uVAJqPeDtDbMU2PpXgf2G
    types:  ['executable_python', 'declarative']
    image:  docker.io/<you>/phylax-sandbox-python:v1
    digest: sha256:8f2328f24aef3e23...
==> 200 OK
{"hotkey":"...","supported_types":["executable_python","declarative"], ...}
Every runtime type you declare needs a sandbox image. The script applies PHYLAX_SANDBOX_IMAGE / PHYLAX_SANDBOX_DIGEST to all runtime types in PHYLAX_SUPPORTED_TYPES. If you build separate images per skill type, edit .env and re-run the script for each one, or call src/scripts/register_miner.py directly with a custom .env per type.
PHYLAX_SANDBOX_DIGEST must exactly match what you pushed to your registry. Validators pull and rerun this image to verify your traces.
8

Run

cd ~/phylax/miner
docker compose pull
docker compose up -d
docker compose logs -f
Within about 30 seconds you should see:
Axon serving on [::]:8091
When a validator dispatches a task:
scan: bundle=sha256:... type=executable_python profile=standard task=...
scan done: sha256:... -> ALLOW risk=12

Primary vs Auditor Role

Every task carries a task_metadata.role field set to either primary or auditor. The validator chooses your role per task per round. You do not choose it.
Three primaries per task, picked from the highest reputation for that skill type.Submit:
  • Full SSSA
  • trace_bundle (for runtime types)
  • sandbox_manifest (for runtime types)
  • probe_evidence
Get the full timing window from the profile timing matrix.Earn full emission.
If you have been an auditor for the same skill type three rounds in a row, you are rotated into a primary slot regardless of reputation rank.

Auditor timing windows

Skill typePrimary t_min / deadlineAuditor t_min / deadline
rag_knowledge5s / 45s2s / 15s
declarative10s / 90s3s / 30s
executable_python30s / 300s10s / 90s
executable_script30s / 300s10s / 90s
mcp_server60s / 600s20s / 150s
agent_composition120s / 900s30s / 240s
The windows above are for the standard profile. fast and deep profiles scale accordingly.

What You Must Submit Per Task

Return the same PhylaxSynapse with these fields populated.
The signed SSSA. Full structure described in SSSA Schema.
A dict derived from the synapse nonce.
{
  "file_path":    "/skill/.probe_<sha256(nonce)[:16]>",
  "file_content": "<sha256(nonce)[16:48]>",
  "dns_host":     "<sha256(nonce)[:8]>.probe.phylax.ai",
  "process_echo": "<sha256(nonce)[8:24]>"
}
For runtime skill types your harness must also perform these three events inside the sandbox so they appear in fs.jsonl, network.jsonl, and process.jsonl.
dict[str, str] of {filename: base64(gzip(jsonl_bytes))}.
Skill typeRequired files
executable_pythonnetwork.jsonl.gz, fs.jsonl.gz, process.jsonl.gz, secrets.jsonl.gz, imports.jsonl.gz
executable_scriptnetwork.jsonl.gz, fs.jsonl.gz, process.jsonl.gz, secrets.jsonl.gz, shell_commands.jsonl.gz
mcp_servernetwork.jsonl.gz, fs.jsonl.gz, process.jsonl.gz, secrets.jsonl.gz, tool_calls.jsonl.gz
agent_compositionnetwork.jsonl.gz, fs.jsonl.gz, process.jsonl.gz, secrets.jsonl.gz, agent_calls.jsonl.gz
rag_knowledge, declarativeOmit entirely
Size caps (compressed): network 5 MB, fs 10 MB, process 5 MB, secrets 1 MB, imports 2 MB, shell_commands 5 MB, tool_calls 5 MB, agent_calls 10 MB. Total bundle must not exceed 30 MB.
{
  "image":          "ghcr.io/<you>/phylax-sandbox-python:v1",
  "digest":         "sha256:abc123...",
  "tracer_version": "1.0.0",
  "tracer_hash":    "sha256:def456...",
  "kernel":         "",
  "cpu_arch":       ""
}
image and digest must exactly match what you registered.

Canary Handling

Every task carries a canary_id and canary_val derived from the nonce. You must handle them correctly or your evidence score is zero.
Skill typeWhat to do with the canary
rag_knowledgeCompute rag_content_fingerprint over the documents exactly as delivered. Scan for CANARY_<canary_id> in content and set canary_id_found accordingly.
declarativeScan SKILL.md for <!-- CANARY: {canary_id} -->. Set canary_id_found = true when found. Compute skill_md_fingerprint over SKILL.md exactly as delivered.
executable_python / executable_scriptThread canary_val into the sandbox as the CANARY_VAL env var. Have your harness write it to /skill/.canary before launching the skill. Your tracer must record this filesystem op in fs.jsonl.
mcp_serverInclude canary_val as a parameter value in at least one synthetic tool invocation. The record must appear in tool_calls.jsonl.
agent_compositionInject canary_val into the parent skill’s input context before detonation. The propagation must appear in agent_calls.jsonl.

Hard Rules

Break any of these and your SSSA scores zero for that task.

No LLM for analysis

Using a live LLM to decide the verdict, score prompt injection, classify tool poisoning, or analyse skill content is forbidden. LLMs are only permitted for post-analysis enrichment.

No skill_type mismatch

Return an SSSA whose skill.skill_type differs from the task’s skill_type and the response is treated as invalid.

No early responses

Return before task_metadata.t_min_s and the response is treated as not having run the sandbox.

No late responses

Return after task_metadata.deadline_s and the submission is discarded entirely. No score, no reputation update.
The only permitted LLM allowed_use values are finding_enrichment, mitre_owasp_mapping, or cve_explanation. Any other value scores zero and flags your hotkey for a reputation penalty.

How the Validator Verifies You

1

In the same round

The validator decompresses each trace file, normalises with ts-sorted JSON, and recomputes the sha256. The hash must equal what you declared in the SSSA. The validator also scans your fs.jsonl for the canary write and checks your probe_evidence matches the nonce derivation.
2

Across your verification group

The validator dispatches the same bundle to 5 miners (3 primaries + 2 auditors). After all responses arrive, the validator computes consensus across verdict, findings, capabilities, dependencies, and policy. Your consensus score multiplies your emission. See Consensus.
3

Asynchronously for the next round

The validator pulls your registered sandbox image, verifies its digest matches what you registered, and reruns it on the same bundle and nonce. Pass adds +0.02 to your per type reputation. Fail multiplies by 0.7. Result feeds into the next round.

Configuration Reference

VariableDefaultDescription
SANDBOX_TIMEOUT60Per detonation timeout in seconds
PHYLAX_LOG_LEVELINFOLog level
PHYLAX_EVIDENCE_HOST_DIRset by install.shHost side absolute path of the evidence bind mount. Required for docker in docker.
PHYLAX_SANDBOX_IMAGEghcr.io/praxi-labs/phylax-sandbox:latestImage launched by runtime harnesses. Must match image_uri at registration.
PHYLAX_SANDBOX_DIGEST(empty)sha256:... digest of the sandbox image. Must match image_hash at registration.
PHYLAX_TRACER_VERSION1.0.0Tracer version string included in sandbox_manifest
AXON_PORT8091Host port for the miner axon

Troubleshooting

Hotkey not found. Check ls ~/.bittensor/wallets/<WALLET_NAME>/hotkeys/<WALLET_HOTKEY> exists.
Either not registered with the network, or axon unreachable. Re-run the registration step. Check inbound 8091.
You declared a runtime type (e.g. executable_python) but PHYLAX_SANDBOX_IMAGE / PHYLAX_SANDBOX_DIGEST are missing or empty in .env. Set both and re-run register.sh.
PHYLAX_SUPPORTED_TYPES is empty or only contains rag_knowledge. Add at least one of executable_python, executable_script, mcp_server, agent_composition to your .env.
Runtime type declared without a sandbox image entry. Add sandbox_images[<type>] for every runtime type you declared.
Evidence bind mount misconfigured. Re-run scripts/install.sh or set PHYLAX_EVIDENCE_HOST_DIR to the correct absolute host path.
Container UID not in host docker group. Confirm DOCKER_GID matches getent group docker.
Wrong bytes downloaded. Check bundle_url is reachable from inside the container.
Heavy bundle or slow analysis. Increase SANDBOX_TIMEOUT.

Next

SSSA Schema

Field by field reference for the signed attestation.

Probe Events

How probe events are derived and verified.

Scoring

How your submission is scored.

Reputation

How per type reputation evolves.