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
44 changes: 37 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ cd Blacknode
```

First run: [Beginner Walkthrough](docs/walkthrough.md) ·
First robot: [SO-ARM101 Quickstart](docs/so-arm101-quickstart.md)
First robot: [Project Lifecycle](docs/project-lifecycle.md) ·
[SO-ARM101 Quickstart](docs/so-arm101-quickstart.md)

## Extension Packages

Expand Down Expand Up @@ -120,12 +121,41 @@ hardware services and shared runtime, configures active UFW rules, verifies the
complete device, and prints the pairing checklist. Rerunning it preserves
existing robot identities, calibrations, names, and the runtime token.

In the Blacknode editor, open **Devices**, select **Pair device**, and enter the
device URL printed by the installer, such as `http://DEVICE_IP:8765`. Paste the hardware token
printed by the installer, then paste its shared runtime token. Blacknode checks
both authenticated services before marking the device ready for deployment.
The runtime token is entered once per computer and reused automatically when
more robot hardware services from that computer are paired.
In the Blacknode editor, open **Devices** and select **Add device**. Automatic
SSH setup verifies the host key, authenticates only after confirmation, and
inspects the computer before changing it. The review shows the host OS and
Python, NVIDIA driver and CUDA toolkit, installed ROS 2 distributions, Docker
CLI/daemon state, existing Blacknode runtimes, and occupied runtime ports.
CUDA, ROS 2, and Docker system installations are preserved. Installation shows
live stage progress through package checks, download, isolated Python setup,
service installation, and pairing. If a Blacknode Runtime already exists,
choose to pair the healthy runtime, reinstall that instance, or install an
independent side-by-side instance. Side-by-side instances use separate
directories, state, pairing tokens, systemd services, and the next available
port from `8766` through `8865`. The SSH installer upgrades older downloaded
service scripts in the new checkout when instance isolation support is needed
and verifies that runtimes and robot services which were already active remain
active after the side-by-side setup.

Runtime instances installed through the editor retain only their non-secret SSH
management identity. **Uninstall runtime** asks for the SSH password again,
removes the selected instance and its UFW rule, and leaves other runtime
instances on the computer untouched. **Remove from editor** deletes only the
local registration. **Pause device** first stops active deployments, stops and
disarms attached robots, then stops that runtime service. **Resume device**
starts the service and reconnects robot monitoring while keeping motion
disarmed; previous deployments stay stopped until explicitly started again.
Each lifecycle action shows stage progress. Each robot also has its own
**Pause robot** and **Resume robot** controls. Robot Pause still sends the
direct hardware stop when its deployment runtime is unavailable and reports
that runtime address as a warning. The robot detail reports physical torque
only when the hardware provider exposes it; otherwise it shows **Not reported**
instead of inferring torque state from the motion-armed flag.
For robots on SSH-managed computers, **Restart robot service** asks for the SSH
password, resolves the exact hardware systemd unit from that robot's saved
hardware port, and restarts only that unit. Restart is blocked while a
deployment is active or the robot is armed. Blacknode then verifies that the
same authenticated robot returned and keeps motion disarmed.

The installer detects each computer's current address; it does not hardcode a
LAN IP. Use a router DHCP reservation or a resolvable hostname for robots that
Expand Down
24 changes: 14 additions & 10 deletions docs/deployment-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,16 +254,20 @@ Credentials are referenced by a local credential ID or operating-system secret
store. They are never embedded in workflows, deployment artifacts, browser
responses, logs, or provider-neutral configuration.

Each paired robot record uses the exact hardware service URL printed by
`blacknode-hardware` pairing. On a multi-robot computer, hardware services use
`8765`, `8767`, `8768`, and subsequent assigned ports. Port `8766` remains the
shared deployment runtime. The editor requires the hardware port explicitly,
rejects `8766` as a robot hardware endpoint, and derives the runtime URL from
the same host. Devices checks the hardware token and the shared runtime token
independently. Run `blacknode-runtime/service.sh pairing` on the device when
port `8766` needs a different token from its robot hardware services. The
editor stores that credential once for the shared runtime URL and reuses it
automatically as additional robots on the same computer are paired.
The editor registers the compute device and its shared runtime first. A device
record owns the runtime URL on port `8766` and the server-side runtime pairing
credential. Each child robot record uses the exact hardware service URL printed
by `blacknode-hardware` pairing. On a multi-robot computer, hardware services
use `8765`, `8767`, `8768`, and subsequent assigned ports. The editor rejects
`8766` as a robot hardware endpoint and binds every child robot to its parent
device's runtime.

Existing paired-robot records migrate into this hierarchy by grouping their
shared runtime URL. Their robot IDs remain unchanged, so saved Project links
and deployment targets continue to resolve. Run
`blacknode-runtime/service.sh pairing` when the device runtime needs to be
paired manually. The editor stores that credential once on the compute device
and reuses it for all of its robots.

For a workflow containing one `Robot` node, deployment also embeds the serial
path reported by the selected hardware service and disables runtime USB
Expand Down
118 changes: 118 additions & 0 deletions docs/guided-projects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Guided Projects

Guided Projects provide a click-through starting path for robot learning while
preserving the normal workflow editor. A Project can use the
`robot_learning` starter kit or remain fully custom.

## Robot learning starter

New Projects offer **Robot learning starter — recommended**. The Project's
**Next step** action creates, saves, links, and opens the appropriate workflow
only when that stage is needed:

| Stage | Predefined template |
|---|---|
| Collect | `teleoperation-episode-recording` from `blacknode-dataset` |
| Train | `act-training` from `blacknode-training` |
| Simulate | `isaac-act-policy-deployment` from `blacknode-isaac` |

The generated saved workflow is named for the Project, for example
`Demo Arm · Train ACT policy`. Its metadata records:

```json
{
"starter_kit": "robot_learning",
"starter_stage": "train",
"source_template": "act-training",
"project_id": "demo-arm"
}
```

Generation is idempotent. Pressing the action again opens the existing linked
starter workflow rather than creating a duplicate. The template is validated
and its package dependencies are checked before a saved workflow is created.
When a required package or template is unavailable, the Project displays the
dependency error and does not create a partial workflow.

Generated workflows are prefilled from Project context:

- collection uses a Project-specific dataset ID, task, and run IDs, selects
automatic ROS 2 transport, and remains disarmed;
- training selects the newest completed linked dataset and assigns a
Project-specific training run ID; and
- simulation selects the newest available linked policy and assigns
Project-specific Isaac run IDs while remaining in status mode.

## Evidence-driven progression

The helper advances from Project evidence:

1. install the device runtime, pair the robot, and link it to the Project;
2. create and open the recording workflow;
3. calibrate the robot required by that workflow;
4. record and save at least one dataset episode;
5. create or open the ACT training workflow;
6. export a policy artifact;
7. create or open the Isaac evaluation workflow; and
8. deploy using the Project's robot-specific deployment workflow.

Every Lifecycle card is also an action:

- Build opens the linked workflows or prepares the first starter workflow.
- Connect opens Devices.
- Configure opens the first robot workflow missing a saved calibration
selection.
- Collect, Train, and Simulate open a custom workflow or prepare their starter
workflow.
- Deploy and Operate open Deployments.

Configure turns complete only after every linked robot workflow has a saved
calibration selection. Preparing or opening a workflow alone does not make the
physical calibration complete.

Artifact capture supplies the evidence for recorded episodes, training
progress, exported policies, and completed evaluations. The helper does not
mark a stage complete merely because its template was opened.

## Custom workflows

Users can link any saved workflow at any time. For each lifecycle stage, an
existing custom linked workflow takes priority over a generated starter
workflow. Starter workflows stay ordinary editable saved workflows.

Selecting **Use custom setup** stops predefined template suggestions and keeps
all already linked workflows and artifacts. Selecting
**Use robot learning starter** enables the helper on an existing Project.

Custom Projects do not create starter workflows. This keeps Projects for
deterministic controllers, perception, agents, and other applications outside
the robot-learning sequence.

## API and storage

The Project record stores:

```json
{
"starter_kit": "robot_learning"
}
```

Existing Projects load with `starter_kit: null`.

The editor server exposes:

```text
POST /projects/{project_id}/starter-workflows/{stage}
```

`stage` is `collect`, `train`, or `simulate`. The response includes the
hydrated Project, the saved workflow reference, and whether it was newly
created.

## Safety

Starter generation only prepares and opens workflows. It does not arm a robot,
start recording, begin training, start simulation, or deploy automatically.
Robot motion remains disarmed by default and continues through the workflow's
normal calibration, stale-data, limit, and shutdown checks.
139 changes: 139 additions & 0 deletions docs/project-artifacts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Project Artifacts v1

Project Artifacts give the Blacknode project lifecycle durable evidence for
data collection, policy training, and simulation. A Project links small typed
references. The extension package that created an artifact remains the owner
of its files and native manifest.

## Goals

- Show what a Project has produced, not only which workflows it can run.
- Turn Collect, Train, and Simulate into evidence-backed lifecycle stages.
- Reuse the manifests already produced by Blacknode extension packages.
- Capture supported node outputs automatically while a linked workflow runs.
- Link existing artifacts by an exact path for work created before Projects.
- Keep model binaries, datasets, logs, credentials, and calibration data out of
the Project registry.

## Ownership

| Artifact | Authoritative owner | Indexed evidence |
|---|---|---|
| Episode dataset | `blacknode-dataset` | ID, path, task, FPS, episode/frame counts |
| Training run | `blacknode-training` | run ID, output path, phase, progress, losses |
| Checkpoint | `blacknode-training` | checkpoint path, run ID, step |
| Policy | `blacknode-training` | policy path, type, source checkpoint, dimensions |
| Replay evaluation | `blacknode-training` | episode, frames, aggregate errors |
| Simulation run | `blacknode-isaac` | run ID, log path, phase, inference counters |

The artifact index is local editor state at `.blacknode/artifacts.json`.
Projects store only `artifact_ids` in `.blacknode/projects.json`. Unlinking an
artifact from a Project does not remove the index record or its source files.
Deleting a Project does not delete artifacts.

## Reference contract

Each indexed reference has this provider-neutral shape:

```json
{
"id": "dataset-2bd193725faf064e5d7a",
"artifact_type": "dataset",
"kind": "blacknode.episode-dataset",
"provider": "blacknode-dataset",
"name": "pick-cube",
"locator": "/home/alex/.blacknode/datasets/pick-cube",
"status": "completed",
"workflow_slugs": ["collect-demonstrations"],
"metadata": {
"task": "Pick cube",
"fps": 30,
"episode_count": 12
},
"created_at": "2026-07-24T20:00:00+00:00",
"updated_at": "2026-07-24T20:10:00+00:00"
}
```

`artifact_type` is one of `dataset`, `training_run`, `checkpoint`, `policy`,
`evaluation`, or `simulation_run`. `status` is `available`, `running`,
`completed`, or `failed`.

The ID is deterministic from provider, artifact type, and locator. Repeated
status events update one reference instead of adding duplicate cards. Logical
locators under `blacknode://` are used when a managed run has an identity but
has not produced a file path yet.

Metadata is an allowlisted summary. Fields whose names look like credentials,
tokens, secrets, passwords, or authorization data are never indexed. Import is
bounded by depth and item count, and checkpoint/model binaries are never
opened.

## Supported native records

The v1 importer understands:

- `blacknode.episode-dataset`
- `blacknode.training-job`
- `blacknode.training-run`
- `blacknode.action-chunking-checkpoint`
- `blacknode.policy-artifact`
- `blacknode.policy-replay-metrics`
- `blacknode.policy-runtime` from an Isaac node

Exact-path inspection accepts a supported JSON manifest, a directory containing
`dataset.json`, `run.json`, or `manifest.json`, or a checkpoint `.pt` path. It
does not crawl the filesystem or guess from unrelated files.

## Capture flow

When a node in a saved workflow linked to the active Project succeeds:

1. the editor checks the output for a supported native record;
2. it sends only candidate output data to the Project artifact import endpoint;
3. the server sanitizes and normalizes the reference;
4. the artifact index is inserted or updated by deterministic ID; and
5. the Project links the ID and refreshes its lifecycle evidence.

Artifact capture is auxiliary evidence. A capture error cannot change a
successful node cook into a failed cook.

## Lifecycle evidence

| Stage | Complete evidence |
|---|---|
| Collect | A linked dataset reports one or more saved episodes |
| Train | A linked policy artifact exists |
| Simulate | A linked simulation run or evaluation is completed |

A created empty dataset, running training job, checkpoint, or running
simulation is shown as progress, not completion. If no artifact exists yet,
the presence of the corresponding workflow keeps the stage available.

The Project overview chooses a guided action from the first relevant gap:
record the first episode, start or monitor training, evaluate a ready policy,
then deploy and operate.

## HTTP API

- `POST /projects/{project_id}/artifacts/import` captures supported typed
records from a node output.
- `POST /projects/{project_id}/artifacts/inspect` adds supported records from
one exact local path.
- `PATCH /projects/{project_id}` with `artifact_ids` links or unlinks
references.

An import carrying `workflow_slug` is accepted only when that workflow is
linked to the Project. Read responses hydrate `artifacts` in the Project
payload and report whether filesystem-backed sources currently exist.

## Compatibility and next versions

Projects created before artifact support load with an empty `artifact_ids`
list. Existing package manifests and artifact files do not change.

Future versions can add provider registration, remote/object-store locators,
lineage between datasets/checkpoints/policies, evaluation thresholds,
deployment-to-policy links, telemetry evidence, and garbage collection for
unlinked index records. Those additions must keep the provider-owned artifact
and reference-only Project boundary.
Loading