Commit graph

225 commits

Author SHA1 Message Date
61870aa481
seo: give every page its own social title, not the homepage's (#203)
Reddit, Slack, X and Facebook read og:title, and every page of
logicsrc.com was serving the homepage's. The <title> tag was correct per
page, which is why it went unnoticed: Next.js shallow-merges metadata, so
a page exporting only `{ title, description, alternates }` inherits the
root layout's `openGraph` object whole. og:title, og:description and
og:url were the homepage's on all 45 spec landing pages, every doc, every
report and every SPA section.

Blog posts were the one route that declared openGraph, and they proved
the mechanism: their og:title is right. They also showed the other half
of it -- declaring openGraph drops the file-convention opengraph-image,
so live posts shipped with no og:image at all, and their twitter:title
was still the homepage's.

- src/lib/page-meta.ts: one builder, three entry points. specMetadata
  titles a spec landing page from its lib/specs.ts entry, pageMetadata
  titles the site's own pages from PAGE_META, contentMetadata titles a
  doc, post, skill or ontology record from its content. All three always
  emit openGraph and twitter title, description, url and image.
- Spec titles come from the registry, so they cannot drift from the way
  the sidebar, /specs and the home page describe the same spec, and a new
  spec page is titled the moment its registry entry exists. composeTitle
  trims a long subject line at a clause boundary to fit a link preview.
- Doc pages carry that subject line too, because every spec's H1 is just
  its name: "OpenStream" alone was the whole title.
- docExcerpt joins the wrapped lines of the first real paragraph and
  skips Status:/Slug: headers and list lead-ins, so descriptions stopped
  being "Status: 0.1 draft" and "Core tables:".
- contract/page-metadata.contract.test.ts fails if a sitemap route has no
  title, if a spec page has no registry entry, if two pages share a
  title, if a page declares metadata without the builder, or if a page
  loses its social image.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-24 01:00:25 -07:00
