mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-02 12:54:03 +00:00
Merge remote-tracking branch 'origin/master' into worktree-open-resource-specs
# Conflicts: # apps/logicsrc-web/src/app/llms.txt/route.ts # apps/logicsrc-web/src/app/sitemap.ts # apps/logicsrc-web/src/components/site-shell.tsx
This commit is contained in:
commit
3e0d795416
8 changed files with 586 additions and 7 deletions
|
|
@ -23,6 +23,7 @@ export function GET(): Response {
|
|||
- [OpenProfile.md](${SITE_URL}/openprofile): One Markdown file that says who you are and where you are, for people and agents alike: identity block, accounts, topics, reshare terms and operator, discovered at /.well-known/openprofile.md or through rel="openprofile".
|
||||
- [OpenMCP](${SITE_URL}/openmcp): An open catalog of MCP relays: a relay serves /.well-known/openmcp.json, a catalog probes it and lists only what it found, and clients reach every relay through the catalog's REST, its own MCP endpoint, or signed webhooks.
|
||||
- [OpenAccess](${SITE_URL}/openaccess): OAuth 2.1 with a grant you can carry: one hub account per person or agent, apps keep their own users and link them once, grants delegate narrower to agents, and a subscription bought in one app is honoured by every app that honours the product. Reference hub at openaccess.logicsrc.com.
|
||||
- [OpenServer](${SITE_URL}/openserver): One file a hosting provider serves about what it sells, at /.well-known/openserver.json: every offer with kind (cloud, vps, dedicated, bare-metal, colocation, on-prem, shared, managed, paas, serverless, storage, gpu, edge, p2p, hybrid), the premises, management, tenancy and model axes, specs, one price, location and stock. Directories read the provider instead of scraping; first reader is nichedb.dev/c/hosting.
|
||||
- [OpenCPU](${SITE_URL}/opencpu): The compute block of an OpenServer offer: threads against cores, the processor by its vendor name, dedicated, shared or burstable allocation, and a range that says what a buyer can add at checkout and for how much.
|
||||
- [OpenMemory](${SITE_URL}/openmemory): The memory block of an OpenServer offer: RAM in mebibytes, DDR generation, ECC as three states, reserved or balloonable allocation, and a range priced per step.
|
||||
- [OpenGPU](${SITE_URL}/opengpu): The gpu block of an OpenServer offer: the card by its vendor name, count and VRAM per device, interconnect, passthrough, MIG, vGPU or shared access, and a range over count.
|
||||
|
|
|
|||
|
|
@ -50,6 +50,26 @@ Ships small fixes to open source projects, nightly.
|
|||
- **Name**: Ada Lovelace
|
||||
- **Profile**: https://ada.example/.well-known/openprofile.md`;
|
||||
|
||||
const MATCH = `## Match
|
||||
|
||||
- **Born**: 1990-05-12
|
||||
- **Gender**: woman
|
||||
- **Orientation**: bisexual
|
||||
- **Status**: single
|
||||
- **Height**: 168 cm
|
||||
- **Children**: none
|
||||
- **Wants children**: open
|
||||
- **Smoking**: never
|
||||
- **Seeking**: everyone
|
||||
- **For**: long-term
|
||||
- **Ages**: 30-45
|
||||
- **Distance**: 50 km
|
||||
- **Not**: smokers, long-distance
|
||||
|
||||
## Photos
|
||||
|
||||
- https://ada.example/photos/garden.jpg`;
|
||||
|
||||
const RULES: Array<[string, string]> = [
|
||||
["One # heading", "It is the name. More than one and the first wins; none and the reader says it has no name."],
|
||||
["The identity block", "The bullet list under the name. Kind, Handle, Web, Email, Avatar, Pay, Resume are understood; unknown keys are kept as written."],
|
||||
|
|
@ -58,7 +78,8 @@ const RULES: Array<[string, string]> = [
|
|||
["Accounts", "One bullet per account and the URL is the identity. The network is derived from the host. An account is a claim until the page links back."],
|
||||
["Topics", "The words you would use to find yourself. Readers lowercase, strip #, and match loosely. No taxonomy at write time."],
|
||||
["Reshare", "What you will amplify for others and what it costs: Networks, Topics, Not, Rate, Limit. No section means no offer."],
|
||||
["Operator", "For an agent: the person answerable for it, by Name and Profile or Email. Chains are followed a few hops and reported."]
|
||||
["Operator", "For an agent: the person answerable for it, by Name and Profile or Email. Chains are followed a few hops and reported."],
|
||||
["Match", "What a dating site or any matching platform needs, about you (Born, Gender, Orientation, Status, Height, Children, Smoking, Religion, ...) and who you seek (Seeking, For, Ages, Distance, Not). Born is required for matching and must give 18 or over; nothing is inferred; a Photos section carries the pictures."]
|
||||
];
|
||||
|
||||
const DISCOVERY: Array<[string, string, string]> = [
|
||||
|
|
@ -71,7 +92,8 @@ const ABSENT: Array<[string, string]> = [
|
|||
["No required fields", "A name and one line of prose is a valid file."],
|
||||
["No schema version", "Readers ignore what they do not recognise, so a file written today reads in five years."],
|
||||
["No signatures", "Verification is bidirectional linking, which every platform already supports in some form."],
|
||||
["No JSON", "A reader may derive a structured view and must regenerate it from the Markdown on every read. The Markdown is the canonical copy."]
|
||||
["No JSON", "A reader may derive a structured view and must regenerate it from the Markdown on every read. The Markdown is the canonical copy."],
|
||||
["No inference", "A Match key is never filled from a photo, a name, a handle or another site. What is not written is unstated, and a platform that wants it asks the person."]
|
||||
];
|
||||
|
||||
export default function OpenProfilePage(): ReactNode {
|
||||
|
|
@ -111,11 +133,12 @@ export default function OpenProfilePage(): ReactNode {
|
|||
</div>
|
||||
<pre style={pre}>{EXAMPLE}</pre>
|
||||
<pre style={pre}>{AGENT}</pre>
|
||||
<pre style={pre}>{MATCH}</pre>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The eight rules</h2>
|
||||
<h2>The nine rules</h2>
|
||||
<p>Every one of them degrades rather than fails.</p>
|
||||
</div>
|
||||
<table style={table}>
|
||||
|
|
|
|||
274
apps/logicsrc-web/src/app/openserver/page.tsx
Normal file
274
apps/logicsrc-web/src/app/openserver/page.tsx
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
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: "OpenServer · LogicSRC",
|
||||
description:
|
||||
"OpenServer is one file a hosting provider serves about what it sells: every server, instance, rack, function and peer-market listing, with specs, price, location and stock, at /.well-known/openserver.json. Cloud, VPS, dedicated, bare metal, colocation, on-prem, managed, unmanaged, PaaS, serverless, storage, GPU, edge and p2p.",
|
||||
alternates: { canonical: "/openserver" }
|
||||
};
|
||||
|
||||
const DESCRIPTOR = `{
|
||||
"provider": {
|
||||
"name": "Northwind Hosting",
|
||||
"web": "https://northwind.example",
|
||||
"operator": "https://northwind.example/.well-known/openprofile.md",
|
||||
"country": "NL",
|
||||
"status": "https://status.northwind.example"
|
||||
},
|
||||
"updated": "2026-09-13T06:00:00Z",
|
||||
"offers": [
|
||||
{
|
||||
"id": "vps-arm-4",
|
||||
"name": "ARM 4",
|
||||
"url": "https://northwind.example/vps/arm-4",
|
||||
"kind": "vps",
|
||||
"premises": "off-prem",
|
||||
"management": "unmanaged",
|
||||
"tenancy": "shared",
|
||||
"model": "centralized",
|
||||
"location": { "regions": ["ams1", "fra1"], "countries": ["NL", "DE"] },
|
||||
"compute": { "vcpu": 4, "ram_mb": 8192, "arch": "arm64" },
|
||||
"storage": [{ "type": "nvme", "size_gb": 80 }],
|
||||
"network": { "bandwidth_mbps": 1000, "transfer_gb": 4000, "ipv4": 1, "ipv6": true },
|
||||
"price": { "amount": 7.5, "currency": "EUR", "interval": "month" },
|
||||
"stock": "in_stock"
|
||||
}
|
||||
]
|
||||
}`;
|
||||
|
||||
const MINIMAL = `{ "provider": { "name": "Northwind Hosting" }, "offers": [{ "name": "ARM 4" }] }`;
|
||||
|
||||
const KINDS: Array<[string, string]> = [
|
||||
["cloud", "a virtual machine on a cloud platform, billed by the hour or the second, with an API"],
|
||||
["vps", "a virtual private server, billed by the month"],
|
||||
["dedicated", "a whole physical server rented from the provider's rack"],
|
||||
["bare-metal", "a whole physical server with cloud-style provisioning and hourly billing"],
|
||||
["colocation", "rack space, power and network for a server the buyer owns"],
|
||||
["on-prem", "hardware or an appliance sold or leased to run on the buyer's premises"],
|
||||
["shared", "a slice of a server the provider administers, typically web hosting with a control panel"],
|
||||
["managed", "a server the provider runs for the buyer, sold as the service rather than the box"],
|
||||
["paas", "a platform that takes code and runs it, with no server the buyer sees"],
|
||||
["serverless", "functions or containers billed by invocation or by the second of use"],
|
||||
["storage", "object, block or file storage sold on its own"],
|
||||
["gpu", "compute sold for the accelerator, whatever runs beside it"],
|
||||
["edge", "compute placed near users at many small points of presence"],
|
||||
["p2p", "a listing on a decentralised marketplace where the seller is a peer, not the operator"],
|
||||
["hybrid", "a bundle that spans premises, such as an appliance with a cloud control plane"]
|
||||
];
|
||||
|
||||
const AXES: Array<[string, string, string]> = [
|
||||
["premises", "on-prem, off-prem, hybrid", "where the hardware physically is"],
|
||||
["management", "managed, unmanaged, co-managed", "who administers the operating system and what runs on it"],
|
||||
["tenancy", "shared, dedicated", "whether the hardware is shared with other customers"],
|
||||
["model", "centralized, p2p", "whether one operator runs the hardware, or peers do"]
|
||||
];
|
||||
|
||||
const DIRECTORY: Array<[string, string]> = [
|
||||
["Fetch daily at least", "Offers change price and stock. A descriptor read once is a snapshot, not a catalog. The descriptor's updated says whether the rest can be skipped."],
|
||||
["Dedupe on origin + id", "A re-read updates the row and never adds a second. An offer that leaves the file is marked gone, not deleted."],
|
||||
["Keep the provider's words", "The name, the region names, the extra keys. Normalise for search, display what the provider wrote."],
|
||||
["Attribute the provider", "Every offer links to its url, and the directory says where the file came from and when it was read."],
|
||||
["Report absence as absence", "An unstated stock is unknown, not in stock. An unstated axis is unstated."]
|
||||
];
|
||||
|
||||
const ABSENT: Array<[string, string]> = [
|
||||
["No ordering", "The file says what is for sale, not how to buy it. Every provider has an order form or a provisioning API, and url on each offer leads to it."],
|
||||
["No reviews, no trust score", "verified means the file came from the provider's own origin. Whether a provider is good is the reader's judgement."],
|
||||
["No benchmarks", "A descriptor says what an offer is specified as, in the provider's words. What it measures at is another document's business."],
|
||||
["No central registry", "Anyone may read any provider's file. A directory is one reader among many, and two directories reading the same file list the same offers."]
|
||||
];
|
||||
|
||||
export default function OpenServerPage(): ReactNode {
|
||||
return (
|
||||
<SiteShell active="OpenServer">
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<p className="eyebrow">LogicSRC standards surface</p>
|
||||
<h2>OpenServer</h2>
|
||||
<p>
|
||||
One file a hosting provider serves about what it sells. A directory reads the
|
||||
provider instead of scraping a page, and the provider stays the author of its own
|
||||
catalog.
|
||||
</p>
|
||||
</div>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
Every provider publishes its catalog as a web page, every comparison site scrapes those
|
||||
pages, and the comparison site's terms then forbid anyone from scraping the scrape.
|
||||
The provider, who wanted its offers seen, has no say in how they appear. A buyer's
|
||||
agent that wants a 4 vCPU ARM box in Europe under 10 a month, in stock, reads twenty
|
||||
pricing pages twenty different ways. OpenServer puts the table the order form already
|
||||
reads at <code style={mono}>/.well-known/openserver.json</code>, in one shape every
|
||||
reader agrees on, so an offer can be found instead of scraped.
|
||||
</p>
|
||||
<p style={{ color: "#5b6b7a" }}>
|
||||
Status: 0.1. It covers cloud, VPS, dedicated and bare-metal servers, colocation,
|
||||
hardware for your own premises, shared and managed hosting, platforms, functions,
|
||||
storage, GPU, edge and peer-to-peer markets. The first directory reading it is the hosting
|
||||
collection at <a href="https://nichedb.dev/c/hosting">nichedb.dev</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The descriptor</h2>
|
||||
<p>
|
||||
Served at <code style={mono}>/.well-known/openserver.json</code>. Only{" "}
|
||||
<code style={mono}>provider.name</code> and each offer's{" "}
|
||||
<code style={mono}>name</code> are required.
|
||||
</p>
|
||||
</div>
|
||||
<pre style={pre}>{DESCRIPTOR}</pre>
|
||||
<p style={{ color: "#41505d" }}>
|
||||
<code style={mono}>id</code> is the dedupe key: the same origin and id tomorrow is the
|
||||
same row. <code style={mono}>compute</code>, <code style={mono}>storage</code> and{" "}
|
||||
<code style={mono}>network</code> use fixed units, mebibytes for memory, gigabytes for
|
||||
disks, megabits for bandwidth. <code style={mono}>price</code> is one amount, an ISO
|
||||
currency and an interval of hour, month, year or once. <code style={mono}>stock</code> is
|
||||
in_stock, out_of_stock, preorder or unknown. <code style={mono}>operator</code> is the
|
||||
person answerable, as an <Link href="/openprofile">OpenProfile.md</Link>. Unknown keys are
|
||||
kept. The smallest valid file is one line:
|
||||
</p>
|
||||
<pre style={pre}>{MINIMAL}</pre>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>Fifteen kinds, four axes</h2>
|
||||
<p>
|
||||
<code style={mono}>kind</code> says what is sold. The axes cut across every kind and are
|
||||
stated, not inferred, because a managed VPS and an unmanaged one are the same kind and
|
||||
different offers.
|
||||
</p>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={th}>kind</th>
|
||||
<th style={th}>what is sold</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{KINDS.map(([kind, what]) => (
|
||||
<tr key={kind}>
|
||||
<td style={td}>
|
||||
<code style={mono}>{kind}</code>
|
||||
</td>
|
||||
<td style={td}>{what}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<table style={{ ...table, marginTop: "1rem" }}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={th}>axis</th>
|
||||
<th style={th}>values</th>
|
||||
<th style={th}>meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{AXES.map(([axis, values, meaning]) => (
|
||||
<tr key={axis}>
|
||||
<td style={td}>
|
||||
<code style={mono}>{axis}</code>
|
||||
</td>
|
||||
<td style={td}>
|
||||
<code style={mono}>{values}</code>
|
||||
</td>
|
||||
<td style={td}>{meaning}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<p style={{ color: "#41505d", marginTop: "1rem" }}>
|
||||
A peer-to-peer marketplace such as Akash, Flux, Golem, Salad or Vast.ai publishes one
|
||||
descriptor whose offers are the market's current asks, one per listing with{" "}
|
||||
<code style={mono}>kind: p2p</code> and <code style={mono}>model: p2p</code>, stock and
|
||||
price updated as often as the market moves, and <code style={mono}>operator</code>{" "}
|
||||
pointing at the marketplace, not the peer. In this family,{" "}
|
||||
<a href="https://github.com/profullstack/logicsrc/blob/master/docs/openswarm/c0mpute.md">c0mpute</a>{" "}
|
||||
is the compute marketplace, <Link href="/docs/opendisk">OpenDisk</Link> the disk-for-rent
|
||||
peer, listable as an offer with <code style={mono}>kind: storage</code>, and{" "}
|
||||
<Link href="/openswarm">OpenSwarm</Link> the settlement and proof layer under both.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>What a directory owes a provider</h2>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<tbody>
|
||||
{DIRECTORY.map(([what, how]) => (
|
||||
<tr key={what}>
|
||||
<td style={td}>
|
||||
<strong>{what}</strong>
|
||||
</td>
|
||||
<td style={td}>{how}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<p style={{ color: "#41505d", marginTop: "1rem" }}>
|
||||
A descriptor is verified when it was fetched from the provider's own origin. Found
|
||||
through <code style={mono}>rel="openserver"</code> or a URL handed to the
|
||||
reader on some other host, it is a claim about the provider by whoever hosts it, and a
|
||||
directory marks it so.
|
||||
</p>
|
||||
</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/openserver">Specification</Link>: the descriptor, fifteen kinds, four
|
||||
axes, peer-to-peer markets, discovery, what a directory owes a provider
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://nichedb.dev/c/hosting">nichedb.dev/c/hosting</a>: the first directory
|
||||
reading it, with providers and offers as feeds over RSS, JSON, an API and MCP
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.findhost.app">findhost.app</a>: a curated register of web hosts under
|
||||
CC BY 4.0, the sibling from the other direction
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/openprofile">OpenProfile.md</Link>, the operator behind a provider;{" "}
|
||||
<Link href="/openmcp">OpenMCP</Link>, how a directory describes its own MCP door
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/docs/opencpu">OpenCPU</Link>, <Link href="/docs/openmemory">OpenMemory</Link>,{" "}
|
||||
<Link href="/docs/opengpu">OpenGPU</Link> and{" "}
|
||||
<Link href="/docs/openbandwidth">OpenBandwidth</Link>: the resource blocks an offer's{" "}
|
||||
<code style={mono}>compute</code>, <code style={mono}>compute.gpu</code> and{" "}
|
||||
<code style={mono}>network</code> may carry, each also an offer on its own
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</SiteShell>
|
||||
);
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ const STATIC_ROUTES: Array<{
|
|||
{ path: "/openprofile", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/openmcp", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/openaccess", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/openserver", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/opencpu", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/openmemory", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/opengpu", changeFrequency: "weekly", priority: 0.9 },
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ const NAV: Array<{ href: string; label: string; external?: boolean }> = [
|
|||
{ href: "/openprofile", label: "OpenProfile" },
|
||||
{ href: "/openmcp", label: "OpenMCP" },
|
||||
{ href: "/openaccess", label: "OpenAccess" },
|
||||
{ href: "/openserver", label: "OpenServer" },
|
||||
{ href: "/opencpu", label: "OpenCPU" },
|
||||
{ href: "/openmemory", label: "OpenMemory" },
|
||||
{ href: "/opengpu", label: "OpenGPU" },
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ export const DOC_SLUGS = [
|
|||
"openprofile",
|
||||
"openmcp",
|
||||
"openaccess",
|
||||
"openserver",
|
||||
"openstream",
|
||||
"opencpu",
|
||||
"openmemory",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue