executable-interactive-plans
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseExecutable Interactive Plans
可执行交互式计划
The plan is agreement on four Effect contracts, proven by executable story tests.
The human reviews two questions:
- Do these tests express the behavior I want?
- 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契约的共识,由可执行的故事测试来验证。
人工评审需确认两个问题:
- 这些测试是否准确表达了我想要的行为?
- 这些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.
将建议代码分为Schemas、Errors、Services和Effectful函数四类。每个条目都需写成可编辑的精确源代码。
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.ErrorE出现在通道中的类。签名中的每个错误都需是建议代码。列出错误的故事测试必须对该错误进行断言。
ESchema.ErrorServices
Services
Context.ServiceRContext.ServiceREffectful 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 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.
@effect/vitestts
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.
每个故事至少包含一个属性。从精确的建议Schema生成测试用例。为每个生成的用例提供全新的Service Layer。调用精确的建议函数。断言调用者可见的成功结果或错误。每个签名都会列出其输入Schema、成功Schema、错误和服务;每个测试也会列出相同的ID。
@effect/vitestts
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 tests that generate from those Schemas and call those functions.
it.effect.prop先编写Schemas、Errors、Services和签名。然后编写测试,从这些Schema生成用例并调用相应函数。
it.effect.prop4. 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
- 故事测试结果摘要
- 下一步人工操作