Commit graph

35 commits

Author SHA1 Message Date
331b437724
docs: OpenJob and OpenResume.md (#148)
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
Two conventions for the hiring end of the agentic stack, published here beside
the other Open* specs.

OpenResume.md says a resume is a Markdown file: a document a person can read,
diff and keep, and one an agent can write without being taught a schema first.
Six conventions, every one of which degrades rather than fails, because a
resume that does not parse still has to be a usable resume.

OpenJob extends schema.org JobPosting with the three things it has no
vocabulary for: whether the employer accepts applications written with an agent
(stated, rather than discovered by silent rejection), the application form as
data so applying does not require rendering a page, and a description in
Markdown.

Both are implemented by profullstack/agenticjobs, and neither requires it.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:16:05 -07:00
91834179b7
Add Tech Stack and Monetization sections to OpenPRD (0.3) (#144)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
OpenPRD 0.2 fixed eight body sections, none of which asked what the thing is
built on or how it earns. The stack got chosen in the first implementation PR
instead of at review, and a PRD could be filled out completely without anyone
writing down who pays. PRD 0006 had already grown a hand-rolled
`## Business model` section, which is the gap showing.

0.3 adds two required sections between `UX Notes` and `Success Metrics`:

  - Tech Stack — languages, frameworks, datastores, third-party services, and
    anything the work must not depend on. It makes the requirements costable.
  - Monetization — the revenue model: who pays, for what, how much, and when.
    `_None._` stays a valid answer, but it now has to be said out loud.

Adding required sections would normally invalidate every document already
written, so a document is now held to the section list its own `openprd:` key
fixes. A 0.2 document keeps conforming with eight sections, forever; a 0.3
document needs ten. Adoption is per document, and `logicsrc prd validate
--expect-version 0.3` (new flag, wiring up the validator option that already
existed) reports the stragglers as OP-L-VERSION.

The front-matter schema is untouched — both additions are body sections.

Conformance bundle proves both directions: invalid/missing-monetization.md
fails with OP-C-SECTION-MISSING, and valid/legacy-0-2.md passes unedited.

This repo's own PRDs 0001-0006 stay at 0.2 as standing evidence that the
compatibility rule holds. PRD 0007 records the decision at 0.3.


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

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 16:50:11 -07:00
ca0283caa9 Add ASDLC, the Agentic Software Development Lifecycle
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
ASDLC 0.1 describes how software gets built when most of the work is done
by agents running in parallel and CI/CD is the only gate. It is a
description of a practice already in production, not a proposal.

The traditional SDLC assumes the scarce resource is engineering time, so
it spends process on deciding whether each change is worth building. When
agents write the code, engineering time stops being scarce and two other
things become scarce: human attention, and trunk stability.

Nine phases: frame, fan out, gate locally, merge, release, verify live,
correct, ratchet, promote. Correct returns to fan out, so the loop is the
lifecycle.

The load-bearing phase is the ratchet. Testing in production is only
defensible if production failures are one-time events, so every escape
becomes a permanent automated check before the incident is closed, and
that check has to be confirmed to fail when the bug is reintroduced. A fix
without a ratchet is how the same class of bug ships three times.

Four conformance levels, of which only level 3 requires evidence rather
than intent. The worked example is DiskPush on 2026-09-06: eight agent
worktrees on one checkout, four releases between 08:53 and 14:56 UTC, and
a three-release desktop bug whose first layer no local harness could have
caught, because a static server resolves absolute paths correctly by
construction and the bug only existed under file://.

Published at /asdlc with the spec at /docs/asdlc, listed in the nav,
sitemap and llms.txt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Q2bt449mEJSHoEZzaemCn
2026-09-06 15:02:31 +00:00
be99e683bd
Add pay2seed, paid2seed, pay2stream and paid2stream to the OpenSwarm family (#143)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
* Add pay2seed to the OpenSwarm family: consent at upload and a paid seed market

OpenSwarm pays a seeder per verified piece served, and nothing pays anyone
to stay. An archive, a backup, a dataset waiting for its buyer or a
podcast's back catalogue earns nothing the month nobody downloads it, so
it dies the way every swarm always has. And nothing in BitTorrent says who
put a swarm there or whether they were allowed to, which is why a seeder
is presumed to be doing something wrong.

pay2seed is the member document for both halves. An attestation, signed
at upload with a fixed basis (own, licensed, open-license, public-domain,
personal) and a notice endpoint, is what a hub requires before it will
list anything; public claims get a claim window and a standing, and a
notice voids them. An offer escrows a budget at an ippay hub for a swarm,
public or private, to be held by M seeders for N days at a price per
GiB-month, bought over x402 exactly as a pass is. Seeders take leases,
prove each period by storage challenge or by a probe over the ordinary
wire, and are paid through the payee they already have. Public feeds ride
on ipdb; ipfile.pin on c0mpute is the same offer on the auction.

Also: the family table, stack diagram and registry rows; the ip seed
command group; PRD 0006; the protocol row on /openswarm.

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

* Split pay2seed into client and server halves, and add pay2stream and paid2stream

The rule is now in the names. pay2* is the client protocol: the side that
pays, over HTTPS, and plays. paid2* is the server protocol: the BitTorrent
side that earns. One hub implements both halves of a pair; a requester or
viewer implements only pay2*; a seeder, relay or gateway only paid2*.

pay2seed keeps consent, offers, the requester's market and notices.
paid2seed takes leases, storage challenges and probes over the wire,
GiB-month accrual and receipts, the seeder client, and the ipfile.pin
mapping.

pay2stream and paid2stream do the same for a live channel over iplive.
A broadcaster attests the channel (with the two rules that separate a
licensed rebroadcast from a stolen feed), buys relays by the hour, and
publishes listings; viewers buy tickets. Relays take leases and are
proven present by a verifier that pulls segments as a peer; a gateway is
a relay that also serves standard HLS, clear or sealed, with the M3U and
XMLTV pair every IPTV app asks for, so VLC, TiviMate, Kodi and a
television play a paid swarm with nothing installed. Ace Stream showed
BitTorrent can carry live TV to millions; this is that with consent,
payment and an open spec.

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

* pay2seed: encrypted by default, access as the product, a README in every swarm

The client encrypts by default and the hub never does: what the hub
manages is who may decrypt. A team is a named set of member keys with a
scope over the owner's swarms; the hub, as keeper, issues grants to
members when the owner is offline, with invitations that expire, roles,
an audit trail, and re-encryption on removal so the next version is
closed to whoever left. A few seats are free; above that the hub charges
per seat and per organisation, settled through the same pay plugins as
everything else. Seeding is priced at disk; access is where a hub earns,
and both sides earn: seeders rent disk, requesters sell access.

Public is not a fallback. Encryption off is an explicit act, and a
public swarm is attested, listed, kept and rendered exactly as a private
one is; the only difference is who can read it.

Every swarm on the market carries a README.md at its root, no
exceptions, and the attestation carries its Markdown and the hash of
the copy inside the swarm, so the hub renders it as the swarm's page
without a key. Relative links resolve into the swarm and are gated the
way the files are.

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

* pay2seed: 1 percent, ads on the free tier, and agents as sellers

Three things the specs did not say. The reference hub takes 1 percent of
any payment that crosses it, charged to whoever is paying and never
deducted from a seeder or a relay, so a quoted price is what the
publisher gets and a promised floor is what the seeder is paid.

Public swarms are free to fetch and free to list, and an advertisement on
the swarm README page is what pays for that. The ad is on the hub page
and nowhere else: never inside a swarm, never injected into a file, a
segment or a playlist, and never in the catalogue or the market API. A
requester who wants no ad buys a seat instead. A free-to-watch channel
works the same way.

And a requester is a key, not a person. An agent can attest what it made,
price access, sell tickets, take payment through its own payee and spend
what it earns keeping its own work online. The consent rules do not
soften because a machine signed them, and the reference hub asks an
agent public attestation to name a responsible operator key so somebody
is reachable when a notice arrives.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKAohrRkqLKVQL2cGCAkR5

* Fix CI: number the PRD requirements and advance the next-id assertion

Two checks the new PRD tripped, both by existing rather than by being
wrong.

The collection validator wants requirements as numbered R# entries and
0006 used a plain ordered list, so it reported OP-L-NO-REQUIREMENTS.
Rewritten as R1 to R7 with priorities, one capability per entry, and the
implementation tracking moved to a paragraph under them where it is not
pretending to be a requirement.

The MCP standards test asserts what the next free PRD id is, and its own
comment says that advances with every PRD added. Adding 0006 makes it
0007.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKAohrRkqLKVQL2cGCAkR5

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-05 19:12:45 -07:00
4fed2681ec
Add the LogicSRC OpenSwarm specification family (#142)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
BitTorrent distributes bytes better than any CDN and has never been a
product: nobody is paid to seed, and nothing in it is private. Every
Profullstack media property answers that with a central HTTP proxy and a
pass system bolted on, and pays for every byte it serves.

OpenSwarm is an add-on to BitTorrent, carried as BEP 10 extension
messages, that fixes both. The swarm carries AES-256-CTR ciphertext whose
integrity is pinned by two SHA-256 merkle roots in a signed manifest, so
a tracker or DHT node learns an infohash and a size. A leecher buys a
pass over x402 in USDC (the same exchange x402-gateway runs for crawl
passes, settled by CoinPay), a seeder serves inside a bounded credit
window, and the leecher signs a cumulative voucher for every verified
batch. Whoever seeds gets paid. Vanilla clients remain valid members and
browsers remain first-class peers.

Adding a file mints a key pair for it, derived from one publisher seed by
default so there is one thing to back up: the public half is the file's
identity and its BEP 46 key, the private half signs the manifest and
authorises grants and payout changes, and a separate content key
encrypts the bytes and is sealed to paying peers.

The family: a core (records, keys, hashing, transports, discovery,
events), ipfile, ippay, ipdb (a signed hash-chained catalogue with heads
on the DHT), ipaudio, ipvideo, iplive (paid relays with backpressure)
and ipname (Moshpit pins and DNS TXT). Plus the c0mpute.com integration
with seven workload types and thirteen use cases, a proposed ip CLI,
conformance profiles, a security model and an FAQ.

Registered on the site the way OpenCreds is: nav entry, docs registry,
sitemap, a /openswarm landing page, PRD 0005, and the MCP prd_next_id
expectation moved to 0006.

Specs only. No code, no schemas, no reference implementation.


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

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-05 15:05:57 -07:00
80a36269bb
Add the LogicSRC OpenCreds specification (#140)
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
* Add the LogicSRC OpenCreds specification

Leaving a password manager means writing every secret you own to disk in
the clear, and losing whatever the spreadsheet had no column for. A CSV
is plaintext by construction, lossy by omission, and carries no
integrity: nothing in it says which rows were meant to be there, so a
truncated import looks exactly like a complete one.

The same gap showed up inside LogicSRC. `logicsrc credentials` moves
.env secrets and SSH keys through end-to-end-encrypted team vaults, but
it can only model a key/value pair. A card, a passport, a login with a
TOTP seed, or an OAuth account with a refresh token are all things
people already keep in a vault, and none of them are a key/value pair.

OpenCreds defines three things: the item, the vault, and the database.

- Six item types (login, card, identity, note, key, account) as one
  record with a type and a named field group, so everything the user
  typed lives in a single encrypted blob. Codes 1-4 match MarkSyncr's
  deployed vault and are not renumbered; compatibility is cheaper than
  elegance.
- AES-256-GCM over that record with the item id bound as AAD. Without
  it, anyone with storage write access could move a low-value login's
  ciphertext into a high-value row and watch what the user does next.
- A key hierarchy where the user key is random, not derived, so a
  password change re-wraps 32 bytes rather than re-encrypting a vault.
  The auth hash comes out of a different HKDF label than the wrap key,
  which is what lets it reach a server at all.
- A portable .opencreds file, encrypted by default, whose header is the
  AAD over the payload -- so the manifest is authenticated by the same
  tag as the data and a truncated import fails rather than reporting
  success. The plaintext form exists because people move to products
  that read nothing else; it is opt-in, confirmed, 0600, and labelled
  "protected": false in its own header.

Namespaces are carried as data, not fixed by the spec: labels are
compiled into every ciphertext a vault has written, so editing one does
not migrate a vault, it makes it undecryptable. MarkSyncr's deployed
vault is conformant by declaring `marksyncr`.

Ships: prd/0004, nine spec pages under docs/opencreds/, six JSON
Schemas, the @logicsrc/opencreds reference implementation with CSV
importers for five products, `logicsrc vault` and the standalone
`opencreds` binary, and the spec page at logicsrc.com/opencreds.

`vault` rather than `creds` because `creds` is already an alias of
`logicsrc credentials`, and the two are different: one moves a pair
between providers, the other stores a record.

@logicsrc/validators now registers every schema by $id before
compiling, so the database schema can $ref the item and manifest
schemas rather than restating them.

120 tests, including CLI end-to-end coverage of the masking rules,
exit codes, and the manifest-mismatch path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QRQrfuwuYKKV5UB9kLHuX5

* Make the OpenCreds conformance claim executable

The conformance page described a fixture suite and an `opencreds
conformance` command that did not exist. A specification that documents
a conformance surface it cannot run is a specification nobody can hold
to, including us.

`opencreds conformance` now runs the requirement list as code -- one
check per C-number, carrying its own id and level -- and emits the
report shape the spec publishes. It exits 2 when a MUST does not pass,
so it can gate CI directly. The reference implementation reports 29
passed, 0 failed, 1 skipped; the skip is C19, because key management for
the team profile lives in @logicsrc/plugin-credential-sharing rather
than in this package, and a skipped MAY does not affect conformance.

Fixtures are generated (`--emit-fixtures <dir>`) rather than
hand-written. A vector produced by an implementation and then verified
by it is worth more than a JSON file someone typed: the typed file
drifts silently when the format moves, and the generated one cannot.
Fourteen files, including an invalid/ set every conforming reader must
reject -- a wrong field group, a weak KDF, an unregistered namespace, a
short payload and a tampered manifest.

The CLI requirements stay with the end-to-end tests that drive the real
binary through a child process; a command cannot meaningfully check its
own exit codes, and a masked value that is only masked in the library is
not masked.

conformance.md and cli.md now describe what ships.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QRQrfuwuYKKV5UB9kLHuX5

* Add @logicsrc/opencreds to the lockfile

`npm ci` refuses a lockfile that does not match package.json, and the
new workspace package plus the CLI's dependency on it were never
recorded: the worktree was bootstrapped by hardlinking node_modules
rather than installing, so npm was never asked to update the lock.

Adds the workspace link and the package entry. No dependency versions
move.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QRQrfuwuYKKV5UB9kLHuX5

* Register PRD 0004, and stop the fixtures looking like real secrets

Two CI failures, both mine.

`prd/README.md` is generated by `logicsrc prd index --write` and the
scaffold test asserts it is current, so adding a PRD without
regenerating it leaves the repo's own conformance check failing.
Regenerated. The MCP test asserts the next free PRD id against the live
prd/ directory — its comment says it advances with every PRD added — so
it moves to 0005.

ThreatCrush flagged three of the example strings: a PEM header in the
item-model docs and in the conformance fixture, and an `sk_live_`
prefixed token. All placeholders, none real, but the finding is the
scanner working. A fixture only has to exercise the field, and a
real-looking private key header or live-key prefix sitting in the tree
trains both the scanner and the people reading its output to shrug at
exactly the shape that matters. Replaced with obvious placeholders
rather than suppressing the rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QRQrfuwuYKKV5UB9kLHuX5

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 04:11:38 -07:00
b1805d08e5
Add SSH keys and config to credential sharing (#139)
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
* Add SSH keys and config to credential sharing

Private keys have lived as plaintext-on-disk files guarded only by a
passphrase. This puts them in the same end-to-end-encrypted vaults as
.env secrets, and adds an agent path so a machine can use a key without
ever writing one to its disk.

- `ssh` provider: ~/.ssh as a value bag. Files are picked by sniffing
  contents (PRIVATE KEY blocks, ssh-*/ecdsa-*/sk-* public keys) plus
  config, config.d/* and allowed_signers. known_hosts and
  authorized_keys are host-specific and access-granting, so they need
  an explicit --include.
- Each file is one secret carrying a JSON envelope of path, mode and
  body. The engine only hands write() the secrets that CHANGED, so a
  separate manifest secret would be absent whenever a key's contents
  change but the file list doesn't — self-describing values keep every
  restore total.
- `logicsrc secrets ssh push|pull|list|agent`, addressed by PERSON not
  project: the vault is ssh--<username>, which teams vaults reads as
  project ssh, env <username>. One teammate's keys never land in
  another's restore; sharing stays a deliberate teams grant.
- Both directions hold back anything that would overwrite a file that
  already differs, and say what they skipped. --force opts in. A
  restore onto a machine with its own keys is otherwise a way to lose
  them.
- Restores chmod each file back to its recorded mode; writeFileSync's
  mode applies only on create, so an existing world-readable key would
  otherwise stay world-readable. The adapter declares delete:false.
- push warns about passphrase-less private keys before they go up.

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

* Add worked examples to secrets and secrets ssh help

Commander's usage line shows only the first alias, so `logicsrc secrets`
— the spelling people actually type — was invisible in its own help.
The examples carry it, alongside the flows worth copying: link/up/down,
the ssh backup round trip, and a plan → dry-run → approve sync.

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

* Advertise the ssh provider on the marketing page

The marketing-drift contract failed the build because `ssh` shipped in the
provider registry with no entry in MARKETING_PROOF -- which is the test
working: it exists so a provider cannot ship while the pages people
actually land on still describe the tool without it.

The proof regex is `/~\/\.ssh|SSH key/` rather than a bare `/SSH/` on
purpose. The provider grid renders every registry `name`, and this one is
"Local SSH directory", so `/SSH/` would already be satisfied by the
generated grid and the provider could ship with no copy written about it
at all -- passing the test while failing its intent. Requiring the path or
the phrase means a human wrote a sentence.

That sentence is the new block in the credential-sharing band: ~/.ssh is a
directory of files whose permission bits are load-bearing, not a set of
KEY=VALUE lines, which is the part that makes this provider different from
the other six. README already named ~/.ssh keys, so it needed no change.

apps/logicsrc-web: 75/75 contract tests pass (was 74 passed, 1 failed).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 17:03:00 -07:00
3ab8a4b38b
Add the LogicSRC OpenContext specification (#132)
* Add the LogicSRC OpenContext specification

OpenContext is an open specification for durable, portable, permissioned,
provenance-aware context shared between humans and AI agents. It defines how
organizational knowledge is described, authorized, versioned, resolved,
audited, and handed between replaceable workers without losing institutional
state.

Follows the OpenPRD/OpenOntology pattern already in the repo: self-contained
JSON Schemas in @logicsrc/schemas, a reference implementation package, CLI
subcommands, docs, examples, and an OpenPRD record.

Schemas (8, all self-contained so a third party can fetch one file and
validate against it with no further resolution):
  manifest, object, bundle, role, provenance, decision, diagnostic,
  audit-event — registered in @logicsrc/validators and schemas:validate.

Reference implementation (@logicsrc/opencontext):
  loader with upward manifest discovery, the full resolution pipeline,
  authority/supersession, permissions, redaction, lifecycle, provenance,
  deterministic digests, doctor, search, graph, history/diff, guarded writes,
  audit events, and file/http/git/sqlite adapters.

CLI: all 15 specified commands, as a standalone `opencontext` binary and as
`logicsrc context`, sharing one implementation so the two cannot drift.

Design decisions worth noting:

- Supersession is declared, never inferred from version numbers. Inferring it
  would hide the governance failure it represents and make
  multiple-active-versions and duplicate-canonical impossible to detect.

- The bundle digest identifies the resolved context, not the moment it was
  computed, so generated_at/bundle_id/digest/as_of are excluded while objects,
  lifecycle states, exclusions and warnings are covered. That is what lets a
  decision record cite exactly the context that produced it.

- A role's own max_classification beats an inherited one, so a ceiling on a
  shared base role cannot silently cap a role deliberately granted more;
  requesting several roles at once still takes the lowest, so combining roles
  never escalates.

- Scope wildcards match whole dotted segments only. A trailing .* covers a
  subtree; an interior * matches exactly one segment. Substring matching here
  would be an access-control bug.

- --include narrows an existing scope and is applied after it, never merged
  into it, so a request can never widen what a role holds.

Verified: 226 tests across core primitives, permissions/redaction, the
resolution pipeline, security, the published conformance fixtures (13 valid,
35 invalid, 8 resolution scenarios), project behaviour, and the five shipped
examples — which are held to --strict and a 100% health score. Benchmarks meet
every published budget (resolve 1,000 objects in ~33ms against a 2s target).

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

* Point install docs at @logicsrc/opencontext; record the npm name collision

The unscoped `opencontext` name is already published on npm by an unrelated
third party (federicodeponte/opencontext, 2.0.0), so `npx opencontext` would
install a stranger's package. Docs now use `npx @logicsrc/opencontext`; the bin
stays named `opencontext` so the command reads as the PRD specifies once
installed.

Recorded in PRD 0003 as a blocker to resolve before any publication, along with
the fact that no @logicsrc spec package has ever been published, so there is no
existing release path to slot into.

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

* Advance the logicsrc-mcp next-PRD-id assertion to 0004

standards.test.ts asserts prd_next_id against the live prd/ directory, so
adding PRD 0003 makes the next free id 0004. The test's own comment
anticipates this: "advances with every PRD added".

Caught by CI, not locally — the earlier verification ran per-package tests for
the packages this branch touches, and logicsrc-mcp is coupled to the PRD
directory without importing from it.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 11:46:11 -07:00
12a1d7f479
feat(credentials): link directories to team secrets (#129) 2026-08-04 17:17:04 -07:00
36236eb1a3
fix(credentials): one vault per user, in the config dir (#119)
The credential store resolved its base directory against process.cwd().
Running the CLI from inside a git checkout wrote `.logicsrc/credentials`
into that repo's working tree — a directory containing `vault/`, the one
place raw credential values touch disk — untracked, unignored, and one
`git add -A` from being committed. Two such directories were sitting in
unrelated repos on the machine this was found on.

A per-directory store is also the wrong shape for what the store is for.
It is the record of what was rotated and what the prior values were, and
a record that forks per project folder is several records that disagree.
There is one user, one identity, one vault.

Everything now hangs off a single logicsrcHome(): $LOGICSRC_HOME, else
$XDG_CONFIG_HOME/logicsrc, else ~/.config/logicsrc. The credential store,
the identity and the CLI config all read it rather than each deriving
their own answer — three separate derivations is how the vault ended up
somewhere the config never was.

~/.logicsrc is migrated rather than abandoned. It holds the X25519 secret
key, and losing that loses access to every team vault the member was ever
given, so it is moved on first use; a move that fails says so on stderr
instead of leaving someone silently logged out with a key still on disk
somewhere they were not told about. If the new directory already exists
it wins and the old one is left untouched, because two directories both
claiming to be the identity is how a login writes one and a read finds
the other.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 22:53:17 -07:00
6f23dbdb0f
feat(credentials): re-key team vaults, and reach sh1pt's vault as a provider (#117)
Two additions to Credential Sharing.

`logicsrc credentials rotate` (alias `logicsrc secrets rotate`) re-keys a
team vault: fresh DEK, re-sealed to the members who keep access, every
secret re-encrypted under it. Values do not change, so nothing that
consumes them breaks; what changes is that every wrapped key issued
before the rotation is dead. --active (the default) keeps only active
members and revokes the rest -- the "someone left" rotation. --all keeps
everyone who holds access, for plain hygiene. Dry run by default, like
`sync`.

The DEK is recoverable ONLY through the grants, so a half-applied
rotation makes a vault permanently unreadable by everyone. The whole next
state therefore goes to the server in one request and commits in one
transaction (new db.batch helper). The server also requires every
submitted fingerprint to equal the stored one: it cannot see values, but
it can prove a re-key did not swap any. Rotations that would leave the
caller ungranted, grant nobody, or cover the wrong secret count are
rejected before anything is written. GET /vaults/:id/grants now returns
publicKey and status so a client can re-seal in one pass instead of N+1
user lookups, and revocation finally deletes the grant row rather than
leaving one that reports access it no longer confers.

The sh1pt adapter is the fifth provider. It is the only one driven
through a CLI rather than HTTP, because sh1pt publishes
`sh1pt secret set|get|list|rm` as the interface to its vault and
documents no REST endpoint. Values go over the child's stdin, never argv
-- a secret in argv is readable by any user on the host via ps. Since
`sh1pt secret get` needs interactive confirmation it cannot be scripted,
so the adapter is write-only for values like github-secrets: a sync
target, never a source, no value-restoring rollback.

Tests drive a real fake sh1pt binary rather than a mocked execFile, which
is how the hang surfaced: with nothing to pipe, stdin was left open and
any subcommand that reads it would wait forever. It is now always closed.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 18:41:03 -07:00
bb09c145cd
fix(cli): vault names join with "--", not "/" — the server rejects slashes (#112)
#109 addressed vaults as <project>/<env> and shipped broken: every push
failed with

    Vault name must be lowercase letters, numbers, and dashes.

The vault-create endpoint slugifies through /^[a-z0-9][a-z0-9-]{0,62}$/
(apps/pwa/src/routes/credshare.mjs), so a "/" join is refused outright.
Nothing in the CLI ever saw it, because the tests exercised vaultName and
splitVaultName in isolation and never made a request — the one assumption
that mattered, that the server takes an arbitrary vault name, was the one
left unverified.

Switches the separator to "--", which is inside the allowed character set
and still splits unambiguously since neither half may contain one. A
single dash would not: "a-b" + "c" and "a" + "b-c" would collide.

Also validates the joined name against the server's own regex before the
request, so a bad name fails locally with a useful message rather than a
422 after the .env has been read.

The tests now assert the produced name matches that regex, so the
separator cannot drift back out of the allowed set without failing.

Verified end to end against app.logicsrc.com: push, then pull into a
scratch file and diff — keys and values both round-trip losslessly. Then
49 repos pushed under the profullstack team; server reports 49 vaults,
169 secrets, 0 failures.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 13:32:07 -07:00
ca182bc057
feat(cli): address team vaults as <project> <env> (#109)
`teams push|pull|grant` took a single `<vault>` name, so a team holding
more than one project had to encode both halves by hand and hope
everyone spelled it the same way. They now take `<project> <env>` and
join them into the `project/env` vault name.

The split lives entirely in the CLI — vaultName()/splitVaultName() are
the only things that know about it, and the server still stores one
opaque vault name — so there's no migration. Both halves reject a "/"
so the join stays unambiguous and the split is a true inverse.

`teams vaults` now breaks the name back into project/env columns,
falling back to the raw name for vaults created before the convention.
Those legacy vaults are no longer addressable (their names don't
contain a slash), so resolveVaultId() lists what the team actually has
instead of just saying "not found" — better than silently retargeting a
push, which in a secrets tool would write to the wrong vault.

Note push/pull carry two different "env"s: the `<env>` positional is
the environment half of the address, `--env` is the local .env path.
Verified commander keeps them separate.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 11:39:22 -07:00
cf475f0f4c fix(cli): point logicsrc login at the real app + add device-code login
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
`logicsrc login` defaulted to http://localhost:4010 — a dev origin that
doesn't exist on an installed machine, so the printed authorize URL went
nowhere. It now defaults to the hosted credentials app (apps/pwa), reads
the documented $LOGICSRC_API, and only reuses a stored apiUrl once that
identity has actually completed a login (which is how machines got stuck
pointing at localhost). Note logicsrc.com is the marketing site and has
no /cli routes.

The loopback flow is also unusable over SSH: redirect_uri is
http://127.0.0.1:<port>/callback, which resolves to the *browser's*
machine, not the CLI's. Added a device-authorization flow — the CLI
prints a short user_code, the human approves it from any browser:

  POST /cli/device/code   mint device_code + user_code (10 min TTL)
  GET  /cli/device        approve page (login required; typo-tolerant)
  POST /cli/device        approve/deny (CSRF-guarded browser form)
  POST /cli/device/token  CLI polls -> lsk_ API key

device_code is stored sha256-hashed, single-use, with authorization_pending
/ slow_down / access_denied / expired_token poll semantics. The CLI picks
the flow automatically (SSH/CI/no-DISPLAY -> device), with --device/--web
to force it and a fallback to loopback against servers without /cli/device.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 18:07:49 +00:00
da5f6f8381
feat(openontology): Phase 2 + Phase 3 — storage, REST/SSE, MCP, RDF/SHACL, adapters, TUI, explorer (#101)
Some checks are pending
CI / build (push) Waiting to run
test / test (push) Waiting to run
Everything the two shipped PRD phases deferred, minus what is called out below.

Storage (Phase 2)
  @logicsrc/openontology gains a SQLite/Turso adapter. It hydrates the read
  model at open, serves reads synchronously — a query evaluator that awaits per
  triple pattern is unusable — and buffers mutations as SQL that flush() writes
  in one transaction. Versioned idempotent migrations; indexes over subject,
  predicate, entity-valued object, status, both time axes, aliases, and external
  ids; FTS5 for label/alias search. The append-only status log is replayed on
  open, so retractions, supersessions, and merge redirects survive a reopen.

REST + SSE + OpenAPI (Phase 2)
  16 paths under /api/ontologies in logicsrc-web, described at
  /api/ontologies/openapi and referencing the published JSON Schemas rather
  than restating them. No token is read-only; a curator token can apply; an
  agent token can propose and cannot apply. Idempotency-Key on mutations,
  revision ETags, 409 on a stale base revision, and an SSE stream that emits
  the same event objects as the JSON endpoint.

MCP (Phase 2)
  OpenOntology and OpenPRD surfaces on the standards server: spec/manifest/
  schema/queries and PRD spec/index as resources, 11 ontology tools and 6 PRD
  tools, 7 prompts. Read-only by default; OPENONTOLOGY_MCP_WRITABLE=1 buys
  proposals, never applies — the denial is the shared policy layer, not a
  second rule that could drift.

Interoperability (Phase 3)
  RDF/Turtle export and import of the reified profile, plus the plain triple
  for asserted relationships so a consumer wanting only the accepted graph gets
  one. SHACL for 5 of 7 constraint kinds; `unique` and `query` are reported as
  unmapped in both the return value and the generated Turtle, because a shape
  that quietly means something narrower is worse than no shape.

Source adapters (Phase 3)
  CSV, JSON, YAML, NDJSON, Markdown, generic JSON HTTP, and GitHub. All produce
  PROPOSED change-set operations with source, evidence selector, run id, and
  confidence attached; fetch is injected so ingestion is offline and testable.
  Each declares its capabilities, so "nothing was deleted upstream" is never
  confused with "this adapter cannot see deletions" — none of the seven can.

TUI + explorer
  Keyboard-first panels (types, entities, claims, sources, queries, change
  sets, validation, audit) as plain strings that survive SSH and 60 columns;
  status is a glyph and a word, never colour alone; the key bar wraps rather
  than truncating. Wired as `logicsrc ontology tui`. A read-only web explorer
  at /openontology/explore with entity and claim views showing status, both
  clocks, confidence, sources, evidence, and append-only history — plus an
  /openprd page for the companion standard.

Bugs found and fixed while testing
  - the API built a new engine per request, so `explain` could never find a
    resultId from a prior request; engines are now cached per role
  - the TUI status bar called engine.validateOntologyPackage(), appending a
    package.validated event on every repaint; it now uses the pure validator

Verification: 76 new tests (527 total across the monorepo, all passing); full
build green; the libSQL adapter is exercised against real files, the API
through its route handlers, and MCP over an in-memory transport.

Not included: PWA review/approval write flows (they need an auth story this
deployment does not have), OWL/RDFS mappings, SPARQL/Cypher/Datalog query
adapters, and Phase 4 governed actions. The compatibility matrix marks those
"planned", not "supported".

Refs: prd/0001-add-logicsrc-openontology-spec.md

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 05:10:33 -07:00
296775e003
feat(openprd): implement the OpenPRD standard — engine, CLI, conformance bundle (#100)
OpenPRD has existed as a document (docs/openprd.md), a front-matter schema, a
template, and this repo's prd/ collection. Nothing enforced it. This adds the
reference implementation.

@logicsrc/openprd
  - parser: front-matter + the eight `##` sections + numbered requirements.
    `###` stays content so a long Requirements section can be organized, and
    headings or R#-shaped lines inside code fences are ignored
  - validation splits the standard's four conformance rules (filename,
    front-matter schema, id-matches-prefix, eight sections in order) from
    lint (empty section, missing priority tag, numbering gaps, duplicate R#,
    date order, one-sided supersession, stale index). Conformance failures are
    errors; --strict promotes the rest. Stable codes, file, line, hint
  - collection rules the per-file view cannot see: unique ids, monotonic
    numbering with no gaps, 0000 reserved for the template, cross-references
    that resolve
  - lifecycle enforced rather than advisory: Draft cannot jump to Final,
    terminal statuses do not resume, Superseded must name its replacement
  - deterministic index generation, so `prd index` is idempotent and CI can
    diff it
  - front-matter rewriting that leaves the body byte-identical
  - the optional LogicSRC task bridge the standard describes: each R# becomes
    one logicsrc.task, validated against logicsrc-task.schema.json before it
    is emitted; creator DID derived from the author email

CLI: logicsrc prd init|new|list|show|validate|lint|index|status|next|tasks|
export. Exit codes stable for CI (0 ok, 1 invalid, 2 usage, 3 not found).

Conformance bundle: packages/schemas/fixtures/openprd/ — 6 documents that must
validate and 12 that must fail, each naming the error code it must produce.
Several rules depend on the filename, so every fixture records the name it is
validated as.

Docs: an Implementation section in docs/openprd.md (CLI, validation model,
task bridge, conformance bundle), the spec added to the site's docs surface,
nav and sitemap entries, and a README section.

Verification: 76 new tests; full monorepo build and all 451 workspace tests
pass. The suite dogfoods this repo — prd/ validates with zero errors and zero
warnings, the embedded template is byte-identical to docs/openprd/0000-
template.md, and all 210 requirements in PRD 0001 map to schema-valid tasks.
prd/README.md is regenerated by the tool it now ships.

Refs: docs/openprd.md

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 04:11:07 -07:00
58c942c67f
feat(openontology): implement OpenOntology Phase 0 + local engine and CLI (#99)
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
Implements OpenPRD 0001 through Phase 0 (specification, schemas, example,
docs surface) and Phase 1 (local engine, CLI, conformance tests).

Schemas (17 contracts, JSON Schema Draft 2020-12, additionalProperties:false)
  manifest, namespace, entity-type, property, relationship-type, constraint,
  query, action, entity, claim, source, evidence, changeset, review, approval,
  event, package — registered in @logicsrc/validators and exported from
  @logicsrc/schemas under https://logicsrc.com/schemas/openontology/.

@logicsrc/openontology
  - canonical JSON + sha256 package digests; YAML, JSON, NDJSON, and inline
    authoring all compile to the same bytes, so digests are authoring-agnostic
  - id profile: compact / IRI / urn with one canonicalization rule, prefix
    bound by a Namespace object so IRIs reverse unambiguously
  - validation: schema, graph (domain/range, datatypes, dangling refs),
    provenance (source-or-firstParty, agent runId, derivation inputs), policy
    (excerpt limits, licensing, visibility, staleness) and declared
    constraints; four severities, stable codes, text/json/yaml/markdown
  - portable triple-pattern query AST: multi-hop, 14 operators, asOf and
    recordedAsOf, per-status filtering, distinct/order/limit, explanation
    mode, and enforced depth/binding/row limits
  - append-only store: claims are immutable; dispute/retract/supersede append
    status transitions and the effective status is the latest one
  - change sets: 9 operations, atomic pre-flight, conflict detection on stale
    base revisions, semantic diff with duplicate-identity warnings and
    affected-query deltas, per-operation reviewer decisions
  - policy: agents propose but can never apply — the denial keys on actor
    type, so every scope plus high confidence plus --yolo still cannot apply;
    merges need approval, bulk retractions need two, undeclared action side
    effects are denied
  - JSON-LD 1.1 export/import with PROV-O aliases and lossy-field reporting
  - pluggable signature envelope with a jws-ed25519 reference profile and a
    fail-closed trust policy

CLI: logicsrc ontology init|validate|lint|build|inspect, entity, claim, query,
changeset, import, export, audit. Reads take --format, writes default to a
proposal, exit codes are stable for CI.

Example: examples/openontology/ethereum-ecosystem — 12 entity types, 17
relationship types, 63 entities, 169 claims, 25 sources, 31 evidence records,
5 saved queries, every claim lifecycle state, and a pending merge proposal.
All data is fictional; the directory is removable without affecting any core
test.

Docs: docs/openontology{,-governance,-interoperability}.md, a real
/openontology route, homepage + nav + sitemap entries, and a root README
section.

Verification: 112 new tests; full monorepo build and every workspace test
pass; conformance bundle (18 valid + 13 invalid fixtures) runs against the
published schemas alone; Node.js 25 and Bun 1.3 produce byte-identical
digests, revisions, event trails, and query results.

Not included (later PRD phases): MCP resources, REST/SSE, Turso adapter, TUI
and PWA surfaces, RDF/SHACL mappings, source adapters, governed actions.

Refs: prd/0001-add-logicsrc-openontology-spec.md

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 02:10:13 -07:00
f057589d66 feat(credential-sharing): end-to-end-encrypted team credential sharing
Adds a `team` credential provider + team/member management so teammates can
share secrets by email instead of passing .env files over chat. Fully E2E:
the server only ever stores ciphertext, per-member sealed vault keys, and
public keys — it never sees a plaintext value or the vault DEK.

Plugin (@logicsrc/plugin-credential-sharing)
- crypto.ts: X25519 identity keys, per-vault DEK (secretbox), DEK sealed to
  each member's pubkey (crypto_box_seal), value encrypt/decrypt (libsodium)
- identity.ts: local ~/.logicsrc/identity.json (0600) holding the device key
  + API token; never uploads the secret key
- client.ts: typed /api/credshare client
- providers/team.ts: `team:<slug>/<vault>` CredentialProvider (inspect,
  readValues=decrypt, write=encrypt, rollback); fingerprints match env so
  env<->team diffs line up
- fixes latent libsodium-wrappers ESM load bug (createRequire) here + in
  github-secrets

Server (commandboard-api /api/credshare)
- zero-knowledge router: email-code auth, keys, teams, members, invites,
  vaults, sealed grants, ciphertext secrets, audit; membership authz in app
- CredShareStore abstraction: in-memory (dev/tests) + Supabase (prod)
- Resend email transport for login codes + invites (no-op -> echoes locally)
- supabase migration: credshare_* tables, deny-by-default RLS

CLI
- real `logicsrc login` (email code -> token + key upload)
- `logicsrc teams create/list/invite/accept/members/vaults/grant/push/pull`

Web (logicsrc.com/teams + /teams/accept)
- management surface only (browser holds no private key, never decrypts):
  login, view teams/members/vaults, invite, accept

Tests: crypto round-trip, server contract (invite->accept->push->grant->pull
+ authz boundaries), and a real HTTP+client+crypto E2E asserting the server
never holds plaintext. Full workspace build + tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 13:11:32 +00:00
756c3f6f21
feat(openprd): revise standard to DIP-style numbered proposals (0.2) (#96)
Reshape OpenPRD from a private single-file (prd/<slug>/prd.md, gitignored) into a
published, numbered proposal collection like BIP/EIP/DIP: prd/NNNN-slug.md +
0000-template.md + a README index, committed to the repo, with a lifecycle
(Draft → Review → Accepted → Final; Rejected/Withdrawn/Superseded).

Tools (e.g. moshcode /prd) consume this to publish PRDs into whatever repo the
user is working in.

- docs/openprd.md — rewritten: numbering, lifecycle, directory layout, conformance.
- docs/openprd/0000-template.md — the canonical template.
- packages/schemas/schemas/openprd-prd.schema.json — 4-digit id, status enum,
  authors, discussion/implementation, supersedes/superseded-by.
- fixture updated to 0.2.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 08:55:19 -07:00
506c001151
feat(openprd): publish the OpenPRD standard (#95)
OpenPRD is a lightweight, single-file PRD standard (prd/<slug>/prd.md) for
humans and AI agents — the low-ceremony counterpart to OpenSpec's multi-file
change bundles. PRD documents are private by convention; only the standard is
published here.

- docs/openprd.md — the standard: file layout, front-matter, the 8 required
  body sections, privacy, and the optional bridge to LogicSRC tasks.
- packages/schemas/schemas/openprd-prd.schema.json — front-matter manifest schema.
- packages/schemas/fixtures/openprd-prd.yaml — a valid manifest fixture.
- packages/validators — register the openprd-prd schema.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 08:06:59 -07:00
7d62e3b661 feat(agentad): AgentAd Marketplace PRD + reference exchange (M5)
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
Add the AgentBBS M5 "AgentAd marketplace" spec and a working reference
implementation built on the existing @logicsrc/schemas AgentAd contracts.

- docs/agentad-marketplace.md: two-sided exchange PRD (buy/sell sides,
  match -> auction -> pace -> serve -> meter -> settle, CoinPay settlement,
  AgentBBS as reference publisher, milestones M5.0-M5.5).
- packages/agentad (@logicsrc/agentad): reference exchange
  - builders that emit schema-valid, always-disclosed ad/campaign/placement docs
  - HMAC-signed, single-use impression/click tracking tokens
  - AgentAdExchange: targeting/format/category matching, second-price auction,
    budget pacing + daily caps, frequency capping, token-driven metering
  - pluggable settlement (InMemorySettlement) that can't overspend escrow
  - runtime validation against the canonical agentad-*.schema.json
- 22 vitest cases (builders, tokens, full serve/meter/settle lifecycle).
- Wire package into root build; link the PRD from README + docs/agentad.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 10:29:36 +00:00
cf73fe5af2 feat(credential-sharing): implement the Credential Sharing OpenSpec (M1-M3)
New @logicsrc/plugin-credential-sharing: a provider-neutral secret-sync engine
with env/.env, Doppler, Railway, and GitHub Secrets adapters behind one
CredentialProvider contract.

- engine: inspect -> diff -> plan -> approve -> sync -> rollback -> audit/export
- dry-run is the default for sync; --approve writes; destructive changes gated
- fingerprint-based diffs (salted SHA-256); raw values never printed or stored in
  plans/runs/audit; rollback pre-image kept in a 0600 .logicsrc vault (gitignored)
- github-secrets is write-only for values (sealed-box via libsodium), so it cannot
  be a sync source or value-restoring rollback target
- CLI: real `logicsrc credentials <providers|inspect|diff|plan|approve|sync|
  rollback|audit|export>` (replaces the prior stub)
- 4 JSON schemas registered in @logicsrc/validators
- flip logicsrc.com/credential-sharing band from coming-soon to available
- 37 tests pass; full env->env lifecycle verified; artifacts schema-validate

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 15:24:30 +00:00
0ae24719e3 docs(ans): spec the @logicsrc/ans TypeScript SDK
Design doc for the LogicSRC TS SDK for the Agent Name Service (ANS): resolver +
offline transparency-log verifier + registration client + coinpay-DID bridge.
Covers scope, package layout, full API surface, the ans-verify algorithm,
milestones (M1 verifier -> M2 register -> M3 DID bridge), and risks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 14:41:00 +00:00
bf046ae280 Add AgentGit M1: agent-native git layer over a Forgejo backend
AgentGit is a thin, DID-gated source-collaboration layer over a backend
forge (default Forgejo at git.profullstack.com, BBS-members-only) — not a
new git host. M1 implements the contract and engines:

- forge/adapter.ts: ForgeAdapter interface (only forge-specific surface)
- forge/forgejo.ts: ForgejoAdapter over Forgejo/Gitea REST v1 (injectable
  fetch, typed errors), incl. ensureUser for member provisioning
- access.ts: gateAccess DID membership gate (owner/role/visibility)
- merge-policy.ts: evaluateMergePolicy pure engine (reviews, reputation
  floor, checks, escrow, merge method, agent-merge toggle)
- service.ts: AgentGitService ties gate + policy to the adapter; refuses
  policy-failing merges; provisionMember hook for AgentBBS
- schemas: logicsrc-repo + logicsrc-pull-request, registered in
  @logicsrc/validators with fixtures
- docs/agentgit.md spec; plugin wired into root build (default/disabled)

27 vitest tests pass; full monorepo build green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 15:15:06 +00:00
7cda686059
Add AgentAd ad schemas as a LogicSRC primitive (#10)
* Add AgentAd ad schemas as a LogicSRC primitive

AgentAd is a disclosed, agent-readable advertising contract for CLI tools
and AI agents. LogicSRC owns the canonical schemas; cl1s.tech is the
reference network built on them.

- packages/schemas: agentad-{ad,placement,ad-request,ad-response,
  impression,click,campaign} schemas (id under schemas.logicsrc.com) +
  ad/placement fixtures, exported from @logicsrc/schemas
- packages/validators: register the 7 agentad kinds, wire fixture
  validation, add tests (disclosure.sponsored must be true)
- docs/agentad.md: the AgentAd spec
- README: list AgentAd under v1 priorities

Validators build clean; all fixtures validate; vitest 4/4 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Prepare @logicsrc/schemas for npm publish

Add license, repository, homepage, keywords, publishConfig (public),
and a package README covering both the logicsrc-* core schemas and the
agentad-* family.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 21:02:43 -07:00
850cf5ea44
feat(agentstack): add @logicsrc/agentstack coordination module (#5)
* feat(agentstack): add @logicsrc/agentstack coordination module

AgentStack is the LogicSRC module for portable agent, task, payment, and
reputation coordination across Profullstack apps. Reference implementation of
the `agentstack` capability in the Profullstack Shared AppKit OpenSpec.

- packages/agentstack: DID helpers (did:coinpay:user/agent), DidTask model +
  lifecycle, AgentStack in-memory coordinator (agents, tasks, delegation,
  events), and a validated LogicSRC plugin definition. 9 vitest cases.
- Wire @logicsrc/agentstack into the root build chain (after plugin-core).
- docs/agentstack.md + mention in openspec-comparison.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(agentstack): note dual-runtime support (Bun + Node.js + Workers + browser)

Matches the revised Shared AppKit PRD's Runtime Compatibility Strategy.
AgentStack is runtime-neutral (no Bun/Node-only APIs; time is injected).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 16:39:32 -07:00
c23ce42948 Add communication account plugin scaffolds 2026-06-09 10:02:07 +00:00
4682b261c0 Add waiting arcade MVP 2026-06-06 22:09:22 +00:00
b1d8fe475a feat: add c0mpute plugin and hire-us request flow 2026-06-06 19:42:00 +00:00
a0314eb774 Add credential sharing openspec 2026-06-06 18:47:41 +00:00
17942eef57 Implement OpenSpec artifacts and SDK contracts 2026-06-06 16:44:58 +00:00
1aa67367b8 Add OpenSpec comparison and compatibility mode 2026-06-06 16:27:51 +00:00
3b3d7ec09a Add LogicSRC CLI and AgentSwarm surfaces 2026-06-06 16:09:23 +00:00
cfac40ebe4 Add AgentByte screening plugin spec 2026-06-06 15:54:08 +00:00
5c9ea821f6 Scaffold LogicSRC and CommandBoard plugins 2026-06-06 11:24:02 +00:00