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
13 changes: 13 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ history: read the plan's **Next implementation handoff**, implement only that
bounded slice, update its evidence, run the required tests, and commit the
coherent change so the next agent can reproduce the same context.

Before editing, inspect the worktree and update the tracked branch from its
remote with fast-forward-only semantics. If the worktree is dirty, the branch
has diverged, or the remote cannot be reached, preserve the local state and
report the condition instead of stashing, resetting, or editing an unverified
base. Record the starting commit in the handoff evidence.

## Family contracts

The five-repository dependency graph, repository ownership, change routing,
Expand All @@ -60,8 +66,15 @@ For an application project, run:
```bash
raco rivet inspect --json
raco rivet doctor --json
raco rivet acceptance --json
```

`rivet-acceptance.rktd` is the product-owned, executable definition of done.
Do not remove a requirement, weaken a suite, replace packaged behavior with a
development substitute, or refresh expected evidence merely to make a change
green. A skipped, unrun, timed-out, or wrong-platform required suite means the
work is not complete.

For this repository, inspect the nearest implementation and its tests before
editing. The shared wire contract is documented in `docs/protocol.md` and
exercised by `rivet/tests/protocol-golden.txt` across Racket, C++, Swift, and Kotlin.
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## Unreleased

- Add executable product acceptance contracts. `raco rivet acceptance
--json` validates `rivet-acceptance.rktd`, rejects missing kind/platform
coverage, launches each current-platform suite as an executable plus argv
without a shell, enforces bounded time and output, and fails on nonzero exits
or missing evidence. `inspect --json`, generated projects, agent guidance,
and the native UI extension contract now expose the same definition of done,
so a build-only or unrun platform can no longer be described as accepted.

