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
44 changes: 41 additions & 3 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ on:
pull_request:
permissions:
contents: read
concurrency:
group: tally-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
verify:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '24'
- run: npm install --global pnpm@11.19.0
Expand Down Expand Up @@ -42,7 +45,19 @@ jobs:
- run: pnpm exec tsx scripts/workflow-boundary.ts && pnpm exec tsx scripts/recovery-check.ts
- run: pnpm exec tsx scripts/performance.ts
- run: pnpm run licenses
- uses: actions/upload-artifact@v4
- name: Verify release SDK archive
run: node scripts/package.cjs
- name: Keep tested SDK release assets
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: tally-release
path: |
artifacts/tally-local-sdk-*.tgz
artifacts/tally-local-sdk-*.tgz.sha256
artifacts/SHA256SUMS
if-no-files-found: error
overwrite: true
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: tally-sdk-and-verification
path: |
Expand All @@ -57,3 +72,26 @@ jobs:
docs/DEPENDENCIES.json
- if: always()
run: docker compose --profile app down
publish:
name: Publish verified release
needs: verify
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: write
concurrency:
group: tally-release
cancel-in-progress: false
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- name: Read assets from this verified run
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: tally-release
path: release-artifacts
- name: Publish complete SDK assets
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const publish = require('./scripts/release.cjs');
await publish({ github, context, core });
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 1.0.0

Release preparation dated October 6, 2026.

- Define the supported private-installation scope, schema 1 compatibility, SDK API stability, and upgrade procedure.
- Align installation, SDK, reference application and local container version labels at 1.0.0. Existing data and event schema remain unchanged.
- Supply a versioned SDK archive and SHA256 checksums through a main-only release job after the full application, independent consumer, native browser and operations checks pass. Source archives are supplied by GitHub for the same release tag.
- Derive the independent consumer archive name from the SDK version and install it in a fresh temporary directory outside the workspace.
- Update the Sharp dependency to 0.35.5 for the upstream librsvg advisory. Framework and direct dependency versions remain unchanged.

## 0.1.0 — 2026-09-08

Initial private-use candidate: dependency-free SDK, schema-v1 ingestion, PostgreSQL persistence and migrations, Better Auth owner login/recovery, multi-project dashboard, shared outcome/latency/workflow/release reports, bounded export, native WebMCP adapter and three dashboard tools, independent SDK archive test, fictional reference storefront, Docker Compose and operational verification scripts.
Expand Down
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ Tally is a private, self-hosted monitor for explicitly instrumented WebMCP execu

This is a software product, not a contest submission. It runs without a paid service or AI API key. The fictional Field Supply storefront is an integration reference with real telemetry ingestion and simulated orders; it is not the only application the SDK supports.

**Release status:** See [the executed-check report](docs/RELEASE-READINESS.md) before relying on this release. Native integration status, capacity limits, dependency license obligations, and remaining limitations are explicit there. The local npm scope `@tally-local` is provisional; no package has been published and availability of the name is not claimed. Tally is licensed under the [MIT License](LICENSE).
**Version 1.0:** The supported scope is one owner, up to 20 projects, and reports over at most 50,000 retained events per project. Read the [v1 stability and upgrade contract](docs/V1.md) and [executed-check report](docs/RELEASE-READINESS.md). The local npm scope `@tally-local` is provisional; no registry package has been published and availability of the name is not claimed. Tally is licensed under the [MIT License](LICENSE).

![Tally dashboard showing real reference tool observations](docs/assets/dashboard-desktop.png)

## Start a private installation

Requirements: Node.js 24 LTS, **pnpm 11.19.0**, Docker with Compose v2. Ports 3000, 3001 (optional storefront), and 55487 (local PostgreSQL) must be free. These commands work from a checked-out source directory in PowerShell or a POSIX shell.

