Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- name: Ensure an OIDC-capable npm CLI
run: npm install --global npm@^11.5.1
- run: pnpm install --frozen-lockfile
Expand All @@ -80,9 +79,6 @@ jobs:
create-github-releases: true
push-git-tags: true
env:
# A granular automation token is needed only to bootstrap package creation. Once each
# package trusts this workflow, npm uses the GitHub OIDC token instead.
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: "true"

canary:
Expand All @@ -99,13 +95,11 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- name: Ensure an OIDC-capable npm CLI
run: npm install --global npm@^11.5.1
- run: pnpm install --frozen-lockfile
- run: pnpm check
- run: pnpm test:postgres:integration
- run: pnpm release:canary
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: "true"
17 changes: 7 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,15 @@ All packages are ESM-only. Public exports must point to generated files under `d
package change must continue to pass `pnpm pack:check` so source files, tests, caches, and local
dependencies never leak into npm tarballs.

Add a Changeset for a publishable package change. Packages are not yet published, so the first
release must also validate a registry-only canary in a clean external consumer and retain the
existing PostgreSQL integration gate in CI. Current maturity and release gates live in
Add a Changeset for a publishable package change. Release checks include a packed external consumer
and the PostgreSQL integration gate in CI. Current maturity and release gates live in
[`docs/current-state.md`](docs/current-state.md).

The first npm release needs a short-lived granular npm token with read/write publish access to the
`@triplex-build` scope and bypass 2FA enabled for unattended publishing. Organization-management
access is not needed. Add it as the `NPM_TOKEN` secret on the `npm-publish` GitHub environment before
approving the release job. After the packages exist, configure a trusted publisher on each npm
package for GitHub owner `bjacobso`, repository `triplex`, workflow `release.yml`, and environment
`npm-publish`, with direct publishing allowed. Then remove the bootstrap token. The workflow already
grants `id-token: write` and uses an OIDC-capable npm CLI for subsequent releases.
The seven public packages were bootstrapped with a short-lived npm token. Subsequent releases use
npm trusted publishing from GitHub owner `bjacobso`, repository `triplex`, workflow `release.yml`,
and the approval-protected `npm-publish` environment. Each package needs its own trusted publisher
connection with direct publishing allowed. The workflow grants `id-token: write` and uses an
OIDC-capable npm CLI.

Keep private packages out of Changeset frontmatter. Changesets cannot version a public release
when a Changeset mixes private and publishable packages.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
# Triplex

> [!WARNING]
> Triplex is pre-1.0. The new `@triplex-build` packages are not yet published; use a source checkout
> for evaluation. The current tree requires `effect@4.0.0-rc.112`; Effect 3 is not compatible. KV
> Triplex is pre-1.0. The published `@triplex-build` packages require `effect@4.0.0-rc.112`;
> Effect 3 is not compatible. KV
> and SQLite are the supported baseline, PostgreSQL is a production candidate, and Cloudflare and
> FoundationDB are experimental. See [Current state](docs/current-state.md) for the exact maturity
> contract.
Expand Down Expand Up @@ -67,8 +67,13 @@ and never ask about history or provenance. Triplex is a system of record, not a

## Installation and evaluation

As of September 10, 2026, npm returns `404` for the new `@triplex-build` package family. Run the
checked examples from a source checkout until the first release gates are complete:
Install the core package and its Effect peer dependency from npm:

```sh
npm install @triplex-build/triplex effect@4.0.0-rc.112
```

To run the checked repository examples from a source checkout:

```sh
git clone https://github.com/bjacobso/triplex.git
Expand Down
2 changes: 1 addition & 1 deletion docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default {
h(DefaultTheme.Layout, null, {
"layout-top": () =>
h("div", { class: "triplex-prerelease", role: "status" }, [
"Pre-1.0 · new npm scope not published yet · use source checkout · ",
"Pre-1.0 · seven public packages available on npm · ",
h("a", { href: "/current-state" }, "current state"),
]),
}),
Expand Down
20 changes: 7 additions & 13 deletions docs/current-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,9 @@ outside the normal test matrix.

## Honest limitations

- The seven public packages are prepared for coordinated publication under the `@triplex-build`
organization scope, but no package under that scope is available from npm yet. Stable `0.1.0` has
not been published. The GitHub repository is `bjacobso/triplex`, and the local `origin` uses that
canonical URL.
- Seven public packages are published under the `@triplex-build` organization scope. The GitHub
repository is `bjacobso/triplex`.
- The superseded `@bjacobso` bootstrap packages are not the installation path for new consumers.
Evaluation uses a current source checkout until the scoped package bootstrap and registry checks
pass.
- `SubscriptionManager` discovers dependencies and reports possible invalidations. It does not
push result deltas or automatically re-run queries.
- Entity snapshots, validation results, and derivation materializations are projections. Callers
Expand All @@ -123,14 +119,12 @@ outside the normal test matrix.
restore, provider limit measurements, staged migration/rollout drills, credentialed Alchemy
reconciliation, and lost-acknowledgement/node-failure exercises remain explicit gates.

## First-release gates
## Release follow-up

1. Bootstrap the `@triplex-build` package records, configure npm trusted publishing, and verify a
registry-only `next` consumer for the whole coordinated package family.
2. Review and version pending Changesets against the release set. The initial version PR has
merged, and the public manifests are already `0.1.0`; that does not mean they are published.
3. Publish the scoped stable packages together and verify their peer dependency, provenance, CLI,
and exports behavior from the registry.
1. Configure npm trusted publishing for all seven packages and verify a tokenless `next` publish.
2. Verify the published packages in a clean registry-only consumer, including peer dependencies,
provenance, CLI, and exports.
3. Deprecate the superseded `@bjacobso` canaries with migration guidance.

Cloudflare and FoundationDB are private for the first release. Their source stays in the monorepo
and continues to compile, but Changesets cannot publish them accidentally.
Expand Down
24 changes: 15 additions & 9 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# Getting started

This guide writes three facts to an in-memory Triplex database, joins them with Datalog, and prints
the result. It is the shortest complete path from a source checkout to a running program.
the result. It is the shortest complete path to a running program.

::: warning Package availability
As of September 10, 2026, the new `@triplex-build` packages are **not yet available from npm**.
The registry returns `404` for the core, SQLite, and CLI packages. Use the source-checkout path
below until the [first release gates](/current-state#first-release-gates) are complete. Do not use
the superseded `@bjacobso` package names for new work.
::: warning Pre-1.0 packages
The `@triplex-build` packages are available from npm and require `effect@4.0.0-rc.112`.
Effect 3 is incompatible. Do not use the superseded `@bjacobso` package names for new work.
:::

## Prerequisites
Expand All @@ -16,6 +14,12 @@ the superseded `@bjacobso` package names for new work.
- Node.js 22 or newer
- Corepack and pnpm 10.11.0 (the repository declares the exact package-manager version)

For an application, install the published core package and its Effect peer dependency:

```sh
npm install @triplex-build/triplex effect@4.0.0-rc.112
```

## Run the example

Clone the repository and install its locked dependencies:
Expand Down Expand Up @@ -77,9 +81,11 @@ work that intentionally needs the complete result set.

## Use durable SQLite

SQLite is the supported local persistent backend. Once the scoped packages are published, a
registry consumer will install the exact compatible releases of core, SQLite, and Effect. Until
then, use them from this workspace checkout.
SQLite is the supported local persistent backend. Install it alongside core and Effect:

```sh
npm install @triplex-build/triplex-sqlite
```

Replace the in-memory layer with a file-backed layer:

Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ pageClass: triplex-index
---

::: warning Pre-1.0 release candidate
The new `@triplex-build` packages are not yet published. Run Triplex from a source checkout; the
current tree requires `effect@4.0.0-rc.112`, and Effect 3 is not compatible. KV and SQLite are the
The seven public `@triplex-build` packages are available from npm. They require
`effect@4.0.0-rc.112`; Effect 3 is not compatible. KV and SQLite are the
supported baseline; PostgreSQL is a production candidate, while Cloudflare and FoundationDB are
experimental. [Read the exact maturity contract](/current-state).
:::
Expand Down
35 changes: 13 additions & 22 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ GitHub Actions; routine releases should not depend on a maintainer's local npm c

## Release set

The first public release contains:
The public release set contains:

- `@triplex-build/triplex`
- `@triplex-build/triplex-sql`
Expand All @@ -19,9 +19,8 @@ The first public release contains:
packages until they pass the supported backend conformance contract. The dashboard and examples
are also private.

The initial version PR has merged and the public manifests are `0.1.0`. Manifest versions are
not evidence of registry publication. Review pending Changesets and the coordinated release set
before publishing; subsequent versioning can advance those versions.
The first release published all seven packages in September 2026. Review pending Changesets and
the coordinated release set before each subsequent publication.

## Required repository configuration

Expand All @@ -30,8 +29,7 @@ Create a GitHub environment named `npm-publish` and require maintainer approval
Repository Actions settings must allow GitHub Actions to create pull requests so the version job
can maintain the release PR.

The release workflow uses npm trusted publishing. For each public package, configure this trusted
publisher after the package exists:
The release workflow uses npm trusted publishing. Each public package needs this trusted publisher:

| Field | Value |
| ----------- | ------------- |
Expand All @@ -45,30 +43,23 @@ Allow direct `npm publish` for this workflow. It runs on a GitHub-hosted runner

## One-time npm bootstrap

npm package settings do not exist until the package has first been created. The package family was
originally tested under the maintainer's scope using pre-stable canaries. The public package family
now uses the `@triplex-build` organization scope. Bootstrap that scope with a short-lived token,
then leave GitHub Actions OIDC as the only automation credential.
npm package settings do not exist until the package has first been created. The seven public
packages were bootstrapped under `@triplex-build` with a short-lived token. Routine releases use
GitHub Actions OIDC without an npm token.

For a new package added to the family, repeat the minimal bootstrap sequence:

1. Authenticate as an npm owner of the `@triplex-build` organization and confirm the new name is
available.
2. Create a granular token limited to the new package with publish access and the minimum useful
lifetime.
3. Store it as the `NPM_TOKEN` secret on the protected `npm-publish` GitHub environment.
4. Manually dispatch the **Release** workflow. The canary job publishes snapshot versions under
the `next` dist-tag and does not create or push Git tags.
5. Configure the trusted publisher above for every package.
6. Delete `NPM_TOKEN`, revoke the bootstrap token, and leave OIDC as the only automation
credential.
lifetime. Temporarily add token authentication to the protected release job for its first publish.
3. Publish its first version under the `next` dist-tag and verify the package record exists.
4. Configure its trusted publisher using the values above.
5. Remove the temporary token authentication, delete its GitHub secret, and revoke the token.
6. Verify the next publish uses OIDC.

Do not put an npm token in the repository, a shell command, or a checked-in `.npmrc`.

The new scope currently has no published package records. During bootstrap, verify which dist-tags
npm assigns and keep consumer checks on explicit `@next` versions until stable `0.1.0` is released;
do not assume the registry state in documentation before checking it.

The six pre-stable packages under `@bjacobso` are a superseded bootstrap line. After the
`@triplex-build` stable release is available, deprecate every old version with a message directing
consumers to its corresponding `@triplex-build` package. Do not unpublish the old artifacts.
Expand Down Expand Up @@ -106,7 +97,7 @@ share the `triplex` stack's `prod` state. Secrets Store Edit is required to bind
secret when a fresh runner authenticates; Secrets Store Read alone is insufficient. See
[Cloudflare's Secrets Store permissions](https://developers.cloudflare.com/secrets-store/access-control/).

## Verify the canary after bootstrap
## Verify a canary

Install from the registry in a clean directory outside this monorepo:

Expand Down
9 changes: 4 additions & 5 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ host rows, Triplex facts/journal, and outbox writes can share one Effect SQL tra
- Delivered: Cloudflare and FoundationDB are private experimental workspace packages and cannot be
included in the first release accidentally.
- Delivered: the GitHub repository cutover to `bjacobso/triplex`.
- Delivered: the initial version PR; all seven public package manifests are now `0.1.0`.
- Remaining: bootstrap the `@triplex-build` package records, verify trusted publishing for all
seven public packages, and pass a registry-only `next` consumer before stable publication.
Earlier canary validation under the superseded maintainer scope does not establish availability
under the new scope. Review pending Changesets and verify the coordinated stable release.
- Delivered: the initial version PR and the first publication of all seven public packages under
`@triplex-build`.
- Remaining: verify trusted publishing for all seven public packages with a tokenless `next`
release and test the registry packages in a clean external consumer.

## Immediate correctness gate: backend parity

Expand Down
10 changes: 5 additions & 5 deletions docs/tools.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# CLI and dashboard

Triplex includes two operator tools in the repository: a JSON-first CLI for repeatable commands and
a browser dashboard for interactive exploration. Both are pre-1.0. The CLI package is not yet
available under the new npm scope, and the dashboard is a private workspace package rather than a
published application.
Triplex includes two operator tools: a published JSON-first CLI for repeatable commands and a
browser dashboard for interactive exploration. Both are pre-1.0. The dashboard is a private
workspace package rather than a published application.

## Build from the source checkout

Expand All @@ -15,7 +14,8 @@ pnpm turbo run build --filter=@triplex-build/triplex-cli...
triplex() { node --disable-warning=ExperimentalWarning packages/cli/dist/cli.js "$@"; }
```

The examples below use the repository command so they work before registry publication:
The examples below use the repository command. Install `@triplex-build/triplex-cli` from npm to
use the same `triplex` binary in an application:

```sh
triplex --sqlite ./app.db describe
Expand Down
11 changes: 5 additions & 6 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Troubleshooting and FAQ

## Why does npm return 404 for `@triplex-build/*`?
## Why does npm return 404 for a Triplex package?

The package namespace has moved to `@triplex-build`, but the new package family has not yet been
published. As of September 10, 2026, registry lookups for core, SQLite, and the CLI return `404`.
Use the [source-checkout quickstart](/getting-started) until the release gates are complete. Do not
switch new examples back to the superseded `@bjacobso` namespace.
The seven public packages use the `@triplex-build` scope. Check the full package name and clear a
stale local npm cache if a newly published version returns 404. Cloudflare and FoundationDB remain
private workspace packages. Do not switch new examples back to the superseded `@bjacobso` scope.

After publication, keep every Triplex package on one coordinated release and use the exact Effect
Keep every Triplex package on one coordinated release and use the exact Effect
peer version declared by that release. The current source tree targets Node.js 22+ and
`effect@4.0.0-rc.112`; Effect 3 is incompatible. Multiple Effect copies or an RC mismatch can make
service tags and runtime types disagree even when imports look correct.
Expand Down
Binary file modified e2e/docs-home.spec.ts-snapshots/home-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/docs-home.spec.ts-snapshots/home-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ triplex --sqlite ./app.db status
triplex --sqlite ./app.db entity types
```

The new `@triplex-build/triplex-cli` package is not yet published. Use the repository command above
from a source checkout. After publication, the installed binary will be `triplex`; the unscoped
Install `@triplex-build/triplex-cli` from npm to use the `triplex` binary. The repository command
above runs the same CLI from a source checkout. The unscoped
`triplex` package name on npm belongs to an unrelated project.

## Agent contract
Expand Down
11 changes: 5 additions & 6 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ and Effect services.

## Availability

The `@triplex-build` package family is not yet published. Evaluate this package from the repository
workspace with Node.js 22+, pnpm 10.11.0, and the locked `effect@4.0.0-rc.112` dependency. See the
[source-checkout quickstart](../../docs/getting-started.md). Do not use the superseded
Install `@triplex-build/triplex` from npm with Node.js 22+ and its `effect@4.0.0-rc.112` peer
dependency. See the [quickstart](../../docs/getting-started.md). Do not use the superseded
`@bjacobso` canaries for new work.

## In-memory store
Expand Down Expand Up @@ -126,11 +125,11 @@ clauses are rejected with typed errors.
domain-separated SHA-256 `ContentId` values. IDs use the format
`sha256-<64 lowercase hex characters>`.

The pre-1.0 entity-snapshot hash changed from `fnv1a:<8 hex characters>`. The unpublished
SQL schema now has one canonical baseline; databases from earlier development builds must
The pre-1.0 entity-snapshot hash changed from `fnv1a:<8 hex characters>`. The SQL schema now has
one canonical baseline; databases from earlier development builds must
be recreated or have their derived snapshots rebuilt from temporal triples.

See the repository [current-state document](../../docs/current-state.md) for backend maturity,
known limitations, and first-release gates.
known limitations, and release follow-up.

MIT © 2026 Ben Jacobson.
4 changes: 2 additions & 2 deletions packages/http/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# @triplex-build/triplex-http

> **Pre-1.0:** the `@triplex-build` packages are not yet published. Evaluate this workspace package
> from a source checkout with `effect@4.0.0-rc.112`; Effect 3 is not compatible.
> **Pre-1.0:** install `@triplex-build/triplex-http` from npm with `effect@4.0.0-rc.112`;
> Effect 3 is not compatible.

Configuration-derived REST and OpenAPI contracts for Triplex. The package is backend-neutral and
uses Effect services: hosts provide `Triples`, `ConfigStore`, and an authorization policy, then
Expand Down
4 changes: 2 additions & 2 deletions packages/postgres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

The PostgreSQL backend for Triplex, built on `@effect/sql-pg`.

The `@triplex-build` packages are not yet published. Evaluate this workspace package from a source
checkout. It requires Node.js 22 or newer and a PostgreSQL connection URL.
Install `@triplex-build/triplex-postgres` from npm. It requires Node.js 22 or newer and a
PostgreSQL connection URL.

```ts
import { PgTriples } from "@triplex-build/triplex-postgres";
Expand Down
Loading
Loading