@sayoriqwq/effect-harness 0.0.4 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -77
- package/diagnostics/effect-routes.md +6 -0
- package/diagnostics/index.md +10 -0
- package/diagnostics/tsgo-routes.md +5 -0
- package/dist/src/eslint.d.ts +57 -0
- package/dist/src/eslint.js +42 -0
- package/dist/src/eslint.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/prelude.d.ts +6 -0
- package/dist/src/prelude.js +161 -0
- package/dist/src/prelude.js.map +1 -0
- package/package.json +25 -17
- package/prelude-assets/effect/managed/docs/diagnostics.md +6 -0
- package/prelude-assets/effect/managed/docs/editor-policy.md +5 -0
- package/prelude-assets/effect/managed/docs/effect-code.md +5 -0
- package/prelude-assets/effect/managed/docs/index.md +14 -0
- package/prelude-assets/effect/managed/docs/managed-surfaces.md +5 -0
- package/prelude-assets/effect/managed/docs/package-config.md +20 -0
- package/prelude-assets/effect/managed/docs/quality-policy.md +5 -0
- package/prelude-assets/effect/managed/docs/source-identity.md +5 -0
- package/prelude-assets/guidance/eslint.md +15 -0
- package/repos/effect.subtree.json +2 -2
- package/repos/tsgo.subtree.json +2 -2
- package/HARNESS.md +0 -66
- package/dist/bin/effect-harness.d.ts +0 -2
- package/dist/bin/effect-harness.js +0 -34
- package/dist/bin/effect-harness.js.map +0 -1
- package/dist/src/cli/Main.d.ts +0 -7
- package/dist/src/cli/Main.js +0 -45
- package/dist/src/cli/Main.js.map +0 -1
- package/dist/src/harness/Errors.d.ts +0 -24
- package/dist/src/harness/Errors.js +0 -26
- package/dist/src/harness/Errors.js.map +0 -1
- package/dist/src/harness/Guardrails.d.ts +0 -7
- package/dist/src/harness/Guardrails.js +0 -50
- package/dist/src/harness/Guardrails.js.map +0 -1
- package/dist/src/harness/Model.d.ts +0 -52
- package/dist/src/harness/Model.js +0 -170
- package/dist/src/harness/Model.js.map +0 -1
- package/dist/src/harness/ModuleSources.d.ts +0 -5
- package/dist/src/harness/ModuleSources.js +0 -47
- package/dist/src/harness/ModuleSources.js.map +0 -1
- package/dist/src/harness/ProviderDiscovery.d.ts +0 -172
- package/dist/src/harness/ProviderDiscovery.js +0 -157
- package/dist/src/harness/ProviderDiscovery.js.map +0 -1
- package/dist/src/harness/SourcePin.d.ts +0 -4
- package/dist/src/harness/SourcePin.js +0 -214
- package/dist/src/harness/SourcePin.js.map +0 -1
- package/dist/src/harness/verify/JsonFields.d.ts +0 -1
- package/dist/src/harness/verify/JsonFields.js +0 -4
- package/dist/src/harness/verify/JsonFields.js.map +0 -1
- package/dist/src/harness/verify/Pipeline.d.ts +0 -7
- package/dist/src/harness/verify/Pipeline.js +0 -55
- package/dist/src/harness/verify/Pipeline.js.map +0 -1
- package/dist/src/harness/verify/ProviderProfile.d.ts +0 -3
- package/dist/src/harness/verify/ProviderProfile.js +0 -726
- package/dist/src/harness/verify/ProviderProfile.js.map +0 -1
- package/dist/src/harness/verify/ProviderRepository.d.ts +0 -4
- package/dist/src/harness/verify/ProviderRepository.js +0 -127
- package/dist/src/harness/verify/ProviderRepository.js.map +0 -1
- package/dist/src/harness/verify/Tsgo.d.ts +0 -3
- package/dist/src/harness/verify/Tsgo.js +0 -166
- package/dist/src/harness/verify/Tsgo.js.map +0 -1
- package/dist/src/harness/verify/TsgoMetadata.d.ts +0 -4
- package/dist/src/harness/verify/TsgoMetadata.js +0 -50
- package/dist/src/harness/verify/TsgoMetadata.js.map +0 -1
- package/dist/src/harness/verify/TsgoPolicy.d.ts +0 -208
- package/dist/src/harness/verify/TsgoPolicy.js +0 -143
- package/dist/src/harness/verify/TsgoPolicy.js.map +0 -1
- package/dist/src/harness/verify/TsgoSuppressions.d.ts +0 -2
- package/dist/src/harness/verify/TsgoSuppressions.js +0 -24
- package/dist/src/harness/verify/TsgoSuppressions.js.map +0 -1
- package/dist/src/harness/verify/VerifyStage.d.ts +0 -62
- package/dist/src/harness/verify/VerifyStage.js +0 -85
- package/dist/src/harness/verify/VerifyStage.js.map +0 -1
- package/dist/src/platform/Json.d.ts +0 -4
- package/dist/src/platform/Json.js +0 -16
- package/dist/src/platform/Json.js.map +0 -1
- package/dist/src/platform/Process.d.ts +0 -6
- package/dist/src/platform/Process.js +0 -35
- package/dist/src/platform/Process.js.map +0 -1
- package/harness/code.md +0 -83
- package/harness/diagnostic-layers.md +0 -94
- package/harness/effect-routes.md +0 -50
- package/harness/feedback-loop.md +0 -156
- package/harness/index.md +0 -83
- package/harness/offcial-guide.md +0 -50
- package/harness/offcial-migrate.md +0 -220
- package/harness/source.md +0 -91
- package/harness/tsgo-routes.md +0 -58
- package/harness/tsgo.md +0 -241
- package/provider/docs/diagnostics.md +0 -48
- package/provider/docs/discovery.md +0 -104
- package/provider/docs/editor-policy.md +0 -55
- package/provider/docs/effect-code.md +0 -41
- package/provider/docs/index.md +0 -48
- package/provider/docs/managed-surfaces.md +0 -51
- package/provider/docs/package-config.md +0 -71
- package/provider/docs/quality-policy.md +0 -68
- package/provider/docs/source-identity.md +0 -48
- package/provider/effect-harness.provider.json +0 -1020
- package/provider/index.md +0 -189
- package/provider/snippets/agents.md +0 -34
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { Data, Schema } from 'effect';
|
|
2
|
-
const VerifyStageTagSchema = Schema.Literals([
|
|
3
|
-
'source-pins',
|
|
4
|
-
'harness-contract',
|
|
5
|
-
'tsgo-diagnostics',
|
|
6
|
-
'tests',
|
|
7
|
-
'lint',
|
|
8
|
-
'knip',
|
|
9
|
-
]);
|
|
10
|
-
const isVerifyStageTag = Schema.is(VerifyStageTagSchema);
|
|
11
|
-
export const verifyStageSpecs = [
|
|
12
|
-
{
|
|
13
|
-
tag: 'source-pins',
|
|
14
|
-
title: 'Source Pins',
|
|
15
|
-
routes: ['harness/source.md'],
|
|
16
|
-
summary: 'Verify pinned GitHub subtree source entries.',
|
|
17
|
-
routeHint: 'Read the source-entry contract and fix Partita source pin drift.',
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
tag: 'harness-contract',
|
|
21
|
-
title: 'Harness Contract',
|
|
22
|
-
routes: ['harness/index.md', 'harness/offcial-migrate.md', 'harness/feedback-loop.md'],
|
|
23
|
-
summary: 'Verify the provider repository contract and current harness baseline.',
|
|
24
|
-
routeHint: 'Read the harness index, migrate notes, and feedback loop contract before changing verifier behavior.',
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
tag: 'tsgo-diagnostics',
|
|
28
|
-
title: 'Tsgo Diagnostics',
|
|
29
|
-
routes: ['harness/tsgo.md', 'harness/tsgo-routes.md'],
|
|
30
|
-
summary: 'Run tsgo --noEmit and enforce zero Effect diagnostics.',
|
|
31
|
-
routeHint: 'Use the tsgo diagnostic output first; read the tsgo policy and routes only when the diagnostic is not enough.',
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
tag: 'tests',
|
|
35
|
-
title: 'Tests',
|
|
36
|
-
routes: ['harness/effect-routes.md'],
|
|
37
|
-
summary: 'Run the Effect test suite.',
|
|
38
|
-
routeHint: 'Read the Effect testing route and fix behavior through @effect/vitest patterns.',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
tag: 'lint',
|
|
42
|
-
title: 'Lint',
|
|
43
|
-
routes: ['harness/diagnostic-layers.md', 'AGENTS.md', 'eslint.config.mjs'],
|
|
44
|
-
summary: 'Run ESLint with zero warnings.',
|
|
45
|
-
routeHint: 'Read the diagnostic layering contract, agent rules, and lint config, then fix repository boundary violations without duplicating tsgo semantics.',
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
tag: 'knip',
|
|
49
|
-
title: 'Knip',
|
|
50
|
-
routes: ['package.json'],
|
|
51
|
-
summary: 'Run knip and keep the package surface minimal.',
|
|
52
|
-
routeHint: 'Read package.json and source imports/exports, then remove unused package surface.',
|
|
53
|
-
},
|
|
54
|
-
];
|
|
55
|
-
export const requiredFeedbackLoopKeywords = [
|
|
56
|
-
'BASELINE',
|
|
57
|
-
'ROUTE_TABLE',
|
|
58
|
-
'VERIFY_PIPELINE',
|
|
59
|
-
...verifyStageSpecs.map(spec => stageKeyword(spec.tag)),
|
|
60
|
-
'DONE',
|
|
61
|
-
];
|
|
62
|
-
export class VerifyStageFailed extends Data.TaggedError('@sayoriqwq/effect-harness/harness/verify/VerifyStage/VerifyStageFailed') {
|
|
63
|
-
get message() {
|
|
64
|
-
return [
|
|
65
|
-
`verify failed at ${this.stageTag} (${this.stageTitle})`,
|
|
66
|
-
'',
|
|
67
|
-
'route:',
|
|
68
|
-
...this.routes.map(route => `- ${route}`),
|
|
69
|
-
'',
|
|
70
|
-
'next:',
|
|
71
|
-
this.routeHint,
|
|
72
|
-
'',
|
|
73
|
-
'cause:',
|
|
74
|
-
this.causeMessage,
|
|
75
|
-
].join('\n');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
function stageKeyword(tag) {
|
|
79
|
-
return `STAGE_${tag.replaceAll('-', '_').toUpperCase()}`;
|
|
80
|
-
}
|
|
81
|
-
export function stageSpecByTag(tag) {
|
|
82
|
-
const verifiedTag = isVerifyStageTag(tag) ? tag : 'source-pins';
|
|
83
|
-
return verifyStageSpecs.find(spec => spec.tag === verifiedTag);
|
|
84
|
-
}
|
|
85
|
-
//# sourceMappingURL=VerifyStage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VerifyStage.js","sourceRoot":"","sources":["../../../../src/harness/verify/VerifyStage.ts"],"names":[],"mappings":"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","sourcesContent":["import { Data, Schema } from 'effect'\n\nexport interface VerifyStageSpec {\n readonly tag: VerifyStageTag\n readonly title: string\n readonly routes: ReadonlyArray<string>\n readonly summary: string\n readonly routeHint: string\n}\n\nconst VerifyStageTagSchema = Schema.Literals([\n 'source-pins',\n 'harness-contract',\n 'tsgo-diagnostics',\n 'tests',\n 'lint',\n 'knip',\n] as const)\n\nexport type VerifyStageTag = typeof VerifyStageTagSchema.Type\nconst isVerifyStageTag = Schema.is(VerifyStageTagSchema)\n\nexport const verifyStageSpecs = [\n {\n tag: 'source-pins',\n title: 'Source Pins',\n routes: ['harness/source.md'],\n summary: 'Verify pinned GitHub subtree source entries.',\n routeHint: 'Read the source-entry contract and fix Partita source pin drift.',\n },\n {\n tag: 'harness-contract',\n title: 'Harness Contract',\n routes: ['harness/index.md', 'harness/offcial-migrate.md', 'harness/feedback-loop.md'],\n summary: 'Verify the provider repository contract and current harness baseline.',\n routeHint: 'Read the harness index, migrate notes, and feedback loop contract before changing verifier behavior.',\n },\n {\n tag: 'tsgo-diagnostics',\n title: 'Tsgo Diagnostics',\n routes: ['harness/tsgo.md', 'harness/tsgo-routes.md'],\n summary: 'Run tsgo --noEmit and enforce zero Effect diagnostics.',\n routeHint: 'Use the tsgo diagnostic output first; read the tsgo policy and routes only when the diagnostic is not enough.',\n },\n {\n tag: 'tests',\n title: 'Tests',\n routes: ['harness/effect-routes.md'],\n summary: 'Run the Effect test suite.',\n routeHint: 'Read the Effect testing route and fix behavior through @effect/vitest patterns.',\n },\n {\n tag: 'lint',\n title: 'Lint',\n routes: ['harness/diagnostic-layers.md', 'AGENTS.md', 'eslint.config.mjs'],\n summary: 'Run ESLint with zero warnings.',\n routeHint: 'Read the diagnostic layering contract, agent rules, and lint config, then fix repository boundary violations without duplicating tsgo semantics.',\n },\n {\n tag: 'knip',\n title: 'Knip',\n routes: ['package.json'],\n summary: 'Run knip and keep the package surface minimal.',\n routeHint: 'Read package.json and source imports/exports, then remove unused package surface.',\n },\n] as const satisfies ReadonlyArray<VerifyStageSpec>\n\nexport const requiredFeedbackLoopKeywords = [\n 'BASELINE',\n 'ROUTE_TABLE',\n 'VERIFY_PIPELINE',\n ...verifyStageSpecs.map(spec => stageKeyword(spec.tag)),\n 'DONE',\n] as const\n\nexport class VerifyStageFailed extends Data.TaggedError('@sayoriqwq/effect-harness/harness/verify/VerifyStage/VerifyStageFailed')<{\n readonly causeMessage: string\n readonly routeHint: string\n readonly routes: ReadonlyArray<string>\n readonly stageTag: VerifyStageTag\n readonly stageTitle: string\n}> {\n override get message(): string {\n return [\n `verify failed at ${this.stageTag} (${this.stageTitle})`,\n '',\n 'route:',\n ...this.routes.map(route => `- ${route}`),\n '',\n 'next:',\n this.routeHint,\n '',\n 'cause:',\n this.causeMessage,\n ].join('\\n')\n }\n}\n\nfunction stageKeyword(tag: VerifyStageTag): string {\n return `STAGE_${tag.replaceAll('-', '_').toUpperCase()}`\n}\n\nexport function stageSpecByTag(tag: VerifyStageTag): VerifyStageSpec {\n const verifiedTag = isVerifyStageTag(tag) ? tag : 'source-pins'\n return verifyStageSpecs.find(spec => spec.tag === verifiedTag)!\n}\n"]}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { PlatformError } from 'effect';
|
|
2
|
-
import { Effect, FileSystem } from 'effect';
|
|
3
|
-
import { HarnessError } from '../harness/Errors.ts';
|
|
4
|
-
export declare function readJson<A>(source: string, decode: (value: unknown, source: string) => Effect.Effect<A, HarnessError>): Effect.Effect<A, HarnessError | PlatformError.PlatformError, FileSystem.FileSystem>;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Effect, FileSystem, Schema } from 'effect';
|
|
2
|
-
import { errorMessage, HarnessError } from "../harness/Errors.js";
|
|
3
|
-
function parseJson(text, source, decode) {
|
|
4
|
-
return Effect.gen(function* () {
|
|
5
|
-
const value = yield* Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(text).pipe(Effect.mapError(error => new HarnessError({ cause: error, message: `Cannot parse JSON at ${source}: ${errorMessage(error)}` })));
|
|
6
|
-
return yield* decode(value, source);
|
|
7
|
-
});
|
|
8
|
-
}
|
|
9
|
-
export function readJson(source, decode) {
|
|
10
|
-
return Effect.gen(function* () {
|
|
11
|
-
const fs = yield* FileSystem.FileSystem;
|
|
12
|
-
const text = yield* fs.readFileString(source);
|
|
13
|
-
return yield* parseJson(text, source, decode);
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=Json.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Json.js","sourceRoot":"","sources":["../../../src/platform/Json.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEjE,SAAS,SAAS,CAAI,IAAY,EAAE,MAAc,EAAE,MAA0E;IAC5H,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACtF,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,wBAAwB,MAAM,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAChI,CAAA;QACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,MAAc,EACd,MAA0E;IAE1E,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAA;QACvC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QAC7C,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type { PlatformError } from 'effect'\nimport { Effect, FileSystem, Schema } from 'effect'\nimport { errorMessage, HarnessError } from '../harness/Errors.ts'\n\nfunction parseJson<A>(text: string, source: string, decode: (value: unknown, source: string) => Effect.Effect<A, HarnessError>): Effect.Effect<A, HarnessError> {\n return Effect.gen(function* () {\n const value = yield* Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(text).pipe(\n Effect.mapError(error => new HarnessError({ cause: error, message: `Cannot parse JSON at ${source}: ${errorMessage(error)}` })),\n )\n return yield* decode(value, source)\n })\n}\n\nexport function readJson<A>(\n source: string,\n decode: (value: unknown, source: string) => Effect.Effect<A, HarnessError>,\n): Effect.Effect<A, HarnessError | PlatformError.PlatformError, FileSystem.FileSystem> {\n return Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem\n const text = yield* fs.readFileString(source)\n return yield* parseJson(text, source, decode)\n })\n}\n"]}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect';
|
|
2
|
-
import { ChildProcess, ChildProcessSpawner } from 'effect/unstable/process';
|
|
3
|
-
import { ProcessError } from '../harness/Errors.ts';
|
|
4
|
-
export declare const commandExitCode: (command: string, args: readonly string[], options?: ChildProcess.CommandOptions | undefined) => Effect.Effect<ChildProcessSpawner.ExitCode, import("effect/PlatformError").PlatformError, ChildProcessSpawner.ChildProcessSpawner>;
|
|
5
|
-
export declare const commandString: (command: string, args: readonly string[], options?: ChildProcess.CommandOptions | undefined) => Effect.Effect<string, ProcessError | import("effect/PlatformError").PlatformError, ChildProcessSpawner.ChildProcessSpawner>;
|
|
6
|
-
export declare const commandLines: (command: string, args: readonly string[], options?: ChildProcess.CommandOptions | undefined) => Effect.Effect<string[], ProcessError | import("effect/PlatformError").PlatformError, ChildProcessSpawner.ChildProcessSpawner>;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Effect, String as Str, Stream } from 'effect';
|
|
2
|
-
import { ChildProcess, ChildProcessSpawner } from 'effect/unstable/process';
|
|
3
|
-
import { ProcessError } from "../harness/Errors.js";
|
|
4
|
-
export const commandExitCode = Effect.fnUntraced(function* (command, args, options) {
|
|
5
|
-
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
6
|
-
return yield* spawner.exitCode(ChildProcess.make(command, args, options));
|
|
7
|
-
});
|
|
8
|
-
export const commandString = Effect.fnUntraced(function* (command, args, options) {
|
|
9
|
-
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
10
|
-
return yield* Effect.scoped(Effect.gen(function* () {
|
|
11
|
-
const handle = yield* spawner.spawn(ChildProcess.make(command, args, options));
|
|
12
|
-
const [stdout, stderr] = yield* Effect.all([
|
|
13
|
-
Stream.mkString(Stream.decodeText(handle.stdout)),
|
|
14
|
-
Stream.mkString(Stream.decodeText(handle.stderr)),
|
|
15
|
-
]);
|
|
16
|
-
const exitCode = yield* handle.exitCode;
|
|
17
|
-
if (exitCode !== ChildProcessSpawner.ExitCode(0)) {
|
|
18
|
-
return yield* new ProcessError({
|
|
19
|
-
args,
|
|
20
|
-
command,
|
|
21
|
-
...(options?.cwd !== undefined ? { cwd: options.cwd } : {}),
|
|
22
|
-
exitCode: Number(exitCode),
|
|
23
|
-
message: `${command} ${args.join(' ')} failed with exit code ${exitCode}`,
|
|
24
|
-
stderr,
|
|
25
|
-
stdout,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
return Str.trim(stdout);
|
|
29
|
-
}));
|
|
30
|
-
});
|
|
31
|
-
export const commandLines = Effect.fnUntraced(function* (command, args, options) {
|
|
32
|
-
const output = yield* commandString(command, args, options);
|
|
33
|
-
return output.length === 0 ? [] : output.split('\n');
|
|
34
|
-
});
|
|
35
|
-
//# sourceMappingURL=Process.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Process.js","sourceRoot":"","sources":["../../../src/platform/Process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAInD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACxD,OAAe,EACf,IAA2B,EAC3B,OAAwB;IAExB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,mBAAmB,CAAA;IAC9D,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;AAC3E,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACtD,OAAe,EACf,IAA2B,EAC3B,OAAwB;IAExB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,mBAAmB,CAAA;IAC9D,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;QAC9E,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YACzC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACjD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SAClD,CAAC,CAAA;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAA;QACvC,IAAI,QAAQ,KAAK,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC;gBAC7B,IAAI;gBACJ,OAAO;gBACP,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3D,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;gBAC1B,OAAO,EAAE,GAAG,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,0BAA0B,QAAQ,EAAE;gBACzE,MAAM;gBACN,MAAM;aACP,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACzB,CAAC,CAAC,CAAC,CAAA;AACL,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACrD,OAAe,EACf,IAA2B,EAC3B,OAAwB;IAExB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC3D,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AACtD,CAAC,CAAC,CAAA","sourcesContent":["import { Effect, String as Str, Stream } from 'effect'\nimport { ChildProcess, ChildProcessSpawner } from 'effect/unstable/process'\nimport { ProcessError } from '../harness/Errors.ts'\n\ntype CommandOptions = ChildProcess.CommandOptions\n\nexport const commandExitCode = Effect.fnUntraced(function* (\n command: string,\n args: ReadonlyArray<string>,\n options?: CommandOptions,\n) {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n return yield* spawner.exitCode(ChildProcess.make(command, args, options))\n})\n\nexport const commandString = Effect.fnUntraced(function* (\n command: string,\n args: ReadonlyArray<string>,\n options?: CommandOptions,\n) {\n const spawner = yield* ChildProcessSpawner.ChildProcessSpawner\n return yield* Effect.scoped(Effect.gen(function* () {\n const handle = yield* spawner.spawn(ChildProcess.make(command, args, options))\n const [stdout, stderr] = yield* Effect.all([\n Stream.mkString(Stream.decodeText(handle.stdout)),\n Stream.mkString(Stream.decodeText(handle.stderr)),\n ])\n const exitCode = yield* handle.exitCode\n if (exitCode !== ChildProcessSpawner.ExitCode(0)) {\n return yield* new ProcessError({\n args,\n command,\n ...(options?.cwd !== undefined ? { cwd: options.cwd } : {}),\n exitCode: Number(exitCode),\n message: `${command} ${args.join(' ')} failed with exit code ${exitCode}`,\n stderr,\n stdout,\n })\n }\n return Str.trim(stdout)\n }))\n})\n\nexport const commandLines = Effect.fnUntraced(function* (\n command: string,\n args: ReadonlyArray<string>,\n options?: CommandOptions,\n) {\n const output = yield* commandString(command, args, options)\n return output.length === 0 ? [] : output.split('\\n')\n})\n"]}
|
package/harness/code.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
audience: [agent, human]
|
|
3
|
-
authors:
|
|
4
|
-
- codex
|
|
5
|
-
reviewed_by: []
|
|
6
|
-
purpose: 说明 effect-harness 仓内 TypeScript 代码的职责和非职责。
|
|
7
|
-
status: active
|
|
8
|
-
sources:
|
|
9
|
-
- src/cli/Main.ts
|
|
10
|
-
- src/harness/SourcePin.ts
|
|
11
|
-
- src/harness/verify/Pipeline.ts
|
|
12
|
-
- src/harness/verify/ProviderProfile.ts
|
|
13
|
-
- src/harness/verify/ProviderRepository.ts
|
|
14
|
-
- src/harness/verify/Tsgo.ts
|
|
15
|
-
- tests/effect-provider-profile.test.ts
|
|
16
|
-
- tests/effect-source-subtree.test.ts
|
|
17
|
-
updated: 2026-07-02
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
# Code Surface
|
|
21
|
-
|
|
22
|
-
## Boundary
|
|
23
|
-
|
|
24
|
-
`src/` 和 `bin/` 不是 target runtime,也不是业务 Effect application。
|
|
25
|
-
|
|
26
|
-
这些代码服务 effect-harness 本仓验证、provider profile hard gate、source pin hard gate 和 CLI
|
|
27
|
-
package entrypoint。
|
|
28
|
-
|
|
29
|
-
## CLI
|
|
30
|
-
|
|
31
|
-
`bin/effect-harness.ts` 是 npm package 的 executable entry。
|
|
32
|
-
|
|
33
|
-
`src/cli/Main.ts` 暴露三个命令:
|
|
34
|
-
|
|
35
|
-
| Command | Purpose |
|
|
36
|
-
| --- | --- |
|
|
37
|
-
| `verify --harness <path>` | 运行完整 provider repository verify pipeline。 |
|
|
38
|
-
| `provider-verify --harness <path>` | 验证 provider repository contract 和 source pin。 |
|
|
39
|
-
| `source-verify --harness <path>` | 验证 Effect/tsgo source pin contract。 |
|
|
40
|
-
|
|
41
|
-
CLI 使用 `effect/unstable/cli`,不使用旧 `@effect/cli`。
|
|
42
|
-
|
|
43
|
-
## Verify
|
|
44
|
-
|
|
45
|
-
`src/harness/verify/Pipeline.ts` 定义 `pnpm verify` 的 stage 顺序。
|
|
46
|
-
|
|
47
|
-
`src/harness/verify/VerifyStage.ts` 定义 stage metadata、route 和 failure message。`harness/feedback-loop.md`
|
|
48
|
-
必须跟它保持一致。
|
|
49
|
-
|
|
50
|
-
`src/harness/verify/ProviderRepository.ts` 验证当前仓库没有恢复 legacy provider surface,并把 provider
|
|
51
|
-
profile、tsgo policy、source pin 和 import boundary 串起来。
|
|
52
|
-
|
|
53
|
-
`src/harness/verify/ProviderProfile.ts` 验证 provider profile 的 contract,包括 package baseline、
|
|
54
|
-
source identity、managed surfaces、docs bundle 和 snippets。
|
|
55
|
-
|
|
56
|
-
## Source
|
|
57
|
-
|
|
58
|
-
`src/harness/SourcePin.ts` 验证 `repos/effect.subtree.json` 和 `repos/tsgo.subtree.json`:
|
|
59
|
-
|
|
60
|
-
- source prefix 必须存在。
|
|
61
|
-
- source prefix 必须是 committed Git tree entry。
|
|
62
|
-
- Git history 必须包含匹配 split 的 subtree trailer。
|
|
63
|
-
- anchor 和 route 必须存在。
|
|
64
|
-
- 应用代码和测试代码不能 import provider-internal source tree。
|
|
65
|
-
- package baseline 不能和 provider profile 漂移。
|
|
66
|
-
|
|
67
|
-
## Tsgo
|
|
68
|
-
|
|
69
|
-
`src/harness/verify/Tsgo.ts`、`TsgoPolicy.ts`、`TsgoMetadata.ts` 和 `TsgoSuppressions.ts` 维护 strict
|
|
70
|
-
tsgo policy:
|
|
71
|
-
|
|
72
|
-
- `tsconfig.json` 与 provider profile 的 `@effect/language-service` plugin 必须一致。
|
|
73
|
-
- metadata 派生出的 v4 rule map 必须和本仓 strict policy 一致。
|
|
74
|
-
- 普通源码不能使用 Effect diagnostic suppress 注释绕过 gate。
|
|
75
|
-
- `effect-tsgo --version` 和 `tsgo --version` 必须匹配当前 baseline。
|
|
76
|
-
|
|
77
|
-
## Tests
|
|
78
|
-
|
|
79
|
-
`tests/effect-provider-profile.test.ts` 约束 provider profile shape。
|
|
80
|
-
|
|
81
|
-
`tests/effect-source-subtree.test.ts` 约束 source pin verifier 的 failure cases。
|
|
82
|
-
|
|
83
|
-
这些测试是 harness contract regression tests,不是 target 项目的模板测试。
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
audience: [agent, human]
|
|
3
|
-
authors:
|
|
4
|
-
- codex
|
|
5
|
-
reviewed_by: []
|
|
6
|
-
purpose: 定义 tsgo diagnostics、ESLint 和 harness guardrails 的分层职责。
|
|
7
|
-
status: active
|
|
8
|
-
sources:
|
|
9
|
-
- harness/feedback-loop.md
|
|
10
|
-
- harness/tsgo.md
|
|
11
|
-
- harness/tsgo-routes.md
|
|
12
|
-
- src/harness/verify/Pipeline.ts
|
|
13
|
-
- src/harness/verify/VerifyStage.ts
|
|
14
|
-
- src/harness/verify/TsgoPolicy.ts
|
|
15
|
-
- src/harness/Guardrails.ts
|
|
16
|
-
- eslint.config.mjs
|
|
17
|
-
updated: 2026-07-01
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
# Diagnostic Layers
|
|
21
|
-
|
|
22
|
-
## CONTRACT
|
|
23
|
-
|
|
24
|
-
`pnpm verify` 的分层真源是 `src/harness/verify/Pipeline.ts`。pipeline 按
|
|
25
|
-
`source-pins`、`harness-contract`、`tsgo-diagnostics`、`tests`、`lint`、`knip`
|
|
26
|
-
顺序 fail-fast 执行。
|
|
27
|
-
|
|
28
|
-
分层原则是每一层只负责自己的事情:
|
|
29
|
-
|
|
30
|
-
- `tsgo-diagnostics` 负责 TypeScript + Effect 语义诊断。
|
|
31
|
-
- `tests` 负责行为回归。
|
|
32
|
-
- `lint` 负责仓库边界、导入制度、测试入口和本地 syntax-level guardrails。
|
|
33
|
-
- `knip` 负责 package surface 最小化。
|
|
34
|
-
|
|
35
|
-
如果 `tsgo-diagnostics` 和 `lint` 对同一段 Effect 写法给出冲突要求,MUST 服从 tsgo,并收窄
|
|
36
|
-
ESLint。ESLint 不应该禁止 tsgo quickfix 或 suggestion 推荐的 Effect API。
|
|
37
|
-
|
|
38
|
-
## TSGO_OWNS
|
|
39
|
-
|
|
40
|
-
`tsgo --noEmit` 是 Effect 语义 feedback 的主入口。本仓 strict profile 覆盖 pinned
|
|
41
|
-
`repos/tsgo/_packages/tsgo/src/metadata.json` 中所有支持 v4 的 rule,并让 error、warning、
|
|
42
|
-
suggestion 都参与 exit-code hard gate。
|
|
43
|
-
|
|
44
|
-
tsgo owns:
|
|
45
|
-
|
|
46
|
-
- Effect error/context/layer channels,例如 missing error、missing context、missing layer。
|
|
47
|
-
- Effect generator、`yield*`、`Effect.fn`、`Effect.gen` 和 pipe 语义。
|
|
48
|
-
- Effect-native API 偏好,例如 Clock、Random、Config、HttpClient、Schema JSON、typed errors。
|
|
49
|
-
- Schema class、Schema number、Schema tagged shape 和 constructor 语义。
|
|
50
|
-
- v4 API drift、deterministic keys、service/error/custom key policy。
|
|
51
|
-
- type-aware Effect unsafe assertions and leaking requirements。
|
|
52
|
-
|
|
53
|
-
这些规则不要在 ESLint 中重新实现。需要改变 Effect 语义约束时,先更新 `harness/tsgo.md`、
|
|
54
|
-
`src/harness/verify/TsgoPolicy.ts` 和 provider profile。
|
|
55
|
-
|
|
56
|
-
## ESLINT_OWNS
|
|
57
|
-
|
|
58
|
-
ESLint 是 lint stage 的入口。它只负责不需要 tsgo 类型语义、但必须快速阻断的仓库制度:
|
|
59
|
-
|
|
60
|
-
- import boundary:应用代码和测试代码不能从 `repos/effect` 或 `repos/tsgo` import。
|
|
61
|
-
- package baseline:不使用 `@effect/cli`,CLI 代码使用 `effect/unstable/cli`。
|
|
62
|
-
- test entry:本仓测试使用 `@effect/vitest`,不使用 `node:test` 或从 `vitest` 导入普通测试入口。
|
|
63
|
-
- harness baseline:当前 service definition baseline 不新增 `Context.Tag` service definition。
|
|
64
|
-
- syntax-level bans:只有当 tsgo 没有对应 rule,且规则是本仓制度时才放进 ESLint。例如
|
|
65
|
-
`{ disableValidation: true }` 禁令属于 lint 层。
|
|
66
|
-
|
|
67
|
-
ESLint MUST NOT own general Effect idioms that tsgo already owns。尤其不要禁止 `Effect.asVoid`:
|
|
68
|
-
当前 tsgo 的 `effectMapVoid` rule 会建议使用该 API。
|
|
69
|
-
|
|
70
|
-
## GUARDRAILS_OWN
|
|
71
|
-
|
|
72
|
-
`harness-contract` stage 里的 guardrails 是最后的仓库契约检查,不替代 ESLint。
|
|
73
|
-
|
|
74
|
-
Guardrails owns:
|
|
75
|
-
|
|
76
|
-
- provider-internal source pins 不能进入应用或测试 import。
|
|
77
|
-
- legacy provider surfaces 不能恢复。
|
|
78
|
-
- provider profile、source identity、package baseline 和 strict tsgo policy 不能漂移。
|
|
79
|
-
- 普通源码不能用 Effect diagnostic suppressions 关闭 strict policy。
|
|
80
|
-
|
|
81
|
-
当某个规则既需要编辑器即时反馈、又属于仓库硬边界时,可以同时存在于 ESLint 和
|
|
82
|
-
`harness-contract`。这种重复只用于提高反馈速度,不用于重新解释 Effect 语义。
|
|
83
|
-
|
|
84
|
-
## UPDATE_LOOP
|
|
85
|
-
|
|
86
|
-
新增或调整规则时按以下判断:
|
|
87
|
-
|
|
88
|
-
1. 如果规则依赖 Effect 类型、error/context/layer channel、Schema 语义或 Effect-native API,
|
|
89
|
-
放进 tsgo policy,不放进 ESLint。
|
|
90
|
-
2. 如果规则是 import、文件、测试入口、package baseline 或 provider boundary,放进 ESLint 或
|
|
91
|
-
harness guardrails。
|
|
92
|
-
3. 如果规则是 package surface,放进 knip stage。
|
|
93
|
-
4. 如果发现 ESLint 与 tsgo 冲突,删除或收窄 ESLint 规则。
|
|
94
|
-
5. 更新 `src/harness/verify/VerifyStage.ts` 的 route 后,同步更新 `harness/feedback-loop.md`。
|
package/harness/effect-routes.md
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# Effect 源码读取路线
|
|
2
|
-
|
|
3
|
-
本文件是 agent 读取 `repos/effect/` 的路线表。它不是通用 pin contract;通用外部真源接入由
|
|
4
|
-
Partita 负责。本仓只维护已经 pin 进来的 Effect 源入口实例,并把它整理成可读取、可核对、
|
|
5
|
-
可验证的参考入口。
|
|
6
|
-
|
|
7
|
-
## 读取边界
|
|
8
|
-
|
|
9
|
-
- `repos/effect/` 是 provider 仓内部只读参考源,目标仓库不接收这棵目录。
|
|
10
|
-
- 业务代码和测试代码只能从已安装 package import,禁止从 `repos/effect` import。
|
|
11
|
-
- `repos/effect/LLMS.md` 是上游 LLM guide,总是优先于零散猜测和 `node_modules`。
|
|
12
|
-
- GitHub subtree status/update/verify 借用 Partita CLI:`pnpm source:status`、
|
|
13
|
-
`pnpm source:update`、`pnpm source:verify`。
|
|
14
|
-
- Partita package CLI 已发布为 `@sayoriqwq/partita@0.1.0`;本仓 `source:*` scripts 通过
|
|
15
|
-
`npx --yes @sayoriqwq/partita pin ...` 执行,不依赖兄弟目录。
|
|
16
|
-
|
|
17
|
-
## 路线表
|
|
18
|
-
|
|
19
|
-
| Agent 意图 | 先读 | 深入核对 | 适用输出 | 注意 |
|
|
20
|
-
| --- | --- | --- | --- | --- |
|
|
21
|
-
| 判断当前源入口 pin 和 package 基线 | `repos/effect.subtree.json`、`provider/effect-harness.provider.json` | `pnpm-workspace.yaml` | 基线审计、provider drift 判断 | 本文档不声明最新状态;需要更新时走 Partita GitHub subtree 流程 |
|
|
22
|
-
| 理解本仓如何接入 Effect source | `harness/source.md` | `provider/index.md`、`harness/offcial-guide.md` | source-entry 维护、更新计划 | 这里是 Effect 实例,不是 Partita 通用 pin |
|
|
23
|
-
| 开始写 Effect 程序逻辑 | `repos/effect/LLMS.md` | `repos/effect/ai-docs/src/index.md`、`repos/effect/.patterns/effect.md` | 代码方案、重构方案 | 先按上游 guide 建模,再查具体 API |
|
|
24
|
-
| 查公开 API surface | `repos/effect/packages/effect/package.json` | `repos/effect/packages/effect/src/index.ts`、对应 `src/<Module>.ts` | import 建议、API 使用 | 不要建议 import `internal/*` 或 `*/index` 禁止项 |
|
|
25
|
-
| 查核心 Effect 写法 | `repos/effect/ai-docs/src/01_effect/01_basics/` | `repos/effect/packages/effect/src/Effect.ts`、`repos/effect/packages/effect/test/Effect.test.ts` | `Effect.gen`、`Effect.fn` 代码 | 失败/中断的 terminal effect 使用 `return yield*` |
|
|
26
|
-
| 设计服务和 Layer | `repos/effect/ai-docs/src/01_effect/02_services/` | `repos/effect/packages/effect/src/Context.ts`、`Layer.ts`、`LayerMap.ts` | service contract、Layer 组合 | 当前 baseline 使用 `Context.Service`,不要新增 `Context.Tag` 服务定义 |
|
|
27
|
-
| 处理错误 | `repos/effect/ai-docs/src/01_effect/03_errors/` | `repos/effect/packages/effect/src/Schema.ts`、`Cause.ts`、`Effect.ts` | typed error、recovery 逻辑 | 优先 `Schema.TaggedErrorClass` 和 `Effect.catch*` |
|
|
28
|
-
| 管理资源和 Scope | `repos/effect/ai-docs/src/01_effect/04_resources/` | `repos/effect/packages/effect/src/Scope.ts`、`Resource.ts`、`Layer.ts` | acquire/release、background layer | 不要用 ad hoc try/finally 代替 Effect resource model |
|
|
29
|
-
| 写 Node 入口 | `repos/effect/ai-docs/src/01_effect/05_running/10_run-main.ts` | `repos/effect/packages/platform-node/src/NodeRuntime.ts`、`NodeServices.ts` | CLI/server entrypoint | Node 目标项目使用 `NodeRuntime.runMain` |
|
|
30
|
-
| 写 CLI | `repos/effect/ai-docs/src/70_cli/10_basics.ts` | `repos/effect/packages/effect/src/unstable/cli/Command.ts`、`Flag.ts`、`Argument.ts`、`Param.ts` | command/flag/argument 设计 | 使用 `effect/unstable/cli`,不要依赖 `@effect/cli` |
|
|
31
|
-
| 写 Effect 测试 | `repos/effect/ai-docs/src/09_testing/` | `repos/effect/packages/vitest/src/`、`repos/effect/.patterns/testing.md`、相关 `packages/*/test/` | `@effect/vitest` 测试 | 用 `it.effect` 和 `assert`,不要用 `Effect.runSync` 测 Effect 程序 |
|
|
32
|
-
| 查模块行为细节 | 对应 `repos/effect/packages/effect/test/<Module>.test.ts` | `repos/effect/packages/effect/typetest/` | 行为断言、类型边界 | 测试是行为参考,不是目标代码的 import 来源 |
|
|
33
|
-
| 写 Stream / Sink / Channel | `repos/effect/ai-docs/src/02_stream/` | `repos/effect/packages/effect/src/Stream.ts`、`Sink.ts`、`Channel.ts` 及测试 | stream pipeline | 先看 ai-docs,再按源码核对 operator 类型 |
|
|
34
|
-
| 写 Schedule / DateTime / 时间逻辑 | `repos/effect/ai-docs/src/06_schedule/`、`07_datetime/` | `Schedule.ts`、`Cron.ts`、`DateTime.ts`、对应测试 | retry/repeat、时间处理 | 时间相关测试使用 TestClock |
|
|
35
|
-
| 写 Schema / JSON / encoding | `repos/effect/packages/effect/src/Schema.ts` | `SchemaParser.ts`、`JsonSchema.ts`、`unstable/encoding/`、schema tests | schema、codec、JSON schema | 复杂 schema 先查测试和 representation 目录 |
|
|
36
|
-
| 写 HTTP client/server | `repos/effect/ai-docs/src/50_http-client/`、`51_http-server/` | `repos/effect/packages/effect/src/unstable/http/`、`unstable/httpapi/`、`repos/effect/packages/platform-node/test/` | HttpClient、HttpApi、server layer | Node server 结合 `@effect/platform-node` 路由 |
|
|
37
|
-
| 写 Node 平台集成 | `repos/effect/packages/platform-node/src/index.ts` | `NodeFileSystem.ts`、`NodeHttpClient.ts`、`NodeHttpServer.ts`、`NodeStream.ts`、对应 tests | filesystem/http/stream/socket 集成 | import 来自 `@effect/platform-node` package,不来自 pinned source |
|
|
38
|
-
| 写 observability | `repos/effect/ai-docs/src/08_observability/` | `repos/effect/packages/effect/src/unstable/observability/`、`repos/effect/packages/opentelemetry/` | logging、metrics、tracing | 新项目优先看 Otlp 示例;已有 OTel 集成再看 opentelemetry package |
|
|
39
|
-
| 写 child process | `repos/effect/ai-docs/src/60_child-process/` | `repos/effect/packages/effect/src/unstable/process/`、`repos/effect/packages/platform-node/src/NodeChildProcessSpawner.ts` | 子进程、pipeline | 需要 Node implementation 时提供 `NodeServices.layer` |
|
|
40
|
-
| 写 AI 功能 | `repos/effect/ai-docs/src/71_ai/` | `repos/effect/packages/effect/src/unstable/ai/`、`repos/effect/packages/ai/*/src/` | LanguageModel、Tool、Chat | 区分 core unstable AI API 和 provider package |
|
|
41
|
-
| 写 Cluster / RPC / Workflow | `repos/effect/ai-docs/src/80_cluster/` | `unstable/cluster/`、`unstable/rpc/`、`unstable/workflow/`、相关 tests | entity、RPC、workflow 设计 | 高级模块先按上游测试核对生命周期和 storage 需求 |
|
|
42
|
-
| 写 SQL / persistence | `repos/effect/packages/effect/src/unstable/sql/`、`unstable/persistence/` | `repos/effect/packages/sql/*/README.md`、`package.json`、tests | SQL client、migrator、persistence | 需要具体 driver 时读对应 `@effect/sql-*` package |
|
|
43
|
-
| 参考上游仓开发约束 | `repos/effect/AGENTS.md` | `repos/effect/.patterns/`、`repos/effect/ai-docs/README.md` | 修改 pinned upstream 或评审上游风格 | 这些约束服务上游 repo 语境;不能覆盖本仓 provider 边界 |
|
|
44
|
-
|
|
45
|
-
## 目标项目接收边界
|
|
46
|
-
|
|
47
|
-
接入 effect-harness 的目标项目应得到 Effect v4 beta 基线、`tsgo --noEmit` 诊断路径、
|
|
48
|
-
`@effect/language-service` floatingEffect 约束、provider record 中的 source identity、provider
|
|
49
|
-
docs bundle 和 snippets。目标项目不应该得到 `repos/effect/` 本体、仓内 Codex skills、runtime
|
|
50
|
-
模板、反馈入口、`.effect-harness.json` 或 effect-harness 管理的 `AGENTS.md` 管理块。
|
package/harness/feedback-loop.md
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
audience: [agent, human]
|
|
3
|
-
authors:
|
|
4
|
-
- codex
|
|
5
|
-
reviewed_by: []
|
|
6
|
-
purpose: 定义 effect-harness 第二阶段的 Codex feedback loop 和统一 verify pipeline。
|
|
7
|
-
status: active
|
|
8
|
-
sources:
|
|
9
|
-
- AGENTS.md
|
|
10
|
-
- HARNESS.md
|
|
11
|
-
- harness/index.md
|
|
12
|
-
- harness/offcial-guide.md
|
|
13
|
-
- harness/offcial-migrate.md
|
|
14
|
-
- harness/source.md
|
|
15
|
-
- harness/effect-routes.md
|
|
16
|
-
- harness/tsgo.md
|
|
17
|
-
- harness/tsgo-routes.md
|
|
18
|
-
- harness/diagnostic-layers.md
|
|
19
|
-
- src/harness/verify/Pipeline.ts
|
|
20
|
-
- src/harness/verify/VerifyStage.ts
|
|
21
|
-
- https://developers.openai.com/codex/learn/best-practices
|
|
22
|
-
- https://developers.openai.com/codex/prompting
|
|
23
|
-
- https://developers.openai.com/codex/guides/agents-md
|
|
24
|
-
updated: 2026-07-02
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
# Feedback Loop
|
|
28
|
-
|
|
29
|
-
## BASELINE
|
|
30
|
-
|
|
31
|
-
进入第二阶段 loop 前,当前仓库 MUST 已经满足干净基线。
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
pnpm verify
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
如果基线不为 0,MUST 先修复当前失败,再开始新的代码或文档修改。
|
|
38
|
-
|
|
39
|
-
`pnpm verify` 是唯一完成命令。`source:verify`、`effect:verify`、`typecheck`、`test`、`lint`
|
|
40
|
-
和 `knip` 只作为局部排错入口,不作为完成态替代命令。
|
|
41
|
-
|
|
42
|
-
`pnpm verify` 同时是 self-conformance gate。它证明 provider repository 符合自己的 exported
|
|
43
|
-
harness contract,但不生成 `.prelude/**` 或 Prelude target lifecycle state。
|
|
44
|
-
|
|
45
|
-
## ROUTE_TABLE
|
|
46
|
-
|
|
47
|
-
Codex 在本仓写 Effect 程序逻辑,或修改 source route、tsgo policy、provider profile、
|
|
48
|
-
verify pipeline、harness 边界时,MUST 按以下闭环执行:
|
|
49
|
-
|
|
50
|
-
1. 明确任务意图和涉及模块。
|
|
51
|
-
2. 从 `harness/index.md` 找到对应路线。
|
|
52
|
-
3. 按 `harness/effect-routes.md` 或 `harness/tsgo-routes.md` 读取 pinned source。
|
|
53
|
-
4. 做一轮最小修改。
|
|
54
|
-
5. 运行 `pnpm verify`。
|
|
55
|
-
6. 如果失败,按失败 stage 的 route 回到对应文档和 source 修复。
|
|
56
|
-
7. 重复到 `pnpm verify` 为 0。
|
|
57
|
-
8. review diff,确认没有绕过 strict policy。
|
|
58
|
-
|
|
59
|
-
MUST NOT 通过 suppress、override、恢复旧口径或从 `repos/**` import 来让 loop 变绿。
|
|
60
|
-
|
|
61
|
-
agent 默认从 `harness/index.md` 和 route tables 选择读取路径。这里不维护额外 task intake
|
|
62
|
-
分类,也不把任务强行归入单选 kind。
|
|
63
|
-
|
|
64
|
-
如果修改前判断和失败后的 stage route 冲突,MUST 服从 failed stage route。
|
|
65
|
-
|
|
66
|
-
## VERIFY_PIPELINE
|
|
67
|
-
|
|
68
|
-
`pnpm verify` 由 Effect pipeline 组织,入口是 `effect-harness verify --harness .`。
|
|
69
|
-
|
|
70
|
-
pipeline 采用 fail-fast。stage 按重要性排序,越接近真源和 harness contract 的检查越靠前。
|
|
71
|
-
失败输出 MUST 包含 code-defined stage tag、title、route、routeHint 和底层工具原始输出。
|
|
72
|
-
|
|
73
|
-
stage 真源是 `src/harness/verify/VerifyStage.ts`。本节只是 agent-readable projection。
|
|
74
|
-
|
|
75
|
-
| Stage | Route | Summary | Route Hint |
|
|
76
|
-
| --- | --- | --- | --- |
|
|
77
|
-
| `source-pins` | `harness/source.md` | Verify pinned GitHub subtree source entries. | Read the source-entry contract and fix Partita source pin drift. |
|
|
78
|
-
| `harness-contract` | `harness/index.md`、`harness/offcial-migrate.md`、`harness/feedback-loop.md` | Verify the provider repository contract and current harness baseline. | Read the harness index, migrate notes, and feedback loop contract before changing verifier behavior. |
|
|
79
|
-
| `tsgo-diagnostics` | `harness/tsgo.md`、`harness/tsgo-routes.md` | Run tsgo --noEmit and enforce zero Effect diagnostics. | Use the tsgo diagnostic output first; read the tsgo policy and routes only when the diagnostic is not enough. |
|
|
80
|
-
| `tests` | `harness/effect-routes.md` | Run the Effect test suite. | Read the Effect testing route and fix behavior through @effect/vitest patterns. |
|
|
81
|
-
| `lint` | `harness/diagnostic-layers.md`、`AGENTS.md`、`eslint.config.mjs` | Run ESLint with zero warnings. | Read the diagnostic layering contract, agent rules, and lint config, then fix repository boundary violations without duplicating tsgo semantics. |
|
|
82
|
-
| `knip` | `package.json` | Run knip and keep the package surface minimal. | Read package.json and source imports/exports, then remove unused package surface. |
|
|
83
|
-
|
|
84
|
-
## STAGE_SOURCE_PINS
|
|
85
|
-
|
|
86
|
-
失败时先读 `harness/source.md`。
|
|
87
|
-
|
|
88
|
-
这一 stage 验证 provider-internal source entries 仍然由 Partita GitHub subtree pin 管理。
|
|
89
|
-
|
|
90
|
-
常见修复方向:
|
|
91
|
-
|
|
92
|
-
- contract 中的 `github.ref`、`subtree.split` 和 git history trailer 必须一致。
|
|
93
|
-
- `repos/effect/` 和 `repos/tsgo/` 必须是 committed Git tree entries。
|
|
94
|
-
- anchor 和 agent route 必须存在。
|
|
95
|
-
- source prefix 不能变成 submodule 或 nested Git repository。
|
|
96
|
-
|
|
97
|
-
## STAGE_HARNESS_CONTRACT
|
|
98
|
-
|
|
99
|
-
失败时先读 `harness/index.md`、`harness/offcial-migrate.md` 和 `harness/feedback-loop.md`。
|
|
100
|
-
|
|
101
|
-
这一 stage 验证当前仓库仍处于新基线。
|
|
102
|
-
|
|
103
|
-
常见修复方向:
|
|
104
|
-
|
|
105
|
-
- provider profile 必须保留当前 package baseline、source identities 和 strict tsgo policy。
|
|
106
|
-
- provider repository 必须保持 self-conformance,不得 materialize `.prelude/**` 或 target
|
|
107
|
-
provider namespace。
|
|
108
|
-
- legacy surfaces 不能恢复。
|
|
109
|
-
- 应用代码和测试代码不能 import `repos/effect` 或 `repos/tsgo`。
|
|
110
|
-
- CLI 必须使用 `effect/unstable/cli`,不能恢复 `@effect/cli`。
|
|
111
|
-
- 当前 service definition baseline 是 `Context.Service`。
|
|
112
|
-
|
|
113
|
-
## STAGE_TSGO_DIAGNOSTICS
|
|
114
|
-
|
|
115
|
-
失败时先读 `harness/tsgo.md` 和 `harness/tsgo-routes.md`。
|
|
116
|
-
|
|
117
|
-
这一 stage 是 Effect 语义 feedback 的主入口。
|
|
118
|
-
|
|
119
|
-
修复时 SHOULD 先用 diagnostic name 定位 `repos/tsgo/_packages/tsgo/src/metadata.json`,再按
|
|
120
|
-
`harness/tsgo-routes.md` 查具体 rule、fixture 或 quickfix 行为。
|
|
121
|
-
|
|
122
|
-
MUST 修复代码或 policy。MUST NOT 用普通源码 suppressions、local override 或放宽 rule map
|
|
123
|
-
绕过失败。
|
|
124
|
-
|
|
125
|
-
## STAGE_TESTS
|
|
126
|
-
|
|
127
|
-
失败时先读 `harness/effect-routes.md` 中 testing 路线。
|
|
128
|
-
|
|
129
|
-
本仓测试使用 `@effect/vitest`。Effect 程序测试 SHOULD 使用 `it.effect`、`it.live` 或 `layer`
|
|
130
|
-
组织,不用普通 `vitest` 入口替代。
|
|
131
|
-
|
|
132
|
-
## STAGE_LINT
|
|
133
|
-
|
|
134
|
-
失败时先读 `harness/diagnostic-layers.md`、`AGENTS.md` 和 `eslint.config.mjs`。
|
|
135
|
-
|
|
136
|
-
lint stage 要求 0 error 和 0 warning。
|
|
137
|
-
|
|
138
|
-
lint 规则用于补 tsgo 未覆盖的仓库边界,例如 import boundary、CLI baseline、测试入口和
|
|
139
|
-
harness syntax-level guardrails。Effect 类型语义、Schema 语义、Layer 语义和 Effect-native
|
|
140
|
-
API 偏好由 `tsgo-diagnostics` stage 负责。
|
|
141
|
-
|
|
142
|
-
## STAGE_KNIP
|
|
143
|
-
|
|
144
|
-
失败时先读 `package.json` 和相关 source exports/imports。
|
|
145
|
-
|
|
146
|
-
knip stage 用于保持 provider package surface 最小。修复时 SHOULD 优先删除不需要的 exports、
|
|
147
|
-
imports 或 package fields,而不是为了 silence knip 添加无意义引用。
|
|
148
|
-
|
|
149
|
-
## DONE
|
|
150
|
-
|
|
151
|
-
一次 loop 只有在以下条件同时满足时才完成:
|
|
152
|
-
|
|
153
|
-
- `pnpm verify` 通过。
|
|
154
|
-
- 失败过的 stage 已按对应 route 修复。
|
|
155
|
-
- 没有新增 suppress、override、legacy surface 或 `repos/**` import。
|
|
156
|
-
- diff 已 review,确认没有把第二阶段扩展成 Prelude target lifecycle 实现或 repo skill/hook/rules 建设。
|