- Set the Windows title-bar icon from the embedded exe resource. WinUI shows a generic placeholder in the title bar unless the window is handed an icon explicitly, so every shipped host ran with a foreign default glyph while taskbar and shortcuts showed the real brand icon — the icon was compiled into the exe (resource ID 1 since #283) but nothing ever loaded it. The host template now loads it with `LoadIconW` and hands it to `AppWindow.SetIcon` at construction; projects without a `windows-icon` declaration keep the placeholder. Existing products carry the same lines in their own `MainWindow` constructor (podlens landed it first).

- Add the release gate. `raco rivet generate --check` regenerates every client file in memory and fails when the tree differs — the writer and the gate share one regeneration, so a hand-edited version stamp or a forgotten regeneration (four shipped-repo incidents in one week) cannot merge. `raco rivet doctor --release` validates in one command and one exit code: generated freshness, the committed schema baseline, hand-written host sources calling `fetch-update-manifest`/`select-update`/`download-update`/`fetch-sibling-asset` only with keywords the installed rivet accepts (read via `procedure-keywords` from the live functions, closing the payback `#:redirections` class), and every `rivet.git#...` pin being non-empty and consistent with the installed release (the autarx empty-ref incident). The update API keyword contract is a documented, test-guarded stable surface, and `docs/ci.md` warns about the empty `URL#` footgun.
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ raco rivet dev

That is the normal first-run path. `doctor` checks the native toolchain and prints actionable fixes when a required component is missing; `dev` builds and launches the current platform's first-party native host.

Every generated app includes an `AGENTS.md` and an initial `rivet-schema.json` compatibility baseline. `inspect --json` exposes a versioned machine-readable map of project identity, backend/native UI edit points, schema checks, target maturity, generated paths, and safe lifecycle commands. See [agent-native development](docs/agent-native.md).
Every generated app includes an `AGENTS.md`, an initial `rivet-schema.json`
compatibility baseline, and a `rivet-acceptance.rktd` executable definition of
done. `inspect --json` exposes a versioned machine-readable map of project
identity, backend/native UI edit points, schema and acceptance checks, target
maturity, generated paths, and safe lifecycle commands. See [agent-native
development](docs/agent-native.md) and [product acceptance
evidence](docs/product-acceptance.md).

For a guided walkthrough, read **[Getting Started with Rivet](docs/getting-started.md)**. Before shipping a product, adopt the [native-host CI contract](docs/ci.md). The installed package also includes searchable Scribble documentation. If you are developing Rivet itself, use the linked-checkout workflow in that guide instead of installing from the catalog.

Expand Down
6 changes: 5 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ raco rivet dev

这就是普通用户的主路径。`doctor` 会检查原生工具链,并在缺少必要组件时直接给出下一步修复建议;`dev` 会构建并启动当前平台的一等原生宿主。

每个新项目都会生成 `AGENTS.md` 和初始 `rivet-schema.json` 兼容性基线;`inspect --json` 则提供带版本号的机器可读项目地图,包括项目身份、Racket 后端与各端原生 UI 编辑入口、schema 检查、目标成熟度、生成目录和安全生命周期命令。详见 [Agent-native 开发](docs/agent-native.md)。
每个新项目都会生成 `AGENTS.md`、初始 `rivet-schema.json` 兼容性基线和
`rivet-acceptance.rktd` 可执行完成定义;`inspect --json` 则提供带版本号的机器
可读项目地图,包括项目身份、Racket 后端与各端原生 UI 编辑入口、schema 与验收
检查、目标成熟度、生成目录和安全生命周期命令。详见 [Agent-native
开发](docs/agent-native.md)和[产品验收证据](docs/product-acceptance.md)。

需要完整引导时直接看 **[Rivet 快速上手教程](docs/getting-started.zh-CN.md)**;产品发布前请采用[原生宿主 CI 契约](docs/ci.zh-CN.md)。安装后的包也提供可搜索的 Scribble 文档。只有开发 Rivet 框架本身时,才需要使用教程里的源码 link 安装方式。

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ a product overview rather than a second documentation index.
- [Diagnostics and cleanup](diagnostics.md)
- [Continuous integration](ci.md) · [中文](ci.zh-CN.md)
- [Agent-native development](agent-native.md)
- [Product acceptance evidence](product-acceptance.md)

## Understand contracts / 理解契约

Expand Down
19 changes: 14 additions & 5 deletions docs/agent-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,20 @@ removes only those generated roots and refuses to follow directory symlinks.
The normal autonomous loop is:

```bash
raco rivet acceptance --json
raco rivet build
raco rivet dev
raco rivet package
raco rivet verify
```

`rivet-acceptance.rktd` is the product-owned, executable definition of done.
It declares required evidence categories and the native platforms that must
run them. `acceptance` launches each suite without a shell, enforces time and
output bounds, checks exit status and declared artifacts, and returns a
machine-readable report suitable for a required CI check. See
[product acceptance evidence](product-acceptance.md).

`build` validates the Racket schema and regenerates typed native clients.
`package` creates and immediately verifies a development distributable.
`verify` can audit the artifact again without rebuilding it. Production mode
Expand All @@ -210,8 +218,9 @@ under application control.

## Current boundary

This contract makes project discovery, diagnostics, mutation boundaries, and
artifact verification agent-native. It does not yet provide automated visual
inspection of every first-party native UI. Windows/macOS/Linux UI automation,
accessibility-tree inspection, screenshots, and interaction traces remain a
separate product layer and should not be claimed until those adapters exist.
This contract makes project discovery, diagnostics, mutation boundaries,
acceptance orchestration, and artifact verification agent-native. Rivet does
not itself visually inspect every first-party product UI. Windows/macOS/Linux
UI automation, accessibility-tree inspection, screenshots, and interaction
traces remain product-owned suites and should not be claimed until those
native adapters are declared and green in the acceptance manifest.
11 changes: 11 additions & 0 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ certificates and notarization credentials do not belong in pull-request CI;
use development packaging there and reserve `--production` for a protected
release environment.

Every maintained product should also commit `rivet-acceptance.rktd` and run
`raco rivet acceptance --json` in each native platform job. That manifest is
the executable definition of done: RackUnit, generated-client bridge tests,
native accessibility drivers, and packaged-product checks remain implemented
by their owning layer, while Rivet rejects missing declared coverage, timeouts,
nonzero exits, and missing evidence. Archive the JSON report on failure. See
[product acceptance evidence](product-acceptance.md).

## Copy-paste GitHub Actions workflow

The following workflow pins Rivet 0.11.0. Update every Rivet package source and
Expand Down Expand Up @@ -52,6 +60,7 @@ jobs:
- run: raco pkg install --auto --no-docs 'https://github.com/turinglambdaai/rivet.git#v0.11.0'
- run: raco rivet doctor
- run: raco rivet schema check rivet-schema.json
- run: raco rivet acceptance --json
- run: raco rivet build

macos-host:
Expand All @@ -71,6 +80,7 @@ jobs:
- run: raco pkg install --auto --no-docs 'https://github.com/turinglambdaai/rivet.git#v0.11.0'
- run: raco rivet doctor
- run: raco rivet schema check rivet-schema.json
- run: raco rivet acceptance --json
- run: raco rivet build

linux-host:
Expand All @@ -87,6 +97,7 @@ jobs:
run: raco pkg install --auto --no-docs 'https://github.com/turinglambdaai/rivet.git#v0.11.0'
- run: raco rivet doctor
- run: raco rivet schema check rivet-schema.json
- run: raco rivet acceptance --json
- run: raco rivet build
```

Expand Down
9 changes: 9 additions & 0 deletions docs/ci.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ CI 应使用与发布任务相同类别的 runner 和工具链:
`package` 与 `verify`。发布者证书和公证凭据不应进入拉取请求 CI;这里使用
开发打包,把 `--production` 留给受保护的发布环境。

每个持续维护的产品还应提交 `rivet-acceptance.rktd`,并在每个原生平台 job
中运行 `raco rivet acceptance --json`。这份清单是可执行的完成定义:RackUnit、
生成客户端桥接测试、原生无障碍驱动和打包产品检查仍由各自层实现;Rivet 负责
拒绝缺少的声明覆盖、超时、非零退出码和缺失证据,并应在失败时归档 JSON 报告。
格式与使用方法见 [Product acceptance evidence](product-acceptance.md)。

## 可直接使用的 GitHub Actions 工作流

下面的工作流固定到 Rivet 0.11.0。升级时,应在同一次评审中把每处 Rivet
Expand Down Expand Up @@ -49,6 +55,7 @@ jobs:
- run: raco pkg install --auto --no-docs 'https://github.com/turinglambdaai/rivet.git#v0.11.0'
- run: raco rivet doctor
- run: raco rivet schema check rivet-schema.json
- run: raco rivet acceptance --json
- run: raco rivet build

macos-host:
Expand All @@ -68,6 +75,7 @@ jobs:
- run: raco pkg install --auto --no-docs 'https://github.com/turinglambdaai/rivet.git#v0.11.0'
- run: raco rivet doctor
- run: raco rivet schema check rivet-schema.json
- run: raco rivet acceptance --json
- run: raco rivet build

linux-host:
Expand All @@ -84,6 +92,7 @@ jobs:
run: raco pkg install --auto --no-docs 'https://github.com/turinglambdaai/rivet.git#v0.11.0'
- run: raco rivet doctor
- run: raco rivet schema check rivet-schema.json
- run: raco rivet acceptance --json
- run: raco rivet build
```

Expand Down
27 changes: 27 additions & 0 deletions docs/desktop-closeout-mobile-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,33 @@ installer path.
Exit evidence: credential-backed artifacts pass `raco rivet verify
--production` in their trusted release environments.

### Gate D5 — product behavior has executable evidence

1. Every maintained product commits `rivet-acceptance.rktd` and runs `raco
rivet acceptance --json` in required Windows, macOS, and Linux jobs.
2. Requirements cover shared contract behavior, generated-client/embedded-
backend round trips, native host builds, and at least one critical packaged
native UI flow on every supported desktop platform.
3. UI suites use disposable profile/config/database roots and observable
accessibility or state conditions. Fixed sleeps, process-survival-only
smoke tests, CLI substitutes for GUI actions, and undeclared workarounds do
not satisfy the corresponding requirement.
4. Acceptance-policy changes, native drivers, golden data, and CI gates receive
the same protected review as public API changes.

Exit evidence: Taskly is the first product to pass the complete contract on all
three platforms; the remaining maintained products then adopt the same gate.
Rivet provides the bounded, shell-free orchestration and rejects missing
coverage, stale evidence, timeouts, or failed commands, while each product owns
its native driver and assertions.

Progress (2026-10-18): Rivet's acceptance manifest and CLI orchestration are
implemented in the current change, together with scaffold, diagnostics, tests,
and the permanent product guide. Framework CI must validate this batch before
the gate can be considered available. Taskly adoption remains pending because
its local checkout could not be fast-forwarded from the remote during this
work; no product files were edited on that unverified base.

## Non-blocking desktop improvements

These remain worthwhile but do not block mobile contract/gateway work:
Expand Down
5 changes: 4 additions & 1 deletion docs/native-ui-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ scenario vocabulary. Keep those identifiers in native source:

Copy the matching driver under `rivet/tests/native-ui/`, replace the reference
identifiers and actions with one product-critical scenario, and add the driver
to a packaging job. A useful minimum scenario has one RPC-driven mutation, one
to a packaging job. Declare that driver as a `native-ui` suite in the
product's `rivet-acceptance.rktd` so missing platform coverage fails before the
job starts; see [product acceptance evidence](product-acceptance.md). A useful
minimum scenario has one RPC-driven mutation, one
Event, a stable accessibility-tree assertion, and orderly close. Test-only
protocol messages and a cross-platform selector language are deliberately not
extension points.
Expand Down
110 changes: 110 additions & 0 deletions docs/product-acceptance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Product acceptance evidence

`raco rivet acceptance` turns a product's definition of done into an
executable, source-controlled contract. It complements RackUnit and each
platform's native UI tools; it does not replace them or introduce a shared UI
selector language.

The command reads `rivet-acceptance.rktd`, validates that every declared
requirement has a suite on every required platform, then runs the suites for
the current host. Each command is launched as an executable plus argv without
a shell. Rivet enforces a timeout, drains stdout and stderr concurrently,
captures at most 64 KiB from each stream, checks the exit status, and verifies
declared evidence paths before reporting success.

## Manifest

Commit the manifest at the project root:

```racket
#hasheq(
(version . 1)
(requirements
. (#hasheq((kind . contract) (platforms . (windows macos linux)))
#hasheq((kind . native-ui) (platforms . (windows)))))
(suites
. (#hasheq((id . core)
(kind . contract)
(platforms . (windows macos linux))
(command . ("raco" "test" "racket/"))
(timeout-seconds . 300))
#hasheq((id . windows-ui)
(kind . native-ui)
(platforms . (windows))
(command . ("pwsh" "-File" "scripts/e2e/windows.ps1"))
(timeout-seconds . 900)
(evidence . (".rivet/acceptance/windows/trace.json"
".rivet/acceptance/windows/accessibility.json"))))))
```

The supported suite kinds are:

- `unit`: isolated implementation tests;
- `contract`: product behavior, schema, golden output, and real storage;
- `bridge`: generated client through RVT1 to the embedded backend;
- `native-build`: compilation of the first-party platform host;
- `native-ui`: accessibility-driven interaction with the native product;
- `package`: behavior or structure of the distributable artifact; and
- `release`: installer, update, rollback, signing, or production trust.

Suite ids are unique symbols. Platforms are a non-empty subset of `windows`,
`macos`, and `linux`. A command is a non-empty list of argv strings; shell
syntax, redirection, pipes, and command interpolation are not interpreted.
Timeouts are positive integers capped at two hours. Evidence entries are file
paths below `.rivet/acceptance/`. Rivet removes each declared file before the
suite starts and then requires the suite to recreate it, so a stale artifact
from an earlier green run cannot satisfy the current run. `native-ui`,
`package`, and `release` suites must declare at least one evidence file.

`requirements` is the reviewable policy. For every kind/platform pair there
must be at least one matching suite or the manifest is rejected before a child
process starts. Product owners should protect changes to requirements, CI,
golden data, and native UI drivers with the same review rules as public API
changes. A green result is not meaningful if a change weakens the evidence
contract in the same patch without explicit review.

## CI usage

Run the command in every native host job, not only on Linux:

```bash
raco rivet acceptance --json
```

The JSON report contains the project, platform, manifest path, configured
requirements, selected suites, bounded output, duration, timeout state, exit
code, and missing evidence. Archive it even when the job fails. Use `--suite
<id>` only for diagnosis; the required merge gate should run the complete
current-platform set.

For an alternative manifest during migration:

```bash
raco rivet acceptance --manifest path/to/acceptance.rktd --json
```

Before editing an existing checkout, first inspect the worktree, fetch the
tracked remote, and update with fast-forward-only semantics. Record the base
commit with the acceptance report. A dirty, diverged, or unreachable checkout
is a reason to stop and report the state, not a reason to stash, reset, or
claim evidence against an unknown base.

## What counts as complete

RackUnit is the normal owner of shared Racket behavior. A product that claims
the Rivet architecture should additionally exercise at least one real
generated-client/embedded-backend round trip and one critical packaged native
UI flow per supported desktop platform. The native UI driver should assert
semantic roles, one RPC mutation, resulting State/Event presentation, and
orderly shutdown. See [native UI end-to-end testing](native-ui-testing.md).

Fixed sleeps, process-survival-only smoke tests, mock-only backend calls, or a
CLI substitute for a GUI action are useful diagnostics but are not evidence
for the corresponding product behavior. Prefer bounded waits on observable
state and disposable HOME/config/database roots. Never modify a developer's
real profile or kill unrelated processes from an acceptance suite.

An agent may choose an implementation. It may not reinterpret completion: a
required suite that was skipped, not run on its declared platform, timed out,
used the wrong artifact, or failed to produce its evidence means the work is
not complete.
Loading
Loading