executable-interactive-plans

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Executable Interactive Plans

可执行交互式计划

The plan is agreement on four Effect contracts, proven by executable story tests.
The human reviews two questions:
  1. Do these tests express the behavior I want?
  2. Do these Schemas, Errors, Services, and Effectful function signatures match that behavior?
Read references/executable-interactive-plans.md. Start from assets/story-test-template.
Gall's Law: ship the smallest complete set of those four contracts. Hyrum's Law: once agreed, every observable of those signatures is the contract.
该计划是对四项Effect契约的共识,由可执行的故事测试来验证。
人工评审需确认两个问题:
  1. 这些测试是否准确表达了我想要的行为?
  2. 这些Schema、错误、服务和Effect函数签名是否与该行为匹配?
阅读references/executable-interactive-plans.md。从assets/story-test-template开始。
Gall定律:交付这四项契约的最小完整集合。Hyrum定律:一旦达成共识,这些签名的每一个可观测项都属于契约内容。

The four contracts

四项契约

Group Proposed Code as Schemas, Errors, Services, and Effectful functions. Write each item as exact editable source.
将建议代码分为SchemasErrorsServicesEffectful函数四类。每个条目都需写成可编辑的精确源代码。

Schemas

Schemas

Effect Schemas for inputs, outputs, and domain values. Tests generate from these Schemas. Do not hand-build random values beside them.
用于输入、输出和领域值的Effect Schemas。测试用例从这些Schema生成。不要在Schema之外手动构建随机值。

Errors

Errors

Schema.Error
classes that appear in the
E
channel. Every Error in a signature is proposed code. A story test that lists an Error must assert that Error.
出现在
E
通道中的
Schema.Error
类。签名中的每个错误都需是建议代码。列出错误的故事测试必须对该错误进行断言。

Services

Services

Context.Service
contracts. The
R
channel names these Services. Test Layers provide them and are not Proposed Code.
Context.Service
契约。
R
通道命名这些服务。测试用Layer提供这些服务,且不属于建议代码。

Effectful function signatures

Effectful函数签名

Write the full signature and call it from the tests:
ts
(input: Input): Effect.Effect<Success, Error, Service>
编写完整的签名并在测试中调用:
ts
(input: Input): Effect.Effect<Success, Error, Service>

Story tests

故事测试

Each story owns at least one
@effect/vitest
property. Generate from the exact proposed Schema. Provide a fresh Service Layer per generated case. Call the exact proposed function. Assert the caller-visible success or Error. Each signature lists its input Schema, success Schema, Errors, and Services; each test lists those same IDs.
ts
import { assert, it } from "@effect/vitest"
import { Effect } from "effect"
import { CreateTaskInput } from "../domain/task"
import { createTask, listTasks, makeTaskService } from "../domain/task-service"

it.effect.prop("creates every valid generated task as incomplete", [CreateTaskInput], ([input]) =>
  Effect.gen(function* () {
    const layer = yield* makeTaskService([])
    const created = yield* createTask(input).pipe(Effect.provide(layer))
    const tasks = yield* listTasks.pipe(Effect.provide(layer))

    assert.strictEqual(created.title, input.title)
    assert.isFalse(created.completed)
    assert.deepStrictEqual(tasks, [created])
  }), { fastCheck: { numRuns: 25 } })
Keep one test file per property so the whole file is the editable range.
每个故事至少包含一个
@effect/vitest
属性。从精确的建议Schema生成测试用例。为每个生成的用例提供全新的Service Layer。调用精确的建议函数。断言调用者可见的成功结果或错误。每个签名都会列出其输入Schema、成功Schema、错误和服务;每个测试也会列出相同的ID。
ts
import { assert, it } from "@effect/vitest"
import { Effect } from "effect"
import { CreateTaskInput } from "../domain/task"
import { createTask, listTasks, makeTaskService } from "../domain/task-service"

it.effect.prop("creates every valid generated task as incomplete", [CreateTaskInput], ([input]) =>
  Effect.gen(function* () {
    const layer = yield* makeTaskService([])
    const created = yield* createTask(input).pipe(Effect.provide(layer))
    const tasks = yield* listTasks.pipe(Effect.provide(layer))

    assert.strictEqual(created.title, input.title)
    assert.isFalse(created.completed)
    assert.deepStrictEqual(tasks, [created])
  }), { fastCheck: { numRuns: 25 } })
每个属性对应一个测试文件,这样整个文件都是可编辑范围。

Workflow

工作流程

1. Name the stories

1. 命名故事

Keep authored story order. For each story, state the caller-visible outcome and the Schema, Error, Service, and function IDs it exercises.
保留编写的故事顺序。对于每个故事,说明调用者可见的结果,以及它所涉及的Schema、错误、服务和函数ID。

2. Create the artifact

2. 创建工件

sh
node scripts/create-plan.mjs <artifact-destination>
Replace plan data, story tests, proposed domain code, and theme tokens. Keep the shared review shell and review server.
sh
node scripts/create-plan.mjs <artifact-destination>
替换计划数据、故事测试、建议的领域代码和主题令牌。保留共享的评审外壳和评审服务器。

3. Fill the four contracts, then the tests

3. 填充四项契约,然后编写测试

Write Schemas, Errors, Services, and signatures first. Then write
it.effect.prop
tests that generate from those Schemas and call those functions.
先编写Schemas、Errors、Services和签名。然后编写
it.effect.prop
测试,从这些Schema生成用例并调用相应函数。

4. Review in the browser

4. 在浏览器中评审

Story Tests runs and edits each property. Proposed Code edits the four contract groups. Saving a test resets that test. Saving a contract resets every linked test. Approval stays off until every current test passes.
Goodhart's Law: green tests are evidence. The human decision is the result.
Story Tests运行并编辑每个属性。Proposed Code编辑四类契约组。保存测试会重置该测试。保存契约会重置所有关联测试。只有当所有当前测试通过后,才能进行审批。
古德哈特定律:绿色测试是证据。最终结果由人工决策决定。

5. Pause for the human

5. 等待人工确认

Keep one decision control and one Export review action. Never infer approval.
保留一个决策控件和一个导出评审操作。绝不自动推断审批状态。

Completion

完成

Return:
  • The browser URL
  • The artifact path
  • The current source-snapshot ID
  • The story-test result summary
  • The one next human action
返回:
  • 浏览器URL
  • 工件路径
  • 当前源代码快照ID
  • 故事测试结果摘要
  • 下一步人工操作