Flow is an ESM TypeScript package built and tested with Git and versions
pinned in package.json.
bun install --frozen-lockfile
bun run checkbun run check is the canonical deterministic gate. Use focused commands while
iterating:
bun run typecheck
bun run lint
bun test tests/domain-transitions.test.ts
bun test tests/runtime-gates.test.ts tests/validation-capture.test.ts
bun test tests/workspace-persistence.test.ts
bun run build
bun run package:smokeThe opt-in real-host check launches the pinned opencode-ai package through
bunx. It requires registry access or a populated Bun cache, not a
separately installed OpenCode binary:
bun run smoke:live@opencode-ai/plugin and zod are on .github/dependabot.yml's ignore list,
so they are raised by hand. The plugin pin is also the host version
smoke:live launches, so bumping it puts a new host under test:
- Move the
devDependenciespin, andpeerDependenciesif the new version falls outside the declared range. - Run
bun run check, thenbun run smoke:livefor the real host.
Widen the peer range only for a smoke-tested host; a wider range makes a compatibility claim no check has run.
src/domain/owns Session v5 values, invariants, and transitions that use only JavaScript/Node standard-library primitives.src/application/owns use cases and repository ports.src/infrastructure/owns filesystem persistence and source fingerprinting:fs/workspace-paths.ts(workspace root validation,.flowlayout),fs/managed-fs.ts(managed filesystem primitives),fs/session-lock.ts(cross-process session lock),fs/workspace.ts(session file protocol).src/platform/opencode/owns OpenCode hooks, host schemas, commands, tools, validation capture, and the duplicate-runtime guard:command-hook.ts(slash-command hook),tool-guard.ts(leadership and auto-drive guard around the tools),auto-drive-decision.ts(pure idle-routing decision,decideOnIdle, run byauto-drive.ts),plugin.ts(wiring only).src/guidance/,skills/, and prompt surfaces own concise workflow judgment.tests/prove state-machine, persistence, platform, package, and host contracts.
Dependencies point inward. Domain code does not import filesystem or host APIs; application code depends on domain; infrastructure implements application ports; the OpenCode platform composes outer layers.
There is no distribution/activation subsystem, cache inventory, repair journal, or Flow-owned installer: OpenCode installs and loads the npm package from its native plugin command and configuration.
- Keep Session v5 as one canonical run aggregate: derive status and progress, not parallel ledgers or cached counters.
- Every mutation needs a revision guard and stable operation ID. Exact replay is safe; conflicting reuse fails.
- Only the reserved reviewer may create a new completion; while the Session v5 workflow remains active, every other caller gets an exact accepted-completion replay through a read-only path that neither cancels validation nor writes session state.
- Keep validation host-observed and session-native: no caller-authored success, detached receipt stores, or clock requirements.
- Treat validation scope as a coverage claim:
broadmeans the canonical repository gate, byte for byte, not a narrow command relabeled. - Validation commands are persisted, never with inline secrets. Raw output is intentionally reduced to completeness and a digest rather than stored or projected.
- Keep one review per run. A final review requires broad validation and is not a
second pass. The reviewer submits through
flow_feature_complete; the manager never proxies its verdict. - Prefer deletion when a test or document exists only for a removed concept, not a dual stack for pre-v6 active state.
- Use table-driven lifecycle and persistence tests, not registries that test the presence of other tests.
Update the README, maintainer contract, ADR, and changelog when a public lifecycle or installation contract changes. Documentation must describe only the current product; Git history owns superseded plans and experiments.
Deterministic CI validates schemas, permissions, prompts, and host integration without provider credentials. It does not claim a model overlaps workers, so wave-behavior changes need manual exercise with a real provider when available, with sanitized evidence of:
- worker start/end times with a positive common overlap;
- assigned versus changed paths and any scope drift;
- permission prompts or denials and worker Bash calls; and
- reviewer-owned
flow_feature_completesubmission.
Every wave-behavior change needs this evidence when marked verified, but it is not a deterministic release gate. Without a provider, mark the behavior unverified, record the review risk, and avoid performance or reliability claims. Do not persist prompts, secrets, raw provider payloads, or a wave ledger, or add provider credentials, a scheduler, or telemetry to CI.
Deterministic tests exercise the coordinator through the real plugin hooks and
the promptAsync client boundary, but not how a configured model
behaves after delivery. When auto-continuation behavior changes and a provider
is available, run one packed-plugin canary recording sanitized evidence of:
- idle
readydelivery with the Flow token and compact revision; - recommendation or clarification at a checkpoint remaining waiting, followed by a same-host accepted approval resuming exactly once while an other-host revision advance does not;
- compaction retaining the manager kernel and reserved Flow roles;
- one automatic fresh retry only at
failedReviewCount === 1without ascopeBlockerfinding, with every higher count awaiting user direction; - one reviewed retry preserving prior
findingIdvalues, refreshed baseline facts, prior dispositions, and its applicable transition matrix; and - confirmed completed closure with the final conversational disposition map
reconstructed from the existing concise
workflowData.delivery.
Use the existing host transcript and Flow detail projection; add no telemetry or persisted continuation state. Keep credentials, raw provider payloads, and user content out of evidence. This is an opt-in provider canary, not a CI model evaluation. If unavailable, mark model behavior unverified while retaining the deterministic hook and lifecycle gates.
Follow the frozen-candidate sequence:
finish fixes and dependency updates, pass deterministic checks, approve paid
evals.
bun run qualify -- --campaign-dir <dir> --canary <record> seals the
policy grid, canary and grader evidence. Versions 9.1.0, 9.2.0, 9.3.0 and 9.4.0 use
GPT-6 Sol only under explicit exceptions. Other versions require two providers. Commit that
bundle before tagging; never substitute interrupted results for qualification.
Release tags use v<package-version>. Blocking release checks: the normal
repository gate, package smoke, packed live OpenCode smoke, package integrity
generation, npm publication, and GitHub release assets. There is no
cross-version active-session gate; v6 is an explicit hard cutover.
Publication accepts both annotated and lightweight tags, but the freshly fetched
tag, workflow event, checkout, and current remote main tip must identify the
same commit immediately before npm publication. Network calls have explicit
deadlines. npm publication reconciles the immutable package integrity after
every result, including timeouts. GitHub publication builds an exact draft under
the same ref proof. That draft recovers if npm succeeds and main advances.
Finalization rechecks the remote tag, refuses conflicting metadata or assets,
and publishes only after every asset digest matches. Reruns converge after
partial success without replacing published bytes.
Preparing an already-published release is read-only and requires exact assets.
Missing or pending assets fail preparation; use the github-publish recovery
path with original inputs and tag proof to restore a missing asset.