mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-02 04:43:58 +00:00
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>
This commit is contained in:
parent
0fe1d423df
commit
a005d7c716
10 changed files with 464 additions and 1 deletions
|
|
@ -34,6 +34,8 @@ export function GET(): Response {
|
|||
- [OpenRecipe.md](${SITE_URL}/openrecipe): One Markdown file that is a recipe: summary block (Serves, Prep, Cook, Cuisine, Diet, Author, Source), ingredients and steps as written, notes, nutrition; served next to the page or linked with rel="openrecipe"; schema.org/Recipe JSON-LD is derived from it, never the reverse.
|
||||
- [OpenAffiliate](${SITE_URL}/openaffiliate): One file a merchant serves about the commission it pays, at /.well-known/openaffiliate.json: programs with what pays (sale, subscription, signup, lead, install), percent or amount, attribution window, hold days and payout methods; four calls let a person or an agent join with an OpenProfile.md, link with ?oa=code, read its own ledger and get paid to its own address. No network in the money; reference implementation crawlproof.com/affiliate.
|
||||
- [OpenThreat](${SITE_URL}/openthreat): One file a security tool serves about what it found in the open, at /.well-known/openthreat.json: findings in public repositories, attacks on the reporter's own infrastructure, indicators and advisories, with severity, rule, subject and status. Private subjects are never in it, secrets are never located while open, announcing is on by default with a one-switch opt-out. First reporter threatcrush.com/discovery, first directory nichedb.dev/c/threats.
|
||||
- [OpenBroadcast](${SITE_URL}/openbroadcast): The Broadcast section of an OpenProfile.md: the show a person hosts (podcast, radio, live audio, stream) with kind, format, cadence, audience, topics, slots, whether it pays or charges guests, and who the host is seeking, so a host and a guest are matched from two files rather than two forms.
|
||||
- [OpenGuest](${SITE_URL}/openguest): The Guest section of an OpenProfile.md: that a person will appear on shows, with expertise, credentials, pitch, formats, availability, rate, past appearances and dealbreakers. An expert is a guest with Expertise and Credentials. Matched against OpenBroadcast.
|
||||
- [AgentSwarm](${SITE_URL}/agent-swarm): Provider-neutral agent orchestration, model routing, and cost controls.
|
||||
- [AgentByte](${SITE_URL}/agentbyte): Agent screening sessions, policy events, and APIs.
|
||||
- [Credential Sharing](${SITE_URL}/credential-sharing): End-to-end-encrypted team vaults, plus source/target credential diffs, approval, sync, rollback, and audit.
|
||||
|
|
|
|||
61
apps/logicsrc-web/src/app/openbroadcast/page.tsx
Normal file
61
apps/logicsrc-web/src/app/openbroadcast/page.tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import type { ReactNode } from "react";
|
||||
import type { Metadata } from "next";
|
||||
import { ProfileSectionPage, type ProfileSection } from "@/components/profile-section-page";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "OpenBroadcast · LogicSRC",
|
||||
description:
|
||||
"OpenBroadcast is the Broadcast section of an OpenProfile.md: the show a person hosts (podcast, radio, live audio, stream), its format, cadence, audience, topics and slots, and who the host is seeking, so a host and a guest are matched from two files rather than two forms.",
|
||||
alternates: { canonical: "/openbroadcast" }
|
||||
};
|
||||
|
||||
const SPEC: ProfileSection = {
|
||||
name: "OpenBroadcast",
|
||||
slug: "openbroadcast",
|
||||
section: "Broadcast",
|
||||
tagline:
|
||||
"What a person hosts, live or recorded, on air or online, and who they are looking for on it.",
|
||||
problem:
|
||||
"Every show has a booking page and every booking page is a form. A host who wants guests fills in four of them, and each holds half of what a guest needs to know: what the show is about, who listens, how long a segment runs, whether it is live, what the host wants this month. A guest's agent asked which shows on climate finance record in the evening in Europe reads twelve pages twelve ways. The host wrote the answers once and typed them into forms that will not hand them back.",
|
||||
sample: `## Broadcast
|
||||
|
||||
- **Show**: The Analytical Engine
|
||||
- **Kind**: podcast
|
||||
- **Format**: interview
|
||||
- **Live**: no
|
||||
- **Cadence**: weekly
|
||||
- **Length**: 45 min
|
||||
- **Language**: en
|
||||
- **Audience**: 12k downloads/episode
|
||||
- **Feed**: https://ada.example/podcast/feed.xml
|
||||
- **Topics**: computing history, mathematics, women in science
|
||||
- **Seeking**: historians, engineers with a story, first-time guests welcome
|
||||
- **Not**: crypto, product pitches
|
||||
- **Slots**: Tue and Thu 18:00-20:00 Europe/London
|
||||
- **Remote**: yes
|
||||
- **Book**: https://ada.example/podcast/book
|
||||
- **Pays**: no
|
||||
- **Charges**: no`,
|
||||
keys: [
|
||||
["Show, Kind, Format", "name; podcast, radio, live-audio, stream, video, newsletter, series; interview, panel, solo, call-in, roundtable, narrative", "What the show is. Two shows are two sections, or ### groups in one."],
|
||||
["Live, Cadence, Length, Language, Since", "yes / no / both; weekly, monthly, seasonal; a duration; language tags; a year or month", "As the host writes them."],
|
||||
["Audience", "the host's figure in the host's unit", "12k downloads/episode, 3,000 live listeners. A reader shows the unit and never compares across units."],
|
||||
["Feed, Listen, Watch, Network", "URLs; a name or OpenProfile.md URL", "Feed is the episode list; RSS already is the spec for it."],
|
||||
["Topics, Seeking, Not", "loosely matched words", "What the show covers, who the host wants, what the host will not book. Not wins over everything."],
|
||||
["Slots, Remote, Book", "as written with a timezone; yes / no / preferred / in-person only; URL", "When and how a guest appears, and where to ask."],
|
||||
["Pays, Charges", "no, yes, or an amount", "Whether the show pays guests and whether it charges them. Unstated by default, because pay-to-play is the thing a guest is most often not told."]
|
||||
],
|
||||
matching:
|
||||
"A booking platform reads a host's Broadcast and a guest's Guest section and scores the pair from what both wrote: Topics and Seeking against Expertise and Topics, Slots against Availability, Language against Languages, Remote against Remote, Pays and Charges against Rate and Pays. Both Not keys are absolute. Everything else is a score, and the platform says how it scored. The platform never fills a key the person did not write.",
|
||||
absent: [
|
||||
["No episode list", "Feed is the episode list, and RSS already is the spec."],
|
||||
["No audience verification", "Audience is the host's figure. A platform that verifies it labels the verification as its own."],
|
||||
["No booking protocol", "Book is a link. What happens there is the platform's business."],
|
||||
["No JSON", "The Markdown is the canonical copy; a structured view is derived on every read."]
|
||||
],
|
||||
counterpart: ["OpenGuest", "openguest"]
|
||||
};
|
||||
|
||||
export default function OpenBroadcastPage(): ReactNode {
|
||||
return <ProfileSectionPage spec={SPEC} />;
|
||||
}
|
||||
60
apps/logicsrc-web/src/app/openguest/page.tsx
Normal file
60
apps/logicsrc-web/src/app/openguest/page.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import type { ReactNode } from "react";
|
||||
import type { Metadata } from "next";
|
||||
import { ProfileSectionPage, type ProfileSection } from "@/components/profile-section-page";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "OpenGuest · LogicSRC",
|
||||
description:
|
||||
"OpenGuest is the Guest section of an OpenProfile.md: that a person is available to appear on shows, their expertise and credentials, formats, availability, rate, past appearances and dealbreakers, so a guest and a host are matched from two files rather than two forms. An expert is a guest with Expertise and Credentials.",
|
||||
alternates: { canonical: "/openguest" }
|
||||
};
|
||||
|
||||
const SPEC: ProfileSection = {
|
||||
name: "OpenGuest",
|
||||
slug: "openguest",
|
||||
section: "Guest",
|
||||
tagline:
|
||||
"That a person will appear on other people's shows, what they can speak to, when, on what terms, and where they have been heard before.",
|
||||
problem:
|
||||
"An expert who is happy to be interviewed has no way to say so that a host's search will find. They fill in a guest-matching site, a speaker bureau, a press page and a line in a bio, and each holds a fragment: topics on one, availability on another, the fee nowhere. A host's agent asked who can talk about analytical engines, records in the evening in Europe and does not charge reads a hundred profiles a hundred ways.",
|
||||
sample: `## Guest
|
||||
|
||||
- **Available**: yes
|
||||
- **Expertise**: analytical engines, early computing, mathematics education
|
||||
- **Pitch**: Wrote the first program for a machine that was never built, and can explain why that matters now.
|
||||
- **Formats**: interview, panel
|
||||
- **Live**: both
|
||||
- **Languages**: en, fr
|
||||
- **Timezone**: Europe/London
|
||||
- **Availability**: weekday evenings, some weekends
|
||||
- **Remote**: preferred
|
||||
- **Lead time**: 2 weeks
|
||||
- **Rate**: free
|
||||
- **Pays**: no
|
||||
- **Appeared on**: [The Analytical Engine](https://ada.example/podcast/ep12), [BBC Radio 4](https://bbc.example/babbage)
|
||||
- **Credentials**: Countess of Lovelace; first published algorithm, 1843
|
||||
- **Not**: crypto, pay-to-play, politics
|
||||
- **Book**: https://ada.example/book`,
|
||||
keys: [
|
||||
["Available", "yes, no, selectively, or a date range", "Absent is unstated, never available."],
|
||||
["Expertise, Credentials, Pitch", "loosely matched words; as written; one or two lines", "The expert half of the framework: an expert is a guest with Expertise and Credentials. Detail lives in the Resume link."],
|
||||
["Formats, Live, Languages", "interview, panel, solo, call-in, debate, live-audio; yes / no / both; language tags", "What the guest will do."],
|
||||
["Location, Timezone, Availability, Lead time, Remote", "as written", "When and how the guest can appear."],
|
||||
["Rate, Pays", "free, an amount, negotiable; no, yes, an amount", "What the guest charges, and whether they will pay to appear. A guest who writes Pays: no is not shown pay-to-play shows."],
|
||||
["Appeared on, Press, Book", "links", "Past appearances a host can listen to; a press page; where to ask."],
|
||||
["Not", "loosely matched words", "What the guest will not do or discuss. Wins over everything else."]
|
||||
],
|
||||
matching:
|
||||
"A booking platform reads a guest's Guest and a host's Broadcast section and scores the pair from what both wrote: Expertise and Topics against Topics and Seeking, Availability against Slots, Languages against Language, Remote against Remote, Rate and Pays against Pays and Charges. Both Not keys are absolute. The platform never fills a key the person did not write; Appeared on is the one key it may add to, only with the appearances it booked itself, marked as its own.",
|
||||
absent: [
|
||||
["No ratings", "A host who wants to know how a guest was listens to Appeared on."],
|
||||
["No exclusivity", "Every platform may read the file. A platform that wants a guest to itself has a contract, not a profile."],
|
||||
["No taxonomy of expertise", "Expertise is the words the person wrote."],
|
||||
["No JSON", "The Markdown is the canonical copy."]
|
||||
],
|
||||
counterpart: ["OpenBroadcast", "openbroadcast"]
|
||||
};
|
||||
|
||||
export default function OpenGuestPage(): ReactNode {
|
||||
return <ProfileSectionPage spec={SPEC} />;
|
||||
}
|
||||
|
|
@ -23,6 +23,8 @@ const STATIC_ROUTES: Array<{
|
|||
{ path: "/openprd", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/asdlc", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/openprofile", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/openbroadcast", changeFrequency: "weekly", priority: 0.9 },
|
||||
{ path: "/openguest", 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 },
|
||||
|
|
|
|||
130
apps/logicsrc-web/src/components/profile-section-page.tsx
Normal file
130
apps/logicsrc-web/src/components/profile-section-page.tsx
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
import Link from "next/link";
|
||||
import type { ReactNode } from "react";
|
||||
import { SiteShell } from "@/components/site-shell";
|
||||
import { mono, pre, table, td, th } from "../app/openontology/ui";
|
||||
|
||||
/**
|
||||
* One landing page shape for the specifications that are a section of
|
||||
* OpenProfile.md (OpenBroadcast, OpenGuest). The section lives in the
|
||||
* person's profile file; the page says what the section's keys mean and
|
||||
* what the other half is.
|
||||
*/
|
||||
|
||||
export type ProfileSection = {
|
||||
name: string;
|
||||
slug: string;
|
||||
/** The `## Heading` in the profile. */
|
||||
section: string;
|
||||
tagline: string;
|
||||
problem: ReactNode;
|
||||
/** The example section, Markdown. */
|
||||
sample: string;
|
||||
/** Key, values, meaning. */
|
||||
keys: Array<[string, string, string]>;
|
||||
/** How a platform matches this section against its counterpart. */
|
||||
matching: string;
|
||||
absent: Array<[string, string]>;
|
||||
/** The other half: name and slug. */
|
||||
counterpart: [string, string];
|
||||
};
|
||||
|
||||
export function ProfileSectionPage({ spec }: { spec: ProfileSection }): ReactNode {
|
||||
const [otherName, otherSlug] = spec.counterpart;
|
||||
return (
|
||||
<SiteShell active={spec.name}>
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<p className="eyebrow">LogicSRC standards surface · OpenProfile.md section</p>
|
||||
<h2>{spec.name}</h2>
|
||||
<p>{spec.tagline}</p>
|
||||
</div>
|
||||
<p style={{ color: "#41505d" }}>{spec.problem}</p>
|
||||
<p style={{ color: "#5b6b7a" }}>
|
||||
Status: 0.1. A <code style={mono}>## {spec.section}</code> section in a person's or
|
||||
a show's <Link href="/openprofile">OpenProfile.md</Link>, matched against{" "}
|
||||
<Link href={`/${otherSlug}`}>{otherName}</Link>. Every key is optional and kept as
|
||||
written; what is not written is unstated, and a platform never fills it in.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The section</h2>
|
||||
</div>
|
||||
<pre style={pre}>{spec.sample}</pre>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>The keys</h2>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={th}>Key</th>
|
||||
<th style={th}>Values</th>
|
||||
<th style={th}>Meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{spec.keys.map(([key, values, meaning]) => (
|
||||
<tr key={key}>
|
||||
<td style={td}>
|
||||
<code style={mono}>{key}</code>
|
||||
</td>
|
||||
<td style={td}>{values}</td>
|
||||
<td style={td}>{meaning}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>Matching</h2>
|
||||
</div>
|
||||
<p style={{ color: "#41505d" }}>{spec.matching}</p>
|
||||
</div>
|
||||
|
||||
<div className="band">
|
||||
<div className="section-head">
|
||||
<h2>What is deliberately absent</h2>
|
||||
</div>
|
||||
<table style={table}>
|
||||
<tbody>
|
||||
{spec.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/${spec.slug}`}>Specification</Link>: the section, every key,
|
||||
matching, discovery
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`/${otherSlug}`}>{otherName}</Link>: the other half of the
|
||||
broadcaster-and-guest framework
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/openprofile">OpenProfile.md</Link>: the file the section lives in, found
|
||||
at <code style={mono}>/.well-known/openprofile.md</code> or through{" "}
|
||||
<code style={mono}>rel="openprofile"</code>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</SiteShell>
|
||||
);
|
||||
}
|
||||
|
|
@ -15,6 +15,8 @@ const NAV: Array<{ href: string; label: string; external?: boolean }> = [
|
|||
{ href: "/openprd", label: "OpenPRD" },
|
||||
{ href: "/asdlc", label: "ASDLC" },
|
||||
{ href: "/openprofile", label: "OpenProfile" },
|
||||
{ href: "/openbroadcast", label: "OpenBroadcast" },
|
||||
{ href: "/openguest", label: "OpenGuest" },
|
||||
{ href: "/openmcp", label: "OpenMCP" },
|
||||
{ href: "/openaccess", label: "OpenAccess" },
|
||||
{ href: "/openserver", label: "OpenServer" },
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ export const DOC_SLUGS = [
|
|||
"openjob",
|
||||
"openresume",
|
||||
"openprofile",
|
||||
"openbroadcast",
|
||||
"openguest",
|
||||
"openmcp",
|
||||
"openaccess",
|
||||
"openserver",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue