* 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>
@logicsrc/opencontext could not be installed from npm. Three defects, each of
which alone breaks a published tarball:
1. opencontext depended on "@logicsrc/validators": "file:../validators". A
file: specifier is unresolvable for anyone installing from the registry, so
`npm install @logicsrc/opencontext` failed outright.
2. validators imported all 50 schemas by relative path across the repository
("../../schemas/schemas/*.json"). That resolves inside the monorepo and
escapes the package once published, so an installed validators could not
load a single schema. Now imported through @logicsrc/schemas package
exports, with a real dependency declared.
3. Three of those schemas — repo, pull-request, openprd-prd — had no entry in
the schemas exports map, so they were unreachable by package specifier.
Added; the map is now sorted so it stays readable as it grows.
validators also gained files/publishConfig/license so it publishes the same way
its siblings do.
Verified the way a stranger would: npm pack all three, install the tarballs
into a clean project outside the monorepo, and run the installed binary —
version, init, validate --strict (which exercises schema loading through the
package exports), and resolve --explain all succeed. Full workspace suite green.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* 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>
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>
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>
* 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>