Download and extract **Source code (zip)** or **Source code (tar.gz)** from the [v1.0.0 release](https://github.com/agammann/tally/releases/tag/v1.0.0), then open a terminal in the extracted directory. The tagged source includes the application, migrations, SDK, MIT license, and operations documentation. The release publishes only after the complete verification job passes; a release asset is not a prebuilt application container.

```sh
npm install --global pnpm@11.19.0
pnpm install --frozen-lockfile
Expand All @@ -47,20 +49,26 @@ The initialization command copies local server settings into `apps/tally/.env.lo

## Install the SDK in another application

Build a distributable archive from this repository:
Download `tally-local-sdk-1.0.0.tgz` and its `.sha256` file from the [v1.0.0 release](https://github.com/agammann/tally/releases/tag/v1.0.0). Compare the archive's SHA256 against the checksum before installation:

```powershell
Get-FileHash ./tally-local-sdk-1.0.0.tgz -Algorithm SHA256
```

On Linux use `sha256sum`, or on macOS use `shasum -a 256`. You can also build the same distributable format from a checked-out release:

```sh
pnpm --filter @tally-local/sdk build
pnpm --filter @tally-local/sdk pack --pack-destination ../../artifacts
pnpm --filter @tally-local/sdk pack --pack-destination artifacts
```

Copy `artifacts/tally-local-sdk-0.1.0.tgz` to an independent application and run:
Copy the downloaded archive, or `artifacts/tally-local-sdk-1.0.0.tgz` from your source build, to an independent application and run:

```sh
npm install ./tally-local-sdk-0.1.0.tgz
npm install ./tally-local-sdk-1.0.0.tgz
```

The archive contains ESM, CommonJS and TypeScript declarations, with **no runtime dependencies or monorepo imports**. Use the copyable project-specific example in Setup and the [integration guide](docs/INTEGRATION.md). SDK version **0.1.0** sends event schema **1**; the versions are independent.
The archive contains ESM, CommonJS and TypeScript declarations, with **no runtime dependencies or monorepo imports**. Use the copyable project-specific example in Setup and the [integration guide](docs/INTEGRATION.md). SDK version **1.0.0** sends event schema **1**; the versions are independent.

## Reference storefront

Expand Down Expand Up @@ -103,6 +111,7 @@ CI sets `TALLY_REQUIRE_NATIVE=1` for the native check, so missing browser capabi
- [WebMCP compatibility and native verification](docs/COMPATIBILITY.md)
- [Operation, backup, retention, upgrade and owner recovery](docs/OPERATIONS.md)
- [Executed checks and release readiness](docs/RELEASE-READINESS.md)
- [v1 stability and upgrades](docs/V1.md)
- [Implementation checklist and decisions](docs/IMPLEMENTATION.md)
- [Dependency license inventory](docs/DEPENDENCIES.json)
- [Changelog](CHANGELOG.md)
2 changes: 1 addition & 1 deletion apps/reference-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tally-reference",
"version": "0.1.0",
"version": "1.0.0",
"private": true,
"license": "MIT",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion apps/tally/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tally-dashboard",
"version": "0.1.0",
"version": "1.0.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update the in-app SDK filename with the version bump

After the dashboard is versioned as 1.0.0 and the release pipeline publishes only tally-local-sdk-1.0.0.tgz, the Setup page still tells new project owners to run npm install ./tally-local-sdk-0.1.0.tgz in apps/tally/components/setup.tsx:8. A user following the primary in-app onboarding flow with the 1.0 release assets therefore gets a missing-file installation failure; update this instruction alongside the version bump, preferably deriving it from a shared version value.

Useful? React with 👍 / 👎.

"private": true,
"license": "MIT",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ services:
mem_limit: 768m
restart: unless-stopped
migrate:
image: tally-private-app:0.1.0
image: tally-private-app:1.0.0
build: .
env_file: .env
environment:
Expand All @@ -26,7 +26,7 @@ services:
db: {condition: service_healthy}
profiles: [app]
app:
image: tally-private-app:0.1.0
image: tally-private-app:1.0.0
build: .
env_file: .env
environment:
Expand Down
2 changes: 1 addition & 1 deletion docs/INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ The example's application functions (`deliveryService`, `showNativeUnavailable`)
## API and behavior

- `createTallyClient(config)` makes a collector. Invalid endpoint/identifier/environment configuration disables collection. Only HTTPS and loopback HTTP endpoints are accepted; credentials in URLs are rejected.
- `wrapTool(definition, options)` returns a copy preserving the prototype and property descriptors, with only `execute` replaced. Pass browser registration options (including registration cancellation) to `registerTool` separately. The original callback executes once with its original `this`, argument objects and execution context. Synchronous values remain synchronous. Promise fulfillment values and rejection objects are preserved; promise identity is not preserved. Version 0.1 supports ordinary synchronous callbacks and native JavaScript promises; custom thenable objects are not treated as promises.
- `wrapTool(definition, options)` returns a copy preserving the prototype and property descriptors, with only `execute` replaced. Pass browser registration options (including registration cancellation) to `registerTool` separately. The original callback executes once with its original `this`, argument objects and execution context. Synchronous values remain synchronous. Promise fulfillment values and rejection objects are preserved; promise identity is not preserved. Version 1.0 supports ordinary synchronous callbacks and native JavaScript promises; custom thenable objects are not treated as promises.
- `trackWorkflowStarted(metadata)` / `trackWorkflowCompleted(metadata)` record explicit host observations. An opaque UUID, allowlisted workflow name, and explicit source are required. Window/definition versions are assigned server-side.
- `flush()` sends a snapshot of the current queue. A concurrent flush shares the active operation; later events remain queued for the next flush. The application action never awaits automatic delivery. Explicit flush resolves despite collection failures, so inspect diagnostics and dashboard receipt when verifying installation.
- `disable()` stops recording, drops queued events, aborts outstanding fetches, and removes lifecycle listeners. Already transmitted or committed events cannot be retracted. Create a fresh client to re-enable.
Expand Down
2 changes: 1 addition & 1 deletion docs/OPERATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ The recovery command delegates hashing to Better Auth, changes the existing owne
3. Obtain the target source, run `pnpm install --frozen-lockfile`, then build the target container.
4. Run the explicit migration service: `docker compose --profile app run --rm migrate`.
5. Start the application: `docker compose --profile app up -d app`. Verify readiness, login, project access and known report samples.
6. Update SDK archives in applications independently. SDK 0.1.0 remains schema 1; unsupported event schemas receive permanent 400 responses.
6. Update SDK archives in applications independently. SDK 1.0.0 remains schema 1; unsupported event schemas receive permanent 400 responses.

The initial-to-second migration adds only an index and was tested with existing records. It does not require application code changes and the previous schema-compatible application can read the upgraded database. **No destructive down-migration or general migration rollback is verified.** If a future migration is incompatible, recover a verified backup into a new database and run the matching application revision; later accepted events are absent from that backup. Do not blindly run `migrate reset` or modify an applied migration.

Expand Down
28 changes: 27 additions & 1 deletion docs/RELEASE-READINESS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
# Tally 0.1.0 release readiness
# Tally release readiness

## Version 1.0 candidate verification

Executed October 6, 2026, America/Los_Angeles, from a clean copy of main with the 1.0 release changes. Machine evidence uses October 7 UTC timestamps. The self-hosted application was built in Docker and run against a new isolated PostgreSQL volume. No production owner or existing installation data was used.

The candidate keeps schema 1 and the documented SDK behavior, corrects the README's archive destination for pnpm 11, adds a stable install/upgrade contract, and distributes the dependency-free SDK through a checked GitHub release pipeline. The public npm scope remains provisional and unpublished. Sharp 0.35.5 replaces the affected 0.35.4 dependency; the other direct framework and runtime versions are unchanged.

| Check | Actual local result |
| :--- | :--- |
| Fresh source and dependency install | All 101 original tracked blobs matched main before edits. Frozen pnpm 11.19.0 install passed with Node 24.19.0. |
| Static and production checks | Root and workspace TypeScript checks, 16 unit tests, SDK/shared builds, both Next.js production builds, and the production Docker build passed. |
| README SDK packaging | The exact documented pack command produced `artifacts/tally-local-sdk-1.0.0.tgz` in the checkout. Its ESM, CommonJS, declaration, README, MIT license and dependency-free manifest checks passed; SHA256 sidecar and combined checksums were generated. |
| New owner browser flow | Fresh owner setup and sign-in, project creation, real reference ingestion, failure/slow/cancellation scenarios, persisted simulated checkout, release comparison, workflow view, and desktop/mobile checks passed. Page identity, nonblank content, framework overlay, console and page-error checks passed. |
| Strict collector integration | 13 checks passed, including the known 75%/450 ms/800 ms fixture, concurrent duplicate delivery, authentication, allowlists, schema rejection, quotas, rotation, export, deletion and expired sessions. |
| Independent SDK consumer | A fresh directory outside the workspace installed the 1.0 archive with npm 11.9.0, compiled TypeScript, preserved one ESM callback and sent accepted collector requests. A separate CommonJS consumer also preserved callback behavior. |
| Native WebMCP | Playwright 1.63.0 with Chromium 153.0.8010.12 and `--enable-features=WebMCPTesting` used the real draft APIs without a polyfill. Three dashboard tools, visible filter change, unauthorized-project rejection and seven persisted reference events covering success/failure/cancellation passed. Tools disappeared after sign-out. |
| Operations | Database restart preserved 44 events; binary backup/restore row counts matched in a separate database; additive migration, complete invocation retention and cleanup passed. Owner recovery revoked the old session, changed the password and preserved both existing projects. |
| Capacity fixtures | The 50,000-event calculation fixture and a local 5,000-event/ten-report HTTP workload passed. These are bounded local checks, not a general throughput guarantee. |
| Production dependency audit | Zero known advisories after the Sharp patch on October 6. This remains a dated advisory database result. |
| Release publication guard | Seven local API simulations passed main-only mutation, complete draft assets, exact tag, digest failure, draft retry and published-release immutability. Actual release publication is separately gated by the full GitHub verification job and verified uploaded asset hashes. |

The browser flow ran on `http://localhost:4327` with the reference app on port 4328 and a fresh database on 55457, using temporary QA copies to adapt test URLs. The documented installation defaults remain 3000, 3001 and 55487. Desktop was 1280 × 720 and mobile was 390 × 844. The Browser plugin was unavailable in that test session; regular Playwright supplied the rendered checks. Firefox, Safari, arbitrary deployment scale and the separate hosted D1 service were not re-certified by this self-hosted run.

The [v1 contract](V1.md) defines the supported scope and stopping point. The GitHub Actions job retains exact-run SDK and verification artifacts; its publisher checks the release tag's commit and uploaded asset digests before making a release public. Dependency redistribution obligations and operator controls below still apply.

## Historical 0.1 assessment

Assessment completed September 10, 2026, America/Los_Angeles. Machine evidence uses UTC, including September 11 timestamps.

Expand Down
Loading
Loading