baa3adf716
OpenIcon gallery: the HQ style for all 370 icons (#202)
openicon.json with the hq block, 259 full-colour UI icons as WebP 64/128
and 111 brand SVGs in their owners' colours. The gallery's Simple/HQ
toggle appears on its own now that icons carry hq.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 23:31:22 -07:00
0b3a7188de
OpenEmoji catalog: 2,424 drawn glyphs, and browse/install by network (#201)
* OpenEmoji catalog: browse and install by network

Reads platforms.json from the set: a network picker grouped by kind
(custom emoji, sticker packs, images to post), and for the chosen
network its verified limits, install steps, packs with sizes, Show (in
the grid) and Download (release assets), the grid narrowed to what its
bundles hold with each emoji's name on that network, and the detail
panel saying which pack holds it. A network that names what it is for
opens on it: X opens on country flags.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* OpenEmoji catalog: previews for 2,424 drawn glyphs

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 23:05:15 -07:00
f2e4dd1ea9
OpenIcon: the optional HQ style (rules 9-11) (#200)
A set may add a full-colour HQ style beside the canonical simple one:
styles: [simple, hq], a top-level hq block (sizes, webp_sizes, provenance,
coverage) and an hq block per icon (png, webp, svg for brands, made_by,
hex, hex_source). Same silhouette as simple, falls back to simple, brand
colour must be the owner's with its source, provenance is per style.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:48:32 -07:00
3e8d3098ba
OpenIcon gallery: all 370 icons on /openicon, with search, filters and terminal glyphs (#199)
Replaces the 47-icon sample with the whole reference set: search by name,
alias or keyword; category chips with counts; UI/brand filter; SVG,
Nerd Font, Unicode or ASCII view (the Nerd Font view uses the official
symbols subset to the set's 349 glyphs, 38 KB woff2, MIT); size and
colour; a detail panel with all three glyphs and codepoints, trademark
notes, copy SVG / <img> / icon("key"), and downloads. Ready for the
optional HQ (full-colour) style: a Simple/HQ toggle appears once icons
carry an hq field. Filters live in the URL.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:43:12 -07:00
3883ee7a2c
OpenIcon 0.1: an icon set as a folder, with terminal glyphs (#198)
One openicon.json naming every icon (kebab-case keys, unique aliases,
shared keywords), 24x24 currentColor SVGs with a stated grid, and three
terminal glyphs per icon: a Nerd Font character with its codepoint and
glyph name, a Unicode symbol and a 1-4 character ASCII spelling, picked
nerd > unicode > ascii. Brand logos carry brand: true, a trademark note,
source and licence. made_by + W3C AI disclosure per set and per icon.
Mapping from Lucide, Tabler, Font Awesome, Nerd Fonts and Simple Icons.
Landing page shows 47 icons from the reference set (profullstack/openicon).

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 22:27:15 -07:00
f80488ce92
OpenEmoji catalog: every emoji in the reference set, with search and filters (#197)
* OpenEmoji catalog: every emoji in the reference set, with search and filters

/openemoji/catalog reads the set's openemoji.json (every Unicode emoji,
drawn or not) and filters by name and CLDR keyword, group, subgroup,
skin tone (keyboard-style swap), Emoji version and status, with sort,
tile size, URL-synced filters, paged rendering and a detail panel
(codepoints, tone family, copy, PNG/SVG downloads, keyword chips).
Spec: an entry without files is listed, not drawn.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* OpenEmoji catalog: reference set previews, first 206 glyphs

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 21:27:40 -07:00
6d1bcd0e05
OpenEmoji 0.1: an emoji set as a folder (#196)
One openemoji.json that states coverage against a Unicode version, the
licence, and who or what drew the set (made_by plus the W3C AI disclosure
vocabulary), and glyphs named by fully-qualified codepoint sequence.
Custom emoji get x- keys with shortcodes; skin tones name their base;
rendered emoji keep the character as alt. Mapping from Mastodon, Slack,
Discord and CLDR.

Landing page shows 19 glyphs drawn by the reference implementation,
`emoji` in profullstack/cli-tools.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 21:08:15 -07:00
3d155af970
vault + teams: filter secrets by category, export to CSV, simpler help (#195)
Every secret now has a category derived from its name (db, social, server,
api, cloud, finance, crypto, ai, email, messaging, storage, dns, analytics,
devtools, auth, config, other). One rule table in @logicsrc/opencreds serves
both vaults; services win over generic words, so STRIPE_WEBHOOK_SECRET is
finance, not auth. Checked against the 1,208 distinct key names in the
profullstack team: 74 fall to "other".

Team vaults (where the shared .env secrets live):
- teams categories [team]    the filter words, with per-category counts
- teams secrets <team> [project] [env] --category/-c --search/-s
                             names + categories, never decrypts; --format csv
- teams export  <team> [project] [env] --category -o file.csv [--yes]
                             decrypts into team,project,env,category,key,
                             value,updated_at (0600); skips vaults without a
                             grant and names them

Personal vault (OpenCreds):
- vault list --category, and the category column in list output
- vault export --format csv: one flat row per item, keeps key/account
  secrets that a Bitwarden CSV drops; --category on every export format

DX:
- examples in `logicsrc vault help` / -h / --help that start by saying which
  of the two vaults you want, plus examples on teams and each subcommand
- password prompts go to stderr, so eval "$(logicsrc vault unlock)" works
- hints name the command you actually ran (logicsrc vault init, not
  opencreds init)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 21:08:08 -07:00
156c9164a9
Add OpenSong spec: a song as plain-text blocks a generator takes (#194)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
TITLE / STYLE / EXCLUDE STYLES / LYRICS label blocks with [Section - direction]
tags, no Markdown (Suno reads plain text only). Kept beside the audio as the
same name with .txt, album lyrics.txt with ==== dividers, one-way mapping to
ID3/Vorbis tags. Example is track 002 of Þrøngva, When the Ravens Lied.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 17:33:18 -07:00
50eaf30beb
Honour Profullstack Power Keys: x402-gateway 0.7.0 (#193)
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
A Power Key bought once at profullstack.com/shop now opens this site:
the gateway verifies it offline with @profullstack/keys and treats it
as a pass, so it is never charged as a crawler or metered. The 402
body and the sales page point at the shop.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 02:58:10 -07:00
c7cecb2955
feat(specs): OpenObject and OpenSlice 0.1 (#192)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
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>
2026-09-21 03:05:38 -07:00
8e4ea2f997
docs: OpenStack.md 0.1, one Markdown file for what a project is built on (#191)
A new LogicSRC spec in the catalogs family. One heading, an identity block
(Kind, Web, Repo, Operator, License, Extends, Updated), one line, then eleven
layers: Languages, Runtimes, Interfaces (one ### per way in: web, api, cli,
tui, mcp, desktop, mobile, worker, extension, bot), Data, Services, Modules,
Tooling, Hosting, Auth, Conventions, Not. An item is one bullet: name,
version, an optional status word (trial, hold, leaving) and a role. Extends
inherits a parent file, sections replace, Conventions and Not accumulate.
Rule 8 is the reading rule for agents: use what is listed, prefer listed
over new, ask before adding a layer or a service, never add a Not, keep the
file true. Discovery at OpenStack.md in the repo, /.well-known/openstack.md,
rel=openstack, or a platform path. JSON is derived and never the source.

logicsrc.com serves its own at /.well-known/openstack.md: the route extracts
the worked example from docs/openstack.md, and a contract test holds the two
together and checks the file follows its own rules. rel=openstack in <head>
and in the Link header beside openprofile.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 02:21:12 -07:00
08490aecf3 fix(web): scope sidebar navigation styles away from breadcrumbs
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
2026-09-13 16:02:00 +00:00
60ffe1051a fix(web): keep expanded skills navigation inside mobile viewport 2026-09-13 15:57:39 +00:00
25e18f0766 Add OpenSkill descriptions for human capabilities and OpenProfile discovery 2026-09-13 15:47:58 +00:00
ba69f58243
OpenWebring and OpenWiki carry the whole AI Content Disclosure vocabulary (#190)
The W3C AI Content Disclosure community group defines four attributes,
not one: ai-disclosure, ai-model, ai-provider and ai-prompt-url. Both
specs carried only the first, as `disclosure`. They now carry all four,
as `disclosure`, `ai_model`, `ai_provider` and `ai_prompt_url`: which
model, whose, and a page describing how it is used, optional and
meaningful only beside a disclosure other than none. `mixed`, the value
the group's meta tag form allows, is accepted at the site level in
OpenWebring and the page level in OpenWiki.

A ring host copies all of them into the member entry as the member said
them. A wiki carries them on the page and per revision, and a host
rendering a page puts the same four on it as the group's meta tag and
attributes. Both specs are 0.1.1; the wire version stays 0.1, since every
field is additive and absent is still unstated.


Claude-Session: https://claude.ai/code/session_01XYae2mH3khdwiXUVzcVMDw

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 13:14:05 +00:00
0395ff12ce
Publish the OpenWiki specification: a wiki that is a folder of Markdown files (#189)
OpenWiki writes down what the [[Page]] convention already is in practice,
so a wiki can be moved, mirrored, read by a directory and edited by an
agent without reading any engine's source. One Markdown file per page
with a small optional front matter (title, aliases, tags, summary,
author, made_by, disclosure, created, updated, license, lang, redirect);
wikilinks resolved by exact name, loose name, alias, path, then wanted;
one address with three representations (rendered, .md, .md?rev=) and a
history.json per page; a descriptor at /.well-known/openwiki.json with
pages_url, changes (Atom), repo, edit, editors and accepts; editing as
PUT of the same file with If-Match on the revision; discovery; what a
directory owes a wiki. Every revision says who made it: human, ai or
both, the same word OpenWebring uses.

A folder that follows it opens unchanged in Obsidian and Logseq, and any
such folder becomes an OpenWiki by adding the two files. The first host,
goviral.wiki, is being built on it.


Claude-Session: https://claude.ai/code/session_01XYae2mH3khdwiXUVzcVMDw

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 13:00:20 +00:00
f389edb6f8
Publish OpenAgent profile specification and discovery (#188) 2026-09-13 05:37:59 -07:00
fd25e8e4ba
docs: OpenStream benchmark report for nixamp 0.24.2 (#184)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
Manual publish of the report attached to the nixamp v0.24.2 release
(openstream-report-0.24.2.json/.md). The release workflow's
publish-report job skipped because LOGICSRC_PUBLISH_TOKEN is not set
on profullstack/nixamp. Built-in synthetic corpus, so the id carries
the -synthetic label per docs/openstream/reports/README.md.


Claude-Session: https://claude.ai/code/session_015uheT4Gn9BBKAnSZGcabyN

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 05:16:24 -07:00
dfbf5a4bc4
docs: OpenL10n and OpenI18n, the words half and the languages half of OpenFile (#187)
OpenL10n is the record of what a file says, in any language: one
transcript per media per language, addressed by the OpenFile id (or a
url: or live: identity for what has no bytes), lines as seconds into the
media, a translation kept beside the original and marked with what it
came from, complete or heard in pieces, made once on request with 202
progress, served as JSON, SRT, VTT or text.

OpenI18n is one file a service serves at /.well-known/openi18n.json
about the languages it speaks: which, which it can turn into which, how
to ask for one, and where texts are translated, with limits, models and
the pivot said out loud.

Both are what nixamp 0.24 and 0.25 serve today, written down so anything
that hears or translates can keep the same record.


Claude-Session: https://claude.ai/code/session_015KAKuRngFbQg3kET6RS5yN

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 04:39:59 -07:00
a47dc62fec
OpenWebring: nichedb.dev/c/webrings is the first directory reading rings (#186)
The spec and its landing page now name the directory that reads every
OpenWebring host: one row per ring and one per member, with made_by as
the member said it and the status the host last verified, re-read hourly.
The first host line also names rssamplifier's curated Profullstack ring.


Claude-Session: https://claude.ai/code/session_01XYae2mH3khdwiXUVzcVMDw

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 11:11:55 +00:00
9ae7ad8962
OpenFleet reference implementation: @logicsrc/openfleet, logicsrc fleet, and Claude Code hooks (#185)
* OpenFleet reference implementation: @logicsrc/openfleet 0.1.0 and logicsrc fleet

Ship what docs/openfleet.md describes. The new workspace package holds the
record (write once, never overwrite, 0600), the ledger (append-only JSON
Lines, merged across ledger*.jsonl by at), the ceiling rules (whole fleet
ceiling, narrowed swarm keys, a merge that never widens, refusals by key),
claiming and deriving exactly as the spec's "Claiming and deriving" and
rule 13, and fold(), which turns any $OPENFLEET_HOME plus the engine
rosters into the tree the landing page shows.

logicsrc fleet open|cap|tree|stop|log are the sysop's verbs, every one with
--json. open and cap exit 4 when OPENFLEET_MEMBER is set; stop exits 4
outside the caller's subtree, ends nested swarms first, goes through each
member's own engine (claude stop, moshcode herd kill, tmux kill-pane, a
signal for claude-p) and writes one swarm.end per swarm. tree reads claude
agents --json --all and ~/.moshcode/herd/sessions.json when it can, draws
recordless sessions as roster roots of the implicit fleet, and writes
member.end lost for a recorded member its engine no longer lists.

Claude Code takes part through hooks: logicsrc fleet hooks install merges
SessionStart, UserPromptSubmit, PreToolUse, Stop and SessionEnd into
~/.claude/settings.json without clobbering it, and logicsrc fleet hook
<Event> runs each one. SessionStart claims, derives or writes a root record
and hands the member its variables through CLAUDE_ENV_FILE; UserPromptSubmit
checks the ceiling with the permission mode the engine reports and writes
member.start, or refuses the first prompt with exit 2 and ceiling.refuse;
PreToolUse denies an edit outside piece.owns; Stop and SessionEnd write
member.end. A hand-started root takes the engine's reported approvals
before member.start, since the command line only guesses them. Hooks
never fail the engine: everything is caught and logged to hooks.log.

The spec and the landing page now say what ships, keep Status 0.1, and
record the two verified Claude Code limits: a background job dispatched from
claude agents gets no launcher environment, and OPENFLEET_* exported at
SessionStart reach the member's tools but not later hooks, so hooks key on
session_id through $OPENFLEET_HOME/sessions/<session_id>.json. PRD 0008
covers the work. CLI 0.2.1 -> 0.3.0; build and build:cli chains build the
package before the CLI; README and docs/cli.md list the group.

Tests: 95 in the package (record, ledger merge, every narrower case, the
worked example's claim and derive, the folded tree, hook install
idempotence, each hook handler including the exit-2 refusal and the
PreToolUse deny, every verb with fake deps) and 4 in the CLI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV

* OpenFleet fix round: rebuild the ceiling from the ledger, once-markers, rule 6 in tree, lost only for what a roster can hold

The review of the reference implementation against moshcode found the two
readers disagreeing on the same files. This round applies the shared
rulings so both sides read a ledger the same way.

Ceiling (R-A, R-B, R-C, R1, R6, R10, R15, R17): memberCeiling rebuilds the
effective ceiling from the ledger on every read. The latest fleet-target
fleet.cap (else fleet.open, else the implicit fleet's) replaces the copy in
a record, so a sysop's widening cap reaches running members; then each
swarm.spawn narrowing down the path, then swarm caps last. In the implicit
fleet a parentless record's own approvals enters at the root; a ceiling a
writer left without the key is never read as native, and startMember fills
it with the engine's word while the record is unclaimed. A fleet.open or
cap with no hosts means the host it was written on (R23).

Once-markers (R-G, R28): member.start, member.end and swarm.end each take
an exclusive create under fleets/<fleet>/marks/<event>.<id> before the
append; a lost end takes <id>.lost so a real end can still supersede it.
The hooks let a real end follow a lost line (R9).

tree (R-F, R20): run by the sysop it enforces rule 6, stopping a member
past its effective until with state timeout and the members of a swarm or
fleet at its budget with state budget, then writes swarm.end for each swarm
touched once it is complete. An agent's tree stops nothing. lost is written
only for a member its engine's roster can hold: a claude-code background job
(8-hex member or session) or a moshcode pane, never an interactive session
claude agents does not list (R-E, R3, R14). A nested swarm is drawn under
the member that spawned it and its row shows the effective ceiling (R25).

stop and cap (R-D, R-H, R22, R27): swarm.end is written only once every
member and every nested swarm has an end line that counts; an engine that
will not end a member leaves it without an end line and the verb exits
non-zero. claude stop takes the job id: the member of a background job,
else the first eight characters of a session UUID; an interactive session
with no job id cannot be stopped and the tool says so. cap on a swarm
refuses a key that would widen. A derived claude-code job is named by its
job id and carries no pid.

Also: R-I (endMember ends only the engine-minted swarm of one), R35 (a
derived record's guessed approvals corrected at UserPromptSubmit), R32
(the UserPromptSubmit hook passes only exit 2 through), R31 (package
README), R36 (rule 13 says the launcher test is unimplemented in 0.1),
docs and PRD 0008 updated for lost, rule 6 and the markers. 113 openfleet
tests, 93 CLI tests, contract green.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV

* openfleet hooks: no member.end for a member that never started

A first prompt refused by the ceiling still lets the session wind down through Stop and SessionEnd; those handlers now write nothing when the ledger holds no member.start for the member, so a refused member is never drawn as done.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV

* logicsrc-mcp test: the next free PRD id is 0009 now that PRD 0008 exists

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 10:58:55 +00:00
519d13c3d6
Merge pull request #183 from profullstack/feat/logicsrc-agent-pricing
Clarify implementation billing as $400 per agent-hour
2026-09-13 02:57:58 -07:00
b27b52fc06
Merge pull request #181 from profullstack/docs/openserver-reference
Promote OpenServer and label NicheDB as its reference implementation
2026-09-13 02:45:00 -07:00
a0148a34e4 Match browser pricing assertion to agent-hour units 2026-09-13 09:44:57 +00:00
d4ee3aa4dc
logicsrc.com joins the Profullstack ring (#182)
The footer carries the three OpenWebring links (previous, ring, random,
next, with ?from=https://logicsrc.com/blog, the member URL the directory
holds), and /.well-known/openwebring.json says who makes the blog: both,
ai-generated, in the W3C AI Content Disclosure vocabulary the spec adopts.


Claude-Session: https://claude.ai/code/session_01XYae2mH3khdwiXUVzcVMDw

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 09:43:25 +00:00
b5d1990c95 Lead with OpenServer and link its NicheDB reference implementation 2026-09-13 09:37:27 +00:00
f001abb539 Check agent-hour units in checkout validation 2026-09-13 09:35:14 +00:00
5727ac8d06 Clarify public implementation pricing per agent-hour 2026-09-13 09:30:24 +00:00
d8b3126782
Add OpenABTest draft experiment and accounting contracts (#180) 2026-09-13 02:17:35 -07:00
123ba2e39a Merge remote-tracking branch 'origin/master' into openfleet
# Conflicts:
#	apps/logicsrc-web/src/lib/specs.ts
2026-09-13 08:48:44 +00:00
b2c23f724b spec-discovery test: accept a landing-page link in llms.txt, still require the docs URL
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV
2026-09-13 08:46:08 +00:00
68f3151699 Merge master; OpenFleet keeps its name, PR 177's rental descriptor becomes OpenRental
PR 177 shipped a second OpenFleet under the same slug: a published listing of OpenAgent profiles and ipfile swarms with CoinPay rental offers. Anthony ruled that OpenFleet means the human-controlled fleet and the record of who spawned whom, so the rental contract is renamed OpenRental (slug openrental, catalogs family, group noun listing): docs/openrental.md, logicsrc-openrental.schema.json with type logicsrc.openrental and scope kind listing, fixtures/openrental, createOpenRental and OpenRental* types in the SDK, the openrental validator kind. Minor bumps because an export moved: @logicsrc/schemas 0.2.0, @logicsrc/validators 0.2.0, @logicsrc/sdk 0.2.0. The discovery contract test now covers openfleet, openrental and openwall, one per family, and accepts a landing-page link in llms.txt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV
2026-09-13 08:45:33 +00:00
1618ecac7e
OpenWebring: a webring that says who made it (#178)
One file a ring serves about its members, one file a member may serve
about itself, plain links between them, and a made_by declaration on
every member (human, ai, both) so a reader can follow the human web or
the machine web on purpose. Six hop rules that accept every addressing
shape rings already use (?from=, ?host=, ?via=, ?url=, a slug in the
path, the bare Referer), so a member of any existing ring joins with no
change; verification the IndieWeb way (mark inactive, never delete); an
OPML twin of every ring; no script, no tracking, no central registry.

Name: OpenRing is Drew DeVault's tool in this exact niche and every
openring domain is taken; OpenWebring has only a dead 2020 predecessor
and free domains. Registered in the catalogs family.

First host: rssamplifier.com/ring (one ring per topic), in flight.


Claude-Session: https://claude.ai/code/session_01XYae2mH3khdwiXUVzcVMDw

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 01:27:27 -07:00
bc489ddd74 OpenFleet: agents under a human, the record of who spawned whom, and the ledger the sysop reads
A new spec at /openfleet and /docs/openfleet replacing the AgentSwarm placeholder. A fleet is every agent session one human answers for; a swarm is the members one spawner starts inside it for one task. One record per session (claimed by the first session that writes its member.start, derived when inherited), one append-only ledger per fleet per host with eight events, five sysop verbs, fifteen rules, and what Claude Code and moshcode would each add. Written from job 172ffd83, which had to reconstruct its own parentage by hand.

openswarm keeps its slug (it is the peer-to-peer media family) and gains a one-line pointer. /agent-swarm redirects permanently to /openfleet; the registry entry, home band, catch-all route and scroll hook for the placeholder are replaced or removed. Contract test covers the redirect.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01RZV4zJ2pDZLNN3kE5jFCmV
2026-09-13 08:15:03 +00:00
45c7629953
Ship OpenFleet contracts and the OpenWall draft proposal (#177)
* feat: add OpenFleet membership and CoinPay rental contracts

* Propose OpenWall broadcasts and direct messaging contracts

* release: prepare OpenFleet and OpenWall public contracts

* fix: use tested npm for compatible CLI installs
2026-09-13 00:57:45 -07:00
a333726a1e
OpenSite: one record about a page or a site, the card a reader would draw (#175)
Every consumer of a link reads a page's card tags its own way, caches the
first reading for days, and publishes nothing. OpenSite writes the reading
down: a record per URL (title, description, image, kind, canonical, author,
feeds, the card tags verbatim, JSON-LD as parsed), a descriptor a site
serves at /.well-known/opensite.json, the order a reader takes each field
from a page, the four calls an index offers, and a table of what each
consumer reads and caches.

docs/opensite.md, one entry in the specs registry (catalogs family), and a
landing page at /opensite. The first index is nichedb.dev/c/sites; the
first publisher is nixamp's share links.


Claude-Session: https://claude.ai/code/session_01MwAoNvWzezmBHeT7oDHo3C

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 22:30:41 -07:00
1d1e84c6f3
OpenSaaS 0.1: one file a subscription service serves about the way in and the way out (#176)
Subscribing takes one click and cancelling takes a support ticket, and no
reader can check that the two are as easy as each other because the way
out is not written down anywhere a reader can fetch. The service already
has a plan table, a cancel endpoint and a refund rule. OpenSaaS is those
at /.well-known/opensaas.json: plans, and eight actions (subscribe,
cancel, pause, resume, change_plan, unsubscribe, export, delete), each
as the page a person opens and the endpoint an agent calls with an
OpenAccess scope, with steps and confirm as the exit measure a directory
shows beside the entrance. Doc, landing page, registry entry under
catalogs. nichedb.dev is named as the first directory and the first
service.


Claude-Session: https://claude.ai/code/session_01S7yeJUHGxA4P5N74xnsRPQ

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 22:29:24 -07:00
7640a16eb3
OpenConnection: a setup token you paste, a bridge that honours it (#174)
The SimpleFIN door written down for anything a bridge holds: a person gets
a single-use setup token from the bridge, pastes it into an app, the app
claims it once for an access URL and a bearer the bridge can revoke. No
client registration, no redirect, no key for the app to keep, which is what
a browser extension or a script needs. Bearer instead of SimpleFIN's Basic
credentials in the URL, because a browser's fetch refuses those. Eight
rules, the social profile (accounts, analyze, write, suggest, activity,
posts only when declared) and the finance profile (SimpleFIN, unchanged).

First bridge: mynaposter.com (/connect). First app: DefPromo. Registered
as one entry in the specs registry under Access and credentials, beside
OpenAccess, which is the registered door with the same scope vocabulary.


Claude-Session: https://claude.ai/code/session_01XYae2mH3khdwiXUVzcVMDw

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 22:22:39 -07:00
9f941fca42
OpenFile and OpenDisk carry OpenServer 0.2's developer block, and OpenFile names fi1zes.com (#173)
A publisher and a disk each say which CLI drives them, in the same
`developer` shape OpenServer 0.2 defines, so a marketplace shows one
install line beside every listing without reading a docs page per host.
fi1zes.com is the name chosen for the OpenFile marketplace on 2026-09-13,
not yet registered; bittorrented.com stays the reference reader until then.


Claude-Session: https://claude.ai/code/session_01Khk1C6Ese6xjdHAWLVstca

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 22:05:06 -07:00
9ba3d5c108
OpenProfile 0.3: Gender and Voice in the identity block (#172)
How a machine should sound when it speaks for you, and the order a reader
chooses in: Voice, then Gender, then Pronouns, never a name or a photo.
Gender means the same in the identity block and under Match. The first
reader is nixamp's party line, which reads trollbox lines to the people
on the phone in a room in the author's voice (nixamp 0.23.5).


Claude-Session: https://claude.ai/code/session_01GxYGCCvvuhVAkU1W2iJKTV

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 21:50:52 -07:00
85426e2ae0
OpenServer 0.2: the provider says how to install its CLI (#171)
A directory that lists a host's plans is asked the next question at once:
how do I drive this thing from a terminal? Every provider answers it on a
page of its own, in its own words, and a reader that wants the install line
has to find and read that page for each host. nichedb.dev's hosting
collection just did exactly that for 46 providers, copying the commands
off each vendor's guide, and the exercise is the argument for putting the
facts in the descriptor.

`provider.developer` names the official CLI, its install commands keyed by
package manager and copied as the guide prints them, the install guide and
source, the API docs, the Terraform provider and the GitHub organisation. A
provider with no CLI says `"cli": null`, which is a fact, while a missing
block means unknown. Commands are copied, never composed: a reader that
invents `brew install <name>` sends a buyer to a formula that may not exist.

c0mpute.md gains the same block for the compute market, with the one
install line c0mpute.com prints, and the landing page says what 0.2 adds.


Claude-Session: https://claude.ai/code/session_01Khk1C6Ese6xjdHAWLVstca

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 21:46:01 -07:00
df57b54bde
Breadcrumbs on every page, and a sidebar that unfolds to where you are (#170)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
Anthony: "this needs a cookie crumb navbar, all pages need this with the
new IA" and "broad and drill down, I'm not seeing that in the sidebar".

lib/crumbs.ts derives the trail from the path and the spec registry, so
no page declares it: /openthreat is Home > Specs > Catalogs a site serves
about itself > OpenThreat, /opencpu adds OpenServer before OpenCPU,
/docs/openthreat ends in Specification, /docs/cli is Home > Docs > CLI,
a blog post passes its title as the leaf. components/breadcrumbs.tsx
renders it (server-rendered, with a BreadcrumbList JSON-LD) at the top
of every SiteShell page; the SPA routes rendered by page-markup.ts get
the same trail as a string.

components/side-nav.tsx replaces the flat sidebar: the four groups stay,
and under Specs the family the current page belongs to unfolds to its
specs, and the spec to its blocks, marked active. The home page string
marks the active entry for the SPA routes too.


Claude-Session: https://claude.ai/code/session_014cmNRtR2vL1p89dbVQ7FZJ

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 21:04:02 -07:00
eee9ce09c5
Site IA: broad sidebar, four spec families, one registry (#169)
Anthony: "that site needs better information architecture, it's impossible
to find anything", "start broad in sidebar and drill down with dedicated
pages, not all one page", and "I see none of our specs" on the home page.

One registry, lib/specs.ts, now lists every specification in four
families (people and agents; access and credentials; catalogs a site
serves about itself; agents and process), with a landing path, a
specification path and, for OpenServer's blocks, a parent. Everything
that lists specs reads it: the sidebar (lib/nav.ts, four groups: Start,
Specs, Tools, Company, rendered by SiteShell and by the home page string
from the same array), /specs and /specs/<family>, the home page's
Standards Surface grid (families with their specs, replacing the five
abstract primitives), /docs (grouped by family, then guides), the sitemap
and llms.txt. DOC_SLUGS is derived from the registry. Adding a spec is
one entry plus its files; the four hand-kept lists are gone.


Claude-Session: https://claude.ai/code/session_014cmNRtR2vL1p89dbVQ7FZJ

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 20:38:28 -07:00
a005d7c716
docs: OpenBroadcast and OpenGuest, the broadcaster-and-guest framework as OpenProfile.md sections (#168)
* docs: OpenBroadcast and OpenGuest, the broadcaster-and-guest framework as OpenProfile.md sections

Anthony: "broadcasters and guests is the usual framework for live audio
shows, radio, podcasts" and OpenProfile.md should carry it so a platform
(anyfans) can match hosts with guests from two files rather than two
forms. OpenExpert folds into OpenGuest: an expert is a guest with
Expertise and Credentials.

OpenBroadcast is the `## Broadcast` section: Show, Kind, Format, Live,
Cadence, Length, Language, Audience (host's own unit), Feed, Topics,
Seeking, Not, Slots, Remote, Book, and Pays / Charges (unstated by
default, because pay-to-play is the thing a guest is most often not
told). OpenGuest is the `## Guest` section: Available, Expertise,
Credentials, Pitch, Formats, Live, Languages, Availability, Lead time,
Remote, Rate, Pays, Appeared on, Press, Book, Not. Matching scores
Topics/Seeking against Expertise/Topics, Slots against Availability,
Pays/Charges against Rate/Pays; both Not keys are absolute; a platform
never fills a key the person did not write. Both landing pages share
profile-section-page.tsx. OpenProfile.md names the two sections in rule
4 and in Related standards. Registered in the four places.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014cmNRtR2vL1p89dbVQ7FZJ

* ci: trigger workflows

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 20:30:42 -07:00
0fe1d423df
docs: OpenThreat, one file a security tool serves about what it found in the open (#167)
* docs: OpenThreat, one file a security tool serves about what it found in the open

Twelve rules that degrade and two that do not: a subject is public or it
is not in the file (no private repos, no customer servers, no paid users'
scans), and a secret is never located while it is open (rule, severity,
subject, status only; no location, message or excerpt). Four kinds:
finding, attack, indicator, advisory. Status open, fixed, mitigated,
blocked, withdrawn; a withdrawn threat stays a while so directories
retract it. Announcing is on by default with a one-switch opt-out in the
tool's own settings. Discovery at /.well-known/openthreat.json,
rel="openthreat", or a handed URL; origin is the verification. Mapped
against SARIF, STIX 2.1 and CSAF rather than replacing them.

First reporter: threatcrush.com/discovery (its own PR). First directory:
nichedb.dev/c/threats (its own PR). Registered in DOC_SLUGS, NAV,
STATIC_ROUTES and llms.txt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014cmNRtR2vL1p89dbVQ7FZJ

* ci: trigger workflows

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 20:30:22 -07:00
938bd5f632
OpenAffiliate 0.1: one file a merchant serves about the commission it pays (#166)
The descriptor at /.well-known/openaffiliate.json (programs with pays,
link, window, attribution, hold_days, payout, approval, self), the four
calls (join with an OpenProfile.md, link with ?oa=code, read the ledger,
get paid to your own address), webhooks, discovery, what a directory
owes a merchant, and what is deliberately absent: no network in the
money, no tracking host, no application form, no exclusivity, no
impression payments. Landing page at /openaffiliate, registered in
DOC_SLUGS, NAV, sitemap and llms.txt. Reference implementation is
crawlproof.com/affiliate.


Claude-Session: https://claude.ai/code/session_01CDEiDss9RWYibtmxSk5Gr2

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 19:36:59 -07:00
8269c12b75
docs: OpenCoupon and OpenRecipe.md, the first two niche specs (#165)
Anthony: every top-level nichedb.dev niche may need its own open<niche>
spec so the serve-your-own-file pattern scales across industries. These
are the two he named first.

OpenCoupon: one JSON file a merchant serves at
/.well-known/opencoupon.json about what is on offer right now: every
code, sale and shipping threshold with kind (percent, amount, shipping,
bogo, gift, other), value, scope, min_order, dates, status, per-customer
and region limits. Expired coupons stay in the file so a directory
learns a code died from the one party that knows. No affiliate links,
no redemption, no votes. First reader: nichedb.dev/c/deals.

OpenRecipe.md: one Markdown file that is a recipe, in the OpenProfile.md
and OpenResume.md style: a summary block (Serves, Prep, Cook, Cuisine,
Course, Diet, Author, Source, Image), a description line, Ingredients
and Steps as written, Notes, Nutrition per serving. Served next to the
page, linked with rel="openrecipe", or indexed at
/.well-known/openrecipe.md. A one-way mapping to schema.org/Recipe:
the JSON-LD is generated from the Markdown, never the reverse.

Both registered in DOC_SLUGS, NAV, STATIC_ROUTES and llms.txt.


Claude-Session: https://claude.ai/code/session_014cmNRtR2vL1p89dbVQ7FZJ

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 19:16:34 -07:00
26295dd740
OpenFile and OpenDisk: the web doors onto an ipfile swarm and a paid2seed seeder (#162)
OpenSwarm says how a file lives on a swarm and how a seeder is paid to hold
it, and nothing in it gives a person with a browser, a search engine or a
directory a URL to start from. A manifest is on the DHT under a key, the
catalogue is a feed found through the DHT, the seed market is one-sided:
offers are listed and seeders poll them. A requester who wants a box in
Germany with two terabytes free and a year of clean proofs has no file to
read, and a seeder with those things has no file to serve.

OpenFile is /.well-known/openfile.json on a publisher's origin: each file
by its plaintext content hash (the ipfile plainRoot, so the id a reader
gets is the root the decrypted file verifies against), every way to fetch
it (an ipfile magnet, a webseed, plain HTTP by range, HLS for a player
with nothing installed), the pay2seed attestation and README, the price
as an x402 offer URL, and a holders list of who has the bytes now with
the age of each seeder's last proof. Encryption is ipfile unless the
publisher says none as an explicit act.

OpenDisk is /.well-known/opendisk.json on a machine that rents disk: free
GiB, price per GiB-month in the unit pay2seed already prices in, the
operator's accept policy stated up front so nobody posts an offer the disk
would never take, proof cadence, the seeder key and the hubs it takes
leases at, and a record block whose source is the hub's own seeder page,
because a marketplace reads standing from the hub and never from the
file. d1sks.com is the reference marketplace. A disk is also an OpenServer
offer of kind storage, and the mapping is a table, so the nichedb hosting
collection lists every disk without a second parser.

Neither restates a record that already has a name: the swarm is ipfile,
the consent is pay2seed, the leases and proofs are paid2seed, the payee
and the pass are ippay, the feed is ipdb. Both are registered in the four
places a LogicSRC spec needs and added to the OpenSwarm family table.
OpenFile has no product domain yet and says so.


Claude-Session: https://claude.ai/code/session_01Khk1C6Ese6xjdHAWLVstca

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 19:05:15 -07:00