mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-01 20:33:50 +00:00
feat(specs): OpenObject and OpenSlice 0.1 (#192)
OpenObject is a bucket you can mount: keyed objects as ipfile swarms placed on OpenDisk disks under pay2seed at a stated redundancy (three replicas on three operators in two countries by default), an ipdb index as the bucket's clock, a repair loop, an HTTP API, an S3 mapping and a mount whose consistency is close-to-open by seq. d1sks.com is the reference store. OpenSlice is a container whose compute is rented from one market and whose disk is mounted from another: a host descriptor at /.well-known/openslice.json, one signed slice file (image by digest, OpenCPU/OpenMemory/OpenGPU units, OpenObject mounts, OpenCreds env, ports, placement, lifetime), and a reservation that is a paid2seed lease applied to compute with presence proofs per epoch. slic3s.com is the reference marketplace; c0mpute hosts take the slice role. Both are registered under OpenServer in the catalogs family with landing pages, rows in the OpenSwarm family table, and the spec-discovery contract. llms.txt now cites the specification URL for child specs too, which every block under OpenServer had been missing. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
8e4ea2f997
commit
c7cecb2955
8 changed files with 1019 additions and 3 deletions
|
|
@ -15,6 +15,8 @@ describe.each([
|
|||
{ slug: "openfleet", name: "OpenFleet", family: "process" },
|
||||
{ slug: "openrental", name: "OpenRental", family: "catalogs" },
|
||||
{ slug: "openwall", name: "OpenWall", family: "people" },
|
||||
{ slug: "openobject", name: "OpenObject", family: "catalogs" },
|
||||
{ slug: "openslice", name: "OpenSlice", family: "catalogs" },
|
||||
{ slug: "openstack", name: "OpenStack.md", family: "catalogs" }
|
||||
])("$name public discovery", ({ slug, name, family }) => {
|
||||
it("serves the specification through its family and docs index", () => {
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ export function GET(): Response {
|
|||
const url = `${SITE_URL}${spec.landing ?? spec.doc ?? ""}`;
|
||||
const doc = spec.doc && spec.landing ? ` Specification: ${SITE_URL}${spec.doc}.` : "";
|
||||
const head = `- [${spec.name}](${url}): ${spec.line}.${doc}`;
|
||||
const kids = children.map(
|
||||
(c) => ` - [${c.name}](${SITE_URL}${c.landing ?? c.doc ?? ""}): ${c.line}.`
|
||||
);
|
||||
const kids = children.map((c) => {
|
||||
const kidDoc = c.doc && c.landing ? ` Specification: ${SITE_URL}${c.doc}.` : "";
|
||||
return ` - [${c.name}](${SITE_URL}${c.landing ?? c.doc ?? ""}): ${c.line}.${kidDoc}`;
|
||||
});
|
||||
return [head, ...kids];
|
||||
});
|
||||
return `## ${family.name}\n\n${family.line}. Family page: ${SITE_URL}/specs/${family.slug}\n\n${lines.join("\n")}`;
|
||||
|
|
|
|||
230
apps/logicsrc-web/src/app/openobject/page.tsx
Normal file
230
apps/logicsrc-web/src/app/openobject/page.tsx
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
import Link from "next/link";
|
||||
import type { ReactNode } from "react";
|
||||
import type { Metadata } from "next";
|
||||
import { SiteShell } from "@/components/site-shell";
|
||||
import { mono, pre, table, td, th } from "../openontology/ui";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "OpenObject · LogicSRC",
|
||||
description:
|
||||
"OpenObject is a bucket you can mount: keyed objects encrypted by their owner, placed on paid OpenDisk disks under a stated redundancy such as three replicas, verified every period, repaired when a disk fails, listed by prefix and read back by path. Reference store d1sks.com.",
|
||||
alternates: { canonical: "/openobject" }
|
||||
};
|
||||
|
||||
const DESCRIPTOR = `{
|
||||
"name": "d1sks.com",
|
||||
"operator": "https://profullstack.com/.well-known/openprofile.md",
|
||||
"key": "ed25519:7c02…0c3b",
|
||||
"api": "https://d1sks.com/openobject/v1",
|
||||
"hubs": ["https://d1sks.com/api/openswarm"],
|
||||
"disks": "https://d1sks.com/api/disks",
|
||||
"policies": [
|
||||
{ "id": "3x", "mode": "replicas", "replicas": 3, "min_operators": 3, "min_countries": 2, "default": true },
|
||||
{ "id": "rs-10-4", "mode": "erasure", "k": 10, "parity": 4, "min_operators": 14 }
|
||||
],
|
||||
"price": { "currency": "USD", "per_gib_month": { "3x": 0.036, "rs-10-4": 0.017 }, "per_gib_transfer": 0.005 },
|
||||
"capacity": { "free_gib": 184000, "disks": 412 },
|
||||
"accepts": { "encryption": ["owner", "store"], "mounts": ["fuse", "nfs", "webdav", "s3"] },
|
||||
"proof": { "every_hours": 6, "repair_within_hours": 24 },
|
||||
"record": { "source": "https://d1sks.com/api/openswarm/pay2seed/requesters/ed25519:7c02…0c3b", "lost": 0 }
|
||||
}`;
|
||||
|
||||
const OBJECT = `{
|
||||
"type": "openobject.object",
|
||||
"bucket": "ed25519:3a9f…4a6c",
|
||||
"key": "photos/2026/09/a.jpg",
|
||||
"rev": 3, "seq": 48211,
|
||||
"id": "sha256:d6c3…93ff",
|
||||
"size": 4194304,
|
||||
"swarm": { "infohashV2": "sha256:4b74…a342" },
|
||||
"policy": { "mode": "replicas", "replicas": 3 },
|
||||
"holders": [
|
||||
{ "disk": "ed25519:a41e…7b0a", "lease": "sha256:5c02…", "provenAt": "2026-09-21T06:00:05Z" },
|
||||
{ "disk": "ed25519:9d3c…11ef", "lease": "sha256:71aa…", "provenAt": "2026-09-21T06:00:09Z" },
|
||||
{ "disk": "ed25519:02be…c8d0", "lease": "sha256:c3f0…", "provenAt": "2026-09-21T05:59:58Z" }
|
||||
],
|
||||
"state": "healthy"
|
||||
}`;
|
||||
|
||||
const LOOP: Array<[string, string]> = [
|
||||
["1. Write", "PUT the bytes, or a record for a swarm already seeded. The client keeps its copy until the store says healthy."],
|
||||
["2. Place", "One pay2seed offer per object with seeders.min = replicas, from the owner's escrow, onto distinct disks, operators and countries."],
|
||||
["3. Prove", "Every holder answers paid2seed challenges each period; provenAt on the record is the last one the store saw."],
|
||||
["4. Repair", "A failed holder is marked at once; a replacement is leased within repair_within_hours; the object is degraded, never silently short."],
|
||||
["5. Read", "GET by key, Range honoured, verified against id before the last byte. LIST by prefix from the index, never from a disk."],
|
||||
["6. Mount", "Keys are paths, the index is the metadata, the swarm is the data, writes are write-back, close-to-open by seq."]
|
||||
];
|
||||
|
||||
const MAPPING: Array<[string, string]> = [
|
||||
["offers[]", "one per policy: kind storage, model p2p, management managed"],
|
||||
["offers[].price", "{ amount: per_gib_month[policy], currency, interval: month, unit: gib }"],
|
||||
["offers[].stock", "in_stock while capacity.free_gib is above zero"],
|
||||
["location", "the pool's countries, unchanged"]
|
||||
];
|
||||
|
||||
const ABSENT: Array<[string, string]> = [
|
||||
["No settlement of its own", "Every byte held is a pay2seed offer and a paid2seed lease. This document adds the index, the policy and the repair loop, nothing under them."],
|
||||
["No plaintext at a disk", "With owner encryption a disk holds ciphertext it cannot read and a store holds an index it cannot decrypt."],
|
||||
["No central registry", "A store is anyone with an index and a hub account. A bucket moves by handing a second store its record and its index."],
|
||||
["No POSIX", "A mount is a bucket seen as paths. It promises close-to-open by seq and no locks, and no more."],
|
||||
["No consensus", "One bucket key, one index, one clock. Two stores serving one bucket follow the same feed."]
|
||||
];
|
||||
|
||||
export default function OpenObjectPage(): ReactNode {
|
||||
return (
|
||||
<SiteShell active="OpenObject">
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<p className="eyebrow">LogicSRC standards surface</p>
|
||||
<h2>OpenObject</h2>
|
||||
<p>
|
||||
A bucket you can mount: keyed objects, encrypted by their owner, kept on paid disks at a
|
||||
stated redundancy, verified every period, repaired when a disk fails, and read back by path
|
||||
from anywhere.
|
||||
</p>
|
||||
</div>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
<Link href="/openswarm">OpenSwarm</Link> says how one swarm is paid to be held and how a
|
||||
holder proves it still holds it. <Link href="/opendisk">OpenDisk</Link> says how a disk is
|
||||
found. What neither says is what an application needs: a bucket with a name, a thousand keys
|
||||
under it that change, a promise that each object is on three different machines in two
|
||||
countries, a list by prefix, a version history, and a mount so a process can open a path
|
||||
without knowing any of the above. OpenObject is that shape written down, so a bucket at one
|
||||
store is the same bucket at another.
|
||||
</p>
|
||||
<p style={{ color: "#5b6b7a" }}>
|
||||
Status: 0.1. <a href="https://d1sks.com">d1sks.com</a> is the reference store, running every
|
||||
bucket at three replicas on three operators in two countries by default. Every store is also
|
||||
a storage offer in the <Link href="/openserver">OpenServer</Link> sense. An{" "}
|
||||
<Link href="/openslice">OpenSlice</Link> slice mounts a bucket as its disk.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The store descriptor</h2>
|
||||
<p>
|
||||
Served at <code style={mono}>/.well-known/openobject.json</code>. Only a name, an API and
|
||||
one policy are required.
|
||||
</p>
|
||||
</div>
|
||||
<pre style={pre}>{DESCRIPTOR}</pre>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
<code style={mono}>policies</code> is what the store will run: <code style={mono}>replicas</code>{" "}
|
||||
means every holder has the whole object, <code style={mono}>erasure</code> means every holder
|
||||
has one shard and any k rebuild it. <code style={mono}>min_operators</code> and{" "}
|
||||
<code style={mono}>min_countries</code> are floors on distinctness. <code style={mono}>disks</code>{" "}
|
||||
is the pool, as OpenDisk descriptors, so an owner reads it before trusting a promise of three
|
||||
operators. <code style={mono}>record.lost</code> is how many objects ever went below the read
|
||||
threshold, and a store that has lost one says so.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The object</h2>
|
||||
<p>One record per revision, appended to the bucket's index, an ipdb feed under the bucket key.</p>
|
||||
</div>
|
||||
<pre style={pre}>{OBJECT}</pre>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
<code style={mono}>key</code> is a path. <code style={mono}>seq</code> is the bucket's
|
||||
clock: the higher seq is the newer statement about a key. <code style={mono}>id</code> is
|
||||
the SHA-256 of the plaintext and the ETag. <code style={mono}>holders</code> are the disks
|
||||
under lease, one per replica or per shard. <code style={mono}>state</code> is healthy,
|
||||
degraded, lost or pending, and a read of a degraded object still succeeds.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The loop</h2>
|
||||
<p>Nothing on the swarm side changes. The store keeps the index and posts the offers.</p>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<tbody>
|
||||
{LOOP.map(([step, what]) => (
|
||||
<tr key={step}>
|
||||
<td style={td}>
|
||||
<strong>{step}</strong>
|
||||
</td>
|
||||
<td style={td}>{what}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<p style={{ color: "#41505d", marginTop: "1rem" }}>
|
||||
A store may also serve S3, because every tool already speaks it: ETag is the id, versions are
|
||||
revisions, multipart becomes one swarm. Owner-encrypted buckets are not reachable over S3,
|
||||
because S3 has nowhere to put the key.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>As an OpenServer offer</h2>
|
||||
<p>A store is a storage offer; its disks are listed separately as OpenDisk offers.</p>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={th}>OpenServer</th>
|
||||
<th style={th}>from OpenObject</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{MAPPING.map(([key, from]) => (
|
||||
<tr key={key}>
|
||||
<td style={td}>
|
||||
<code style={mono}>{key}</code>
|
||||
</td>
|
||||
<td style={td}>{from}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>What is deliberately absent</h2>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<tbody>
|
||||
{ABSENT.map(([what, why]) => (
|
||||
<tr key={what}>
|
||||
<td style={td}>
|
||||
<strong>{what}</strong>
|
||||
</td>
|
||||
<td style={td}>{why}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>Where everything lives</h2>
|
||||
</div>
|
||||
<ul style={{ color: "#41505d", lineHeight: 1.9, paddingLeft: "1.1rem" }}>
|
||||
<li>
|
||||
<Link href="/docs/openobject">Specification</Link>: the store descriptor, the bucket, the
|
||||
object, placement, repair, the API, mounting, S3, the OpenServer mapping, c0mpute
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://d1sks.com">d1sks.com</a>: the reference store, three replicas by default
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/opendisk">OpenDisk</Link>: the disks a store places onto;{" "}
|
||||
<Link href="/openswarm">OpenSwarm</Link>: pay2seed and paid2seed for holding and proof,
|
||||
ipdb for the index
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/openslice">OpenSlice</Link>: the container that mounts a bucket;{" "}
|
||||
<Link href="/openserver">OpenServer</Link>: the storage offer a store maps onto
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</SiteShell>
|
||||
);
|
||||
}
|
||||
227
apps/logicsrc-web/src/app/openslice/page.tsx
Normal file
227
apps/logicsrc-web/src/app/openslice/page.tsx
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
import Link from "next/link";
|
||||
import type { ReactNode } from "react";
|
||||
import type { Metadata } from "next";
|
||||
import { SiteShell } from "@/components/site-shell";
|
||||
import { mono, pre, table, td, th } from "../openontology/ui";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "OpenSlice · LogicSRC",
|
||||
description:
|
||||
"OpenSlice is a container whose compute is rented from one market and whose disk is mounted from another: a host serves /.well-known/openslice.json, a slice is one signed file, the state lives in an OpenObject bucket, so the host is interchangeable. Reference marketplace slic3s.com.",
|
||||
alternates: { canonical: "/openslice" }
|
||||
};
|
||||
|
||||
const DESCRIPTOR = `{
|
||||
"name": "rig-7b, Helsinki",
|
||||
"operator": "https://rig-7b.example/.well-known/openprofile.md",
|
||||
"key": "ed25519:b70c…9c2b",
|
||||
"hubs": ["https://slic3s.com/api/openswarm", "https://c0mpute.com/api/openswarm"],
|
||||
"runtime": { "engine": "crun", "oci": "1.1", "rootless": true, "arch": "x86_64", "gpu": "nvidia" },
|
||||
"capacity": { "vcpu_free": 20, "ram_mb_free": 81920, "scratch_gb_free": 800,
|
||||
"gpu": [{ "model": "NVIDIA RTX 4090", "count": 1, "vram_mb": 24576, "free": 1 }] },
|
||||
"price": { "currency": "USD", "per_vcpu_hour": 0.006, "per_gib_ram_hour": 0.002, "per_gpu_hour": 0.35 },
|
||||
"location": { "countries": ["FI"] },
|
||||
"network": { "bandwidth_mbps": 1000, "ipv4": 1, "ipv6": true, "ports": "any", "domains": true },
|
||||
"accepts": { "images": ["ghcr.io", "docker.io", "openobject"], "privileged": false, "mounts": ["openobject"] },
|
||||
"proof": { "kinds": ["presence", "probe"], "epoch_seconds": 3600 },
|
||||
"record": { "source": "https://slic3s.com/api/openswarm/openslice/hosts/ed25519:b70c…9c2b", "standing": 96, "evicted": 0 },
|
||||
"payout": { "payee": "ed25519:b70c…9c2b", "network": "eip155:8453" }
|
||||
}`;
|
||||
|
||||
const SLICE = `{
|
||||
"type": "openslice.slice",
|
||||
"id": "ed25519:5e1d…1e6d",
|
||||
"name": "shop-api",
|
||||
"image": { "ref": "ghcr.io/ana/shop-api@sha256:1f0e…d9c2" },
|
||||
"compute": { "vcpu": 2, "ram_mb": 4096, "gpu": null, "scratch_gb": 10 },
|
||||
"mounts": [
|
||||
{ "bucket": "ed25519:3a9f…4a6c", "prefix": "shop/", "path": "/data", "mode": "rw", "cache_gb": 4 }
|
||||
],
|
||||
"env": [{ "name": "DATABASE_URL", "vault": "opencreds://ana.example/shop/database-url" }],
|
||||
"ports": [{ "container": 8080, "protocol": "tcp", "public": true, "domain": "api.shop.example" }],
|
||||
"health": { "http": "/healthz", "every_seconds": 30 },
|
||||
"placement": { "countries": ["FI", "DE", "NL"], "near": "ed25519:3a9f…4a6c", "min_standing": 80 },
|
||||
"lifetime": { "hours": 720, "renew": true, "restart": "always" },
|
||||
"price_cap": { "currency": "USD", "per_hour": 0.05 }
|
||||
}`;
|
||||
|
||||
const RUN: Array<[string, string]> = [
|
||||
["1. Read", "The host descriptor for accepts, capacity and price, and record.source at the hub for standing."],
|
||||
["2. Reserve", "An openslice.reservation at one of the host's hubs: the spec, hours, an hourly price, the budget escrowed."],
|
||||
["3. Take", "The host takes it on its next poll or when the hub pushes, and answers with an address per public port."],
|
||||
["4. Start", "Pull by digest, resolve env from the vault, attach the mounts inside the slice's namespace, apply cgroup limits, run."],
|
||||
["5. Prove", "One signed presence record per epoch, a probe of health from outside; a proven epoch is paid, a missed one is not."],
|
||||
["6. Move", "Stop here, reserve there under the same id; the mounts reattach at the index's current seq. Nothing on the old host is needed."]
|
||||
];
|
||||
|
||||
const MAPPING: Array<[string, string]> = [
|
||||
["offers[].kind", "cloud, model p2p for a peer"],
|
||||
["offers[].compute", "{ vcpu: vcpu_free, ram_mb: ram_mb_free, arch }"],
|
||||
["offers[].gpu", "capacity.gpu[0] as an OpenGPU block, count its free"],
|
||||
["offers[].price", "{ amount: per_vcpu_hour, currency, interval: hour, unit: vcpu }"],
|
||||
["offers[].stock", "in_stock while threads and memory are free and slices_running is below slices_max"]
|
||||
];
|
||||
|
||||
const ABSENT: Array<[string, string]> = [
|
||||
["No orchestration", "One slice is one container on one host. No pods, no services, no autoscaling. Two slices find each other by domain."],
|
||||
["No confidential compute", "A host can read what the container reads. What is promised is the other direction: nothing on the host is needed to get the slice back."],
|
||||
["No persistent local disk", "Scratch is gone on a move. State that must survive is in a mount."],
|
||||
["No network between slices", "Each slice has its own address on its own host. A private network across hosts is a different specification."],
|
||||
["No settlement of its own", "The reservation is a lease, the epoch is a period, the presence record is a proof, payout is ippay."]
|
||||
];
|
||||
|
||||
export default function OpenSlicePage(): ReactNode {
|
||||
return (
|
||||
<SiteShell active="OpenSlice">
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<p className="eyebrow">LogicSRC standards surface</p>
|
||||
<h2>OpenSlice</h2>
|
||||
<p>
|
||||
A container whose compute is rented from one market and whose disk is mounted from
|
||||
another, so the host is interchangeable: stop the slice here, start it there, the mount
|
||||
reattaches.
|
||||
</p>
|
||||
</div>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
A <a href="https://c0mpute.com">c0mpute</a> job ends; a service does not. A web app, a game
|
||||
server, an agent that listens for messages need a share of a machine for a while, not a job
|
||||
done. OpenSlice is that share written down: a host puts its free threads, memory, GPU, price,
|
||||
runtime and policy at <code style={mono}>/.well-known/openslice.json</code>, an owner writes
|
||||
one signed file that says image, resources, mounts, ports and lifetime, and a reservation at
|
||||
a hub matches them for a number of hours with proofs every epoch. The durable state is an{" "}
|
||||
<Link href="/openobject">OpenObject</Link> bucket kept at three replicas elsewhere, which is
|
||||
what makes a peer's machine tolerable to run on.
|
||||
</p>
|
||||
<p style={{ color: "#5b6b7a" }}>
|
||||
Status: 0.1. <a href="https://slic3s.com">slic3s.com</a> is the reference marketplace: every
|
||||
host descriptor it has read, standing from the hubs each names, and a launcher that takes a
|
||||
slice spec. Compute from c0mpute.com, disk from d1sks.com, the pair from slic3s.com. The name
|
||||
is shared with ETSI's OpenSlice, an operations system for 5G network slicing; this
|
||||
document is about containers.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The host descriptor</h2>
|
||||
<p>
|
||||
Served at <code style={mono}>/.well-known/openslice.json</code>. Only a name, free threads,
|
||||
free memory and the two hourly prices are required.
|
||||
</p>
|
||||
</div>
|
||||
<pre style={pre}>{DESCRIPTOR}</pre>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
<code style={mono}>capacity</code> is in <Link href="/docs/opencpu">OpenCPU</Link>,{" "}
|
||||
<Link href="/docs/openmemory">OpenMemory</Link> and <Link href="/docs/opengpu">OpenGPU</Link>{" "}
|
||||
units, and <code style={mono}>*_free</code> is what a new slice can have now.{" "}
|
||||
<code style={mono}>runtime</code> is what runs the container. <code style={mono}>accepts</code>{" "}
|
||||
is policy stated up front. <code style={mono}>record.evicted</code> counts slices the host
|
||||
stopped before the owner did, and a marketplace ranks on the hub's number, not the
|
||||
file's.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The slice</h2>
|
||||
<p>One signed file. The id is the slice key and it keeps it across hosts, which is what makes a move a move.</p>
|
||||
</div>
|
||||
<pre style={pre}>{SLICE}</pre>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
<code style={mono}>image</code> is by digest, from a registry or from a bucket, so it
|
||||
outlives the registry. <code style={mono}>mounts</code> are OpenObject buckets seen as
|
||||
directories, the content key granted to the slice, not the host.{" "}
|
||||
<code style={mono}>env</code> resolves secrets from an <Link href="/opencreds">OpenCreds</Link>{" "}
|
||||
vault at start. <code style={mono}>placement.near</code> names a bucket so the marketplace
|
||||
prefers hosts on the same network as its holders.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>Running one</h2>
|
||||
<p>The disk protocols were written first. A reservation is a lease, an epoch is a period, a presence record is a proof.</p>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<tbody>
|
||||
{RUN.map(([step, what]) => (
|
||||
<tr key={step}>
|
||||
<td style={td}>
|
||||
<strong>{step}</strong>
|
||||
</td>
|
||||
<td style={td}>{what}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>As an OpenServer offer</h2>
|
||||
<p>A host is a hosting offer, and a directory that reads OpenServer lists it without a second parser.</p>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={th}>OpenServer</th>
|
||||
<th style={th}>from OpenSlice</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{MAPPING.map(([key, from]) => (
|
||||
<tr key={key}>
|
||||
<td style={td}>
|
||||
<code style={mono}>{key}</code>
|
||||
</td>
|
||||
<td style={td}>{from}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>What is deliberately absent</h2>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<tbody>
|
||||
{ABSENT.map(([what, why]) => (
|
||||
<tr key={what}>
|
||||
<td style={td}>
|
||||
<strong>{what}</strong>
|
||||
</td>
|
||||
<td style={td}>{why}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>Where everything lives</h2>
|
||||
</div>
|
||||
<ul style={{ color: "#41505d", lineHeight: 1.9, paddingLeft: "1.1rem" }}>
|
||||
<li>
|
||||
<Link href="/docs/openslice">Specification</Link>: the host descriptor, the slice, running
|
||||
one, the reservation, the marketplace, the OpenServer mapping, c0mpute
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://slic3s.com">slic3s.com</a>: the reference marketplace
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/openobject">OpenObject</Link>: the bucket a slice mounts;{" "}
|
||||
<Link href="/opendisk">OpenDisk</Link>: the same shape for a disk
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/openswarm">OpenSwarm</Link>: the reservation's shape and the payee;{" "}
|
||||
<Link href="/openserver">OpenServer</Link>: the hosting offer a host maps onto
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</SiteShell>
|
||||
);
|
||||
}
|
||||
|
|
@ -88,6 +88,8 @@ export const FAMILIES: Family[] = [
|
|||
s("opengpu", "OpenGPU", "The gpu block: the card by vendor name, count, VRAM, interconnect, access", { parent: "openserver" }),
|
||||
s("openbandwidth", "OpenBandwidth", "The network block: port, meter, overage, IPv4 and IPv6 as a priced resource", { parent: "openserver" }),
|
||||
s("openfile", "OpenFile", "One file a publisher serves about the files it has published: hash, swarm and HTTP routes", { parent: "openserver" }),
|
||||
s("openobject", "OpenObject", "A bucket you can mount: keyed objects encrypted by their owner, kept on paid disks at a stated redundancy, verified, repaired and read back by path", { parent: "openserver" }),
|
||||
s("openslice", "OpenSlice", "A container whose compute is rented from one market and whose disk is mounted from another: the host descriptor, the slice file and the reservation between them", { parent: "openserver" }),
|
||||
s("openmcp", "OpenMCP", "An open catalog of MCP relays: a relay serves /.well-known/openmcp.json and a catalog probes it"),
|
||||
s("opencoupon", "OpenCoupon", "One file a merchant serves about what is on offer right now, expired codes kept so directories learn they died"),
|
||||
s("opensaas", "OpenSaaS", "One file a subscription service serves about the way in and the way out of every plan, for a person and for an agent"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue