@xfey/tutti 0.1.51 → 0.1.53
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/dist/artifacts/candidate-validator.d.ts +2 -3
- package/dist/artifacts/candidate-validator.js +0 -40
- package/dist/run-pipeline/openai.js +7 -12
- package/dist/workspace-ops/index.d.ts +1 -1
- package/dist/workspace-ops/index.js +1 -1
- package/dist/workspace-ops/project-workspace.d.ts +0 -1
- package/dist/workspace-ops/project-workspace.js +0 -20
- package/dist/workspace-ops/types.d.ts +0 -2
- package/migrations/README.md +2 -2
- package/package.json +1 -1
- package/prompts/prompt-flow-experiment-plan.md +14 -13
- package/prompts/prompt-flow-map.md +21 -20
- package/prompts/runs/README.md +2 -1
- package/prompts/runs/task-continuation.md +1 -0
- package/prompts/runs/task-retry.md +3 -2
- package/prompts/runs/task-run.md +1 -0
- package/web/assets/{homepage-motion-scene-CV9ceFzS.js → homepage-motion-scene-F4ibPvI9.js} +1 -1
- package/web/assets/{index-CxVBmEoi.js → index-B1mBtL9x.js} +3 -3
- package/web/assets/{index-DNnf10zz.css → index-OFlcQ3eS.css} +1 -1
- package/web/index.html +2 -2
- package/dist/run-pipeline/candidate-diff.d.ts +0 -3
- package/dist/run-pipeline/candidate-diff.js +0 -4
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ChildProcessWithoutNullStreams } from "node:child_process";
|
|
2
2
|
import { type ValidatedArtifactContract } from "./manifest-contract.js";
|
|
3
3
|
import { type ArtifactPreviewProcessPlan } from "./process-boundary.js";
|
|
4
|
-
export type ArtifactValidationReasonCode = "artifact_applicability_failed" | "artifact_manifest_missing" | "artifact_manifest_invalid" | "artifact_static_entry_invalid" | "artifact_preview_script_missing" | "artifact_preview_start_failed" | "artifact_preview_not_ready" | "artifact_preview_entry_invalid"
|
|
5
|
-
export type ArtifactValidationDiagnosticSource = "applicability_judge" | "manifest_parser" | "package_json" | "preview_process" | "ready_probe"
|
|
4
|
+
export type ArtifactValidationReasonCode = "artifact_applicability_failed" | "artifact_manifest_missing" | "artifact_manifest_invalid" | "artifact_static_entry_invalid" | "artifact_preview_script_missing" | "artifact_preview_start_failed" | "artifact_preview_not_ready" | "artifact_preview_entry_invalid";
|
|
5
|
+
export type ArtifactValidationDiagnosticSource = "applicability_judge" | "manifest_parser" | "package_json" | "preview_process" | "ready_probe";
|
|
6
6
|
export type ArtifactValidationDiagnostic = {
|
|
7
7
|
source: ArtifactValidationDiagnosticSource;
|
|
8
8
|
text: string;
|
|
@@ -30,7 +30,6 @@ export type ValidateCandidateArtifactOptions = {
|
|
|
30
30
|
allocatePort?: () => Promise<number>;
|
|
31
31
|
fetchImpl?: typeof fetch;
|
|
32
32
|
terminateProcess?: (child: ChildProcessWithoutNullStreams) => Promise<void>;
|
|
33
|
-
fingerprintCandidate?: (repoRoot: string) => string;
|
|
34
33
|
readyTimeoutMs?: number;
|
|
35
34
|
probeIntervalMs?: number;
|
|
36
35
|
probeRequestTimeoutMs?: number;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
3
|
-
import { fingerprintProjectSourceState } from "../workspace-ops/index.js";
|
|
4
3
|
import { ARTIFACT_MANIFEST_PATH, MAX_ARTIFACT_MANIFEST_BYTES, parseArtifactManifestContract, } from "./manifest-contract.js";
|
|
5
4
|
import { allocateArtifactPreviewPort, ArtifactDiagnosticBuffer, cleanupArtifactProcessRuntime, createArtifactPreviewEnv, createArtifactProcessRuntime, spawnArtifactPreviewProcess, terminateArtifactProcessTree, } from "./process-boundary.js";
|
|
6
5
|
const MAX_PACKAGE_JSON_BYTES = 1024 * 1024;
|
|
@@ -290,21 +289,6 @@ async function validateServerCandidate(repoRealPath, contract, options) {
|
|
|
290
289
|
sensitive: { repoRoot: repoRealPath, extra: [cwd.path] },
|
|
291
290
|
});
|
|
292
291
|
}
|
|
293
|
-
const fingerprint = options.fingerprintCandidate ?? fingerprintProjectSourceState;
|
|
294
|
-
let beforeFingerprint;
|
|
295
|
-
try {
|
|
296
|
-
beforeFingerprint = fingerprint(repoRealPath);
|
|
297
|
-
}
|
|
298
|
-
catch (error) {
|
|
299
|
-
return failure({
|
|
300
|
-
reasonCode: "artifact_preview_modified_candidate",
|
|
301
|
-
summary: "Tutti could not capture the candidate state before preview validation.",
|
|
302
|
-
guidance: "Keep the candidate project directory in a valid Git repository and retry.",
|
|
303
|
-
source: "candidate_diff",
|
|
304
|
-
detail: error instanceof Error ? error.message : "Candidate state capture failed",
|
|
305
|
-
sensitive: { repoRoot: repoRealPath },
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
292
|
const processRuntime = createArtifactProcessRuntime();
|
|
309
293
|
const diagnostics = new ArtifactDiagnosticBuffer();
|
|
310
294
|
let child;
|
|
@@ -439,30 +423,6 @@ async function validateServerCandidate(repoRealPath, contract, options) {
|
|
|
439
423
|
}
|
|
440
424
|
cleanupArtifactProcessRuntime(processRuntime);
|
|
441
425
|
}
|
|
442
|
-
let afterFingerprint;
|
|
443
|
-
try {
|
|
444
|
-
afterFingerprint = fingerprint(repoRealPath);
|
|
445
|
-
}
|
|
446
|
-
catch (error) {
|
|
447
|
-
return failure({
|
|
448
|
-
reasonCode: "artifact_preview_modified_candidate",
|
|
449
|
-
summary: "Tutti could not verify the candidate state after preview validation.",
|
|
450
|
-
guidance: "Ensure artifact:preview exits cleanly without changing repository files.",
|
|
451
|
-
source: "candidate_diff",
|
|
452
|
-
detail: error instanceof Error ? error.message : "Candidate state capture failed",
|
|
453
|
-
sensitive: { repoRoot: repoRealPath },
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
if (afterFingerprint !== beforeFingerprint) {
|
|
457
|
-
return failure({
|
|
458
|
-
reasonCode: "artifact_preview_modified_candidate",
|
|
459
|
-
summary: "The server Artifact preview modified the candidate repository.",
|
|
460
|
-
guidance: "Make artifact:preview read-only, or generate required tracked files before validation.",
|
|
461
|
-
source: "candidate_diff",
|
|
462
|
-
detail: "Candidate Git state changed while artifact:preview was running",
|
|
463
|
-
sensitive: { repoRoot: repoRealPath },
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
426
|
return (result ??
|
|
467
427
|
failure({
|
|
468
428
|
reasonCode: "artifact_preview_start_failed",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createNodeNpmCheckPlan, executeCheckPlan } from "../checks/index.js";
|
|
2
|
-
import { candidateChangedAfterChecks } from "./candidate-diff.js";
|
|
3
2
|
import { runArtifactCandidateGate, } from "./artifact-applicability.js";
|
|
4
3
|
import { checkSkipFields, checkStatus, checksSummary, completedWithoutRepoChanges, docsStatusForChangedPaths, failedBeforeChecks, failedFinishedResult, promotionNotAttempted, promotionNotPromoted, successfulRunSummary, } from "./result-projections.js";
|
|
5
4
|
import { runWorkspaceWriteTask } from "./task-run-invocation.js";
|
|
@@ -94,7 +93,7 @@ function stageProgressSummary(stage) {
|
|
|
94
93
|
case "checks":
|
|
95
94
|
return "running project checks.";
|
|
96
95
|
case "post_checks_diff_collect":
|
|
97
|
-
return "
|
|
96
|
+
return "collecting the final project changes after checks.";
|
|
98
97
|
case "accepted_checkpoint":
|
|
99
98
|
return "saving the validated project state as an accepted checkpoint.";
|
|
100
99
|
case "self_correction":
|
|
@@ -358,21 +357,18 @@ async function runTaskAttempt(options, input) {
|
|
|
358
357
|
const postChecksDiff = loggedSyncStage(options, input, "post_checks_diff_collect", () => collectProjectSourceDiff(options.workspaceRoot), (result) => ({ changed_path_count: result.changed_paths.length }));
|
|
359
358
|
changedPaths = postChecksDiff.changed_paths;
|
|
360
359
|
docs = docsStatusForChangedPaths(changedPaths);
|
|
361
|
-
if (
|
|
360
|
+
if (!postChecksDiff.has_changes) {
|
|
362
361
|
const result = failedFinishedResult({
|
|
363
|
-
summary: "Checks
|
|
364
|
-
checks
|
|
365
|
-
status: "failed",
|
|
366
|
-
commands: checks.commands,
|
|
367
|
-
},
|
|
362
|
+
summary: "Checks completed but no candidate changes remain for acceptance.",
|
|
363
|
+
checks,
|
|
368
364
|
docs,
|
|
369
365
|
changedPaths,
|
|
370
|
-
promotion: promotionNotAttempted("
|
|
366
|
+
promotion: promotionNotAttempted("no_candidate_changes", "No candidate changes were available for promotion after checks."),
|
|
371
367
|
});
|
|
372
368
|
return requestSelfCorrection({
|
|
373
369
|
result,
|
|
374
|
-
reasonCode: "
|
|
375
|
-
guidance: "
|
|
370
|
+
reasonCode: "no_candidate_changes",
|
|
371
|
+
guidance: "Produce a concrete final candidate diff for the frozen task contract.",
|
|
376
372
|
});
|
|
377
373
|
}
|
|
378
374
|
const checkpoint = loggedSyncStage(options, input, "accepted_checkpoint", () => createAcceptedCheckpoint({
|
|
@@ -380,7 +376,6 @@ async function runTaskAttempt(options, input) {
|
|
|
380
376
|
taskId: input.task.id,
|
|
381
377
|
activityRef: input.activity_ref,
|
|
382
378
|
summary: `Complete Tutti task: ${input.task.title}`,
|
|
383
|
-
expectedSourceFingerprint: postChecksDiff.fingerprint,
|
|
384
379
|
}), (result) => ({
|
|
385
380
|
promoted_commit_oid: result.promoted_commit_oid,
|
|
386
381
|
checkpoint_disposition: result.disposition,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { DEFAULT_VIEWER_MAX_BYTES, MAX_REFERENCE_UPLOAD_BYTES, MAX_VIEWER_MAX_BYTES, PROJECT_DOC_PATHS, REFERENCE_IMAGE_ASSET_CACHE_VERSION, REFERENCE_IMAGE_PREVIEW_MAX_EDGE_PX, REFERENCE_IMAGE_THUMBNAIL_MAX_EDGE_PX, REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH, REFERENCE_TUTTI_DIRECTORY_PATH, VIEWER_ASSET_READ_LIMIT_BYTES, VIEWER_HARD_READ_LIMIT_BYTES, WORKSPACE_OPS_MAINLINE_BRANCH, } from "./constants.js";
|
|
2
2
|
export { WorkspaceOpsError } from "./errors.js";
|
|
3
3
|
export { commitOwnedPaths, requireOwnedPathsWriteReady } from "./system-commits.js";
|
|
4
|
-
export { collectProjectSourceDiff, createAcceptedCheckpoint,
|
|
4
|
+
export { collectProjectSourceDiff, createAcceptedCheckpoint, inspectProjectWorkspace, recoverAcceptedCheckpoint, } from "./project-workspace.js";
|
|
5
5
|
export { initializeProjectDocs, readProjectDocsInitializationStatus, syncProjectDocs, } from "./project-docs.js";
|
|
6
6
|
export { uploadReferenceFile } from "./reference-files.js";
|
|
7
7
|
export { referenceFileCategoryForPath, referenceFileSourceForPath, referenceMediaTypeForPath, referenceTuttiGroupForPath, } from "./reference-metadata.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { DEFAULT_VIEWER_MAX_BYTES, MAX_REFERENCE_UPLOAD_BYTES, MAX_VIEWER_MAX_BYTES, PROJECT_DOC_PATHS, REFERENCE_IMAGE_ASSET_CACHE_VERSION, REFERENCE_IMAGE_PREVIEW_MAX_EDGE_PX, REFERENCE_IMAGE_THUMBNAIL_MAX_EDGE_PX, REFERENCE_DIRECTORY_PATH, REFERENCE_FILES_DIRECTORY_PATH, REFERENCE_IMAGES_DIRECTORY_PATH, REFERENCE_INDEX_PATH, REFERENCE_TUTTI_DIRECTORY_PATH, VIEWER_ASSET_READ_LIMIT_BYTES, VIEWER_HARD_READ_LIMIT_BYTES, WORKSPACE_OPS_MAINLINE_BRANCH, } from "./constants.js";
|
|
2
2
|
export { WorkspaceOpsError } from "./errors.js";
|
|
3
3
|
export { commitOwnedPaths, requireOwnedPathsWriteReady } from "./system-commits.js";
|
|
4
|
-
export { collectProjectSourceDiff, createAcceptedCheckpoint,
|
|
4
|
+
export { collectProjectSourceDiff, createAcceptedCheckpoint, inspectProjectWorkspace, recoverAcceptedCheckpoint, } from "./project-workspace.js";
|
|
5
5
|
export { initializeProjectDocs, readProjectDocsInitializationStatus, syncProjectDocs, } from "./project-docs.js";
|
|
6
6
|
export { uploadReferenceFile } from "./reference-files.js";
|
|
7
7
|
export { referenceFileCategoryForPath, referenceFileSourceForPath, referenceMediaTypeForPath, referenceTuttiGroupForPath, } from "./reference-metadata.js";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ActivityRef, TaskId } from "@tutti/shared/ids";
|
|
2
2
|
import type { AcceptedCheckpointRecoveryResult, AcceptedCheckpointResult, CreateAcceptedCheckpointOptions, ProjectWorkspaceInspection, RunDiffSummary } from "./types.js";
|
|
3
|
-
export declare function fingerprintProjectSourceState(workspaceRoot: string): string;
|
|
4
3
|
export declare function collectProjectSourceDiff(workspaceRoot: string): RunDiffSummary;
|
|
5
4
|
export declare function inspectProjectWorkspace(workspaceRoot: string): ProjectWorkspaceInspection;
|
|
6
5
|
export declare function recoverAcceptedCheckpoint(options: {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
1
|
import { classifyRepositoryPathMetadata } from "@tutti/shared/utils";
|
|
3
2
|
import { WorkspaceOpsError } from "./errors.js";
|
|
4
3
|
import { runGit, runGitRaw, runGitText, stagedChangesExist, summarizeGitFailure, tryGitText, } from "./git.js";
|
|
@@ -48,20 +47,6 @@ function requireGitCommandSuccess(args, workspaceRoot) {
|
|
|
48
47
|
}
|
|
49
48
|
return result;
|
|
50
49
|
}
|
|
51
|
-
export function fingerprintProjectSourceState(workspaceRoot) {
|
|
52
|
-
const status = requireGitCommandSuccess(["status", "--porcelain=v1", "-z"], workspaceRoot);
|
|
53
|
-
const diff = requireGitCommandSuccess(["diff", "--binary", "HEAD", "--"], workspaceRoot);
|
|
54
|
-
const untracked = requireGitCommandSuccess(["ls-files", "--others", "--exclude-standard", "-z"], workspaceRoot);
|
|
55
|
-
const hash = createHash("sha256").update(status.stdout).update(diff.stdout);
|
|
56
|
-
for (const path of untracked.stdout.toString("utf8").split("\0")) {
|
|
57
|
-
if (path.length === 0) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
const object = requireGitCommandSuccess(["hash-object", "--no-filters", "--", path], workspaceRoot);
|
|
61
|
-
hash.update(path).update("\0").update(object.stdout);
|
|
62
|
-
}
|
|
63
|
-
return hash.digest("hex");
|
|
64
|
-
}
|
|
65
50
|
export function collectProjectSourceDiff(workspaceRoot) {
|
|
66
51
|
const status = requireGitCommandSuccess(["status", "--porcelain=v1", "-z"], workspaceRoot);
|
|
67
52
|
const changedPaths = parsePorcelainChangedPaths(status.stdout);
|
|
@@ -82,7 +67,6 @@ export function collectProjectSourceDiff(workspaceRoot) {
|
|
|
82
67
|
has_changes: status.stdout.length > 0,
|
|
83
68
|
changed_paths: changedPaths,
|
|
84
69
|
summary: truncateText(summaryParts.join("\n\n"), MAX_RUN_DIFF_SUMMARY_BYTES),
|
|
85
|
-
fingerprint: fingerprintProjectSourceState(workspaceRoot),
|
|
86
70
|
};
|
|
87
71
|
}
|
|
88
72
|
function acceptedTagName(workspaceRoot, activityRef) {
|
|
@@ -225,10 +209,6 @@ export function createAcceptedCheckpoint(options) {
|
|
|
225
209
|
};
|
|
226
210
|
}
|
|
227
211
|
const inspection = inspectProjectWorkspace(options.workspaceRoot);
|
|
228
|
-
if (options.expectedSourceFingerprint !== undefined &&
|
|
229
|
-
fingerprintProjectSourceState(options.workspaceRoot) !== options.expectedSourceFingerprint) {
|
|
230
|
-
throw new WorkspaceOpsError("conflict", "Project source changed after validation and before accepted checkpoint", { reason_code: "accepted_checkpoint_candidate_changed" });
|
|
231
|
-
}
|
|
232
212
|
runGit(["add", "-A"], options.workspaceRoot);
|
|
233
213
|
if (!stagedChangesExist(options.workspaceRoot)) {
|
|
234
214
|
throw new WorkspaceOpsError("validation_failed", "Accepted checkpoint has no staged source changes", { reason_code: "accepted_checkpoint_candidate_missing" });
|
|
@@ -170,7 +170,6 @@ export type RunDiffSummary = {
|
|
|
170
170
|
has_changes: boolean;
|
|
171
171
|
changed_paths: string[];
|
|
172
172
|
summary: string;
|
|
173
|
-
fingerprint: string;
|
|
174
173
|
};
|
|
175
174
|
export type ProjectWorkspaceInspection = {
|
|
176
175
|
workspace_root: string;
|
|
@@ -181,7 +180,6 @@ export type CreateAcceptedCheckpointOptions = WorkspaceViewerOptions & {
|
|
|
181
180
|
taskId: TaskId;
|
|
182
181
|
activityRef: ActivityRef;
|
|
183
182
|
summary: string;
|
|
184
|
-
expectedSourceFingerprint?: string;
|
|
185
183
|
};
|
|
186
184
|
export type AcceptedCheckpointResult = {
|
|
187
185
|
promoted_commit_oid: string;
|
package/migrations/README.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- `0006_scratchpad_source_state.sql`:新增自动 Scratchpad refresh 的本机 source cursor / dirty / in-flight / backoff 状态表。
|
|
22
22
|
- `0007_workspace_signal_read_state_scopes.sql`:扩展 read-state scope,允许 References 与 Skills 写入模块更新通知事件。
|
|
23
23
|
- `0008_provider_usage_anchors.sql`:为 provider usage ledger 增加可空 activity / workflow / task / run result anchor 字段,供 Timeline 尽力把 token usage 挂到可证明的历史节点。
|
|
24
|
-
- `0009_project_timeline_events.sql`:新增 Timeline 专用 append-only durable event 表,用于记录缺少其他稳定 record 的 context sync、reference summary
|
|
24
|
+
- `0009_project_timeline_events.sql`:新增 Timeline 专用 append-only durable event 表,用于记录缺少其他稳定 record 的 context sync、reference summary 与历史 promotion reconcile 轻量可观测性节点;新 Run 不再写 reconcile event。
|
|
25
25
|
- `0010_project_brief.sql`:新增 host-local Project Brief projection 表,用于保存四个 baseline Project Docs 的短摘要和 source fingerprint。
|
|
26
26
|
- `0011_message_author_avatar.sql`:为消息作者增加可选 Relay account avatar 快照,保证跨浏览器查看历史消息时不依赖当前 viewer profile 或 presence sample。
|
|
27
27
|
- `0012_scratchpad_receipts.sql`:为当前 Scratchpad 增加 `submitted` 状态字段,并新增已提交 Scratchpad 小票历史表。
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
- `0001_init.sql`、`0002_allow_sealed_round_successor_note.sql`、`0003_drop_scratchpad_source_message_refs.sql`、`0004_read_state.sql`、`0005_provider_usage.sql`、`0006_scratchpad_source_state.sql`、`0007_workspace_signal_read_state_scopes.sql`、`0008_provider_usage_anchors.sql`、`0009_project_timeline_events.sql`、`0010_project_brief.sql`、`0011_message_author_avatar.sql`、`0012_scratchpad_receipts.sql` 与 `0013_scratchpad_receipt_sources.sql` 已存在,代表当前 host project SQLite schema contract。
|
|
33
33
|
- SQLite adapter、migration runner、checksum 校验、store metadata 初始化、transaction helper 与 command recovery scan helper 已实现。
|
|
34
|
-
- 协作 repository 与 Control Plane 已实现第一批业务读写;Phase 7 首批已复用 `0001_init.sql` 中的 `tasks.latest_run_result_id`、`task_details.result_json` 与 `run_results` 表完成 Run result / checks / promotion 摘要持久化。Control Plane recovery resolver 与 task-bound continuation / retry 复用现有 schema
|
|
34
|
+
- 协作 repository 与 Control Plane 已实现第一批业务读写;Phase 7 首批已复用 `0001_init.sql` 中的 `tasks.latest_run_result_id`、`task_details.result_json` 与 `run_results` 表完成 Run result / checks / promotion 摘要持久化。Control Plane recovery resolver 与 task-bound continuation / retry 复用现有 schema;新 Run 的 accepted checkpoint 业务 truth 继续写入最终 Run result / task detail result,Git tag / commit trailer 承担 crash recovery evidence。Timeline 默认从 `tasks`、`run_results` 与历史主群聊 `refs.worklist_feedback` 投影任务级审计节点,当前 task terminal Chat feedback 写入 `refs.task_result` 消息;`project_timeline_events` 只保留缺少稳定 record 的轻量可观测性事件和历史 reconcile 兼容记录。project workspace、working diff 与 ignored runtime state 都不进入 SQLite truth。`provider_usage_events` 只保存 token 计数、调用来源、模型名、记录时间和可空 anchor,不保存 provider secret、prompt 或 raw response。store 基础设施本身已经可以创建并迁移 `tutti.sqlite`。
|
|
35
35
|
|
|
36
36
|
## PRAGMA 边界
|
|
37
37
|
|
package/package.json
CHANGED
|
@@ -76,7 +76,7 @@ repositories are background material only; they can be trimmed or adjusted to ma
|
|
|
76
76
|
- Purpose:
|
|
77
77
|
- Fast checks.
|
|
78
78
|
- Easy task-bound clarification fixture.
|
|
79
|
-
-
|
|
79
|
+
- Accepted checkpoint / tag recovery fixture.
|
|
80
80
|
- Adjustments:
|
|
81
81
|
- Use a tiny TypeScript or JavaScript CLI.
|
|
82
82
|
- Include one ambiguous data-format task that should require clarification.
|
|
@@ -88,13 +88,13 @@ repositories are background material only; they can be trimmed or adjusted to ma
|
|
|
88
88
|
|
|
89
89
|
Purpose:
|
|
90
90
|
|
|
91
|
-
- Verify project context bootstrap, task compile, Run,
|
|
91
|
+
- Verify project context bootstrap, task compile, Run, Artifact gate, checks, and accepted checkpoint.
|
|
92
92
|
|
|
93
93
|
Expected:
|
|
94
94
|
|
|
95
95
|
- Missing baseline context files are created before Worklist proposal.
|
|
96
96
|
- First task reaches `done`.
|
|
97
|
-
- Run result includes changed paths and promoted commit.
|
|
97
|
+
- Run result includes changed paths and promoted accepted commit; the immutable activity tag points to that commit.
|
|
98
98
|
|
|
99
99
|
### E2: Run Updates Related Docs
|
|
100
100
|
|
|
@@ -110,7 +110,7 @@ Expected:
|
|
|
110
110
|
|
|
111
111
|
- Candidate changed paths include source changes and relevant Markdown / README changes.
|
|
112
112
|
- Run result records `docs = updated`.
|
|
113
|
-
-
|
|
113
|
+
- Accepted checkpoint is created after Artifact validation and checks.
|
|
114
114
|
|
|
115
115
|
### E3: Code-Only Run Defers Docs
|
|
116
116
|
|
|
@@ -150,26 +150,27 @@ Purpose:
|
|
|
150
150
|
Expected:
|
|
151
151
|
|
|
152
152
|
- Failed checks produce a finished result with failed outcome.
|
|
153
|
-
- No
|
|
153
|
+
- No accepted commit or activity tag is created.
|
|
154
154
|
- Task remains explainable through Worklist and run result history.
|
|
155
155
|
|
|
156
|
-
### E6:
|
|
156
|
+
### E6: Persistent Workspace Dependency Continuity
|
|
157
157
|
|
|
158
158
|
Purpose:
|
|
159
159
|
|
|
160
|
-
- Verify
|
|
160
|
+
- Verify candidate validation, accepted checkpoint, and formal Artifact preview use one persistent project directory without copying runtime state.
|
|
161
161
|
|
|
162
162
|
Setup:
|
|
163
163
|
|
|
164
|
-
-
|
|
165
|
-
-
|
|
164
|
+
- Use an existing npm repo with `node_modules/` ignored and dependencies initially absent.
|
|
165
|
+
- Let the Run install the project-local dependency required by `npm run artifact:preview` and produce a valid Artifact candidate.
|
|
166
166
|
|
|
167
167
|
Expected:
|
|
168
168
|
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
169
|
+
- Provider, candidate preview, checks, accepted checkpoint, and formal preview resolve the same project workspace root.
|
|
170
|
+
- Candidate validation and checks pass, then accepted commit + immutable activity tag are created.
|
|
171
|
+
- `node_modules/` is not committed but remains available in the project directory.
|
|
172
|
+
- Formal preview and a later preview restart succeed without reinstalling or restoring a prepared snapshot.
|
|
173
|
+
- No `tutti/run/*`, `tutti/merge/*`, extra worktree, or promotion reconcile event is created.
|
|
173
174
|
|
|
174
175
|
### E7: Task-Bound Clarification
|
|
175
176
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
- OpenAI SDK structured output:用于轻量结构化整理和判断。调用统一经过 Responses API strict JSON schema,schema 由 TypeScript 代码绑定,prompt 只能影响内容倾向,不能新增输出字段。
|
|
12
12
|
- Codex app-server read-only:用于 `@tutti` 协作聊天问答、缺失 Project Docs baseline 的初始化计划、Scratchpad 任务化、文档同步计划和 Reference summary。可以附加 built-in skills 与 invocation-scoped agent context API token。
|
|
13
|
-
- Codex app-server workspace-write:用于正式 task Run、`Run.needs_human` 后的 continuation,以及 Run pipeline 内部 bounded self-correction retry
|
|
13
|
+
- Codex app-server workspace-write:用于正式 task Run、`Run.needs_human` 后的 continuation,以及 Run pipeline 内部 bounded self-correction retry。所有 attempt 都在 `tutti/mainline` checkout 所在的持久 project workspace 中运行,可附加 built-in skills 和 user skills。provider transient retry 不新增 prompt 或 selection,只在 retryable app-server failure 后复用失败 attempt 的同一 prompt family 与同一目录现场。
|
|
14
14
|
|
|
15
15
|
Provider validation 也使用 OpenAI Responses API,但它只是启动前 credential/model 可用性检查,不属于协作 prompt 改造主线。
|
|
16
16
|
|
|
@@ -27,7 +27,7 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
|
|
|
27
27
|
- `workspace_write_run`:已对齐为 workspace-write + 精简 task contract 输入 + Project Docs / Worklist skills + user skills;存在 user skills 时通过 `skills/list.perCwdExtraUserRoots` 预热当前项目 `<TUTTI_HOME>/projects/<project_id>/skills`;Reference Files 不再通过 built-in skill 暴露,若任务或项目文档指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件。
|
|
28
28
|
- `follow_up_run`:已对齐为 workspace-write + 精简 task contract 输入 + continuation block + Project Docs / Worklist skills + user skills;存在 user skills 时同样预热当前项目 `<TUTTI_HOME>/projects/<project_id>/skills` extra root;Reference Files 不再通过 built-in skill 暴露,若任务、项目文档或 clarification answer 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件。
|
|
29
29
|
- `artifact_applicability`:候选缺少 manifest 且 deterministic evidence 无法明确判定时,使用 `artifacts/applicability.md` 做 transient read-only structured-output 判断;判断不写入 Task contract,失败时 fail closed。
|
|
30
|
-
- `pipeline_self_correction`:已对齐为 workspace-write + 精简 task contract 输入 + 必填 correction diagnostic;使用 `runs/task-retry.md` 和 `workspace_write_run` selection,在同一 active Run 记录终态前处理 Artifact gate、
|
|
30
|
+
- `pipeline_self_correction`:已对齐为 workspace-write + 精简 task contract 输入 + 必填 correction diagnostic;使用 `runs/task-retry.md` 和 `workspace_write_run` selection,在同一 active Run 记录终态前处理 Artifact gate、checks 前后无 candidate diff、checks 失败或 accepted-checkpoint failure 等可自纠 feedback,并在同一持久 project workspace 中保留前一 attempt 的 source 与 repo-local runtime state。
|
|
31
31
|
- `follow_up_check`:保持 OpenAI SDK structured output;已收敛为只判断上游 `Run.needs_human` 的 task-bound answer,不接入 skill,不重查代码或协作上下文;provider-facing input 只保留精简 task contract、previous Run pause reason、原 clarification request 和 answers,provider raw output 使用 `{ result: ... }` 互斥分支,failed-task retry 从 active path 移除。
|
|
32
32
|
- `reference_summary_refresh`:已对齐为 Codex app-server read-only + 单文件临时 `cwd`;workflow / activity refs、原始 path、blob、media type 和 file metadata 只留在 Control Plane 内部,不进入 prompt;provider raw output 使用 `{ result: ... }` 互斥分支,只输出 `summarized.summary` 或 `unavailable.reason`。
|
|
33
33
|
|
|
@@ -51,6 +51,7 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
|
|
|
51
51
|
- 2026-06-29:`reference_summary_refresh` provider-facing input 清零;runner 复制目标 reference 文件到独立临时目录,并以该目录作为 app-server `cwd` 和唯一 readable path。prompt 不再接收 workflow/activity trace anchors、原始路径、file metadata、blob 或 media type;provider raw output 改为 `{ result: ... }` 互斥分支,只输出 `summarized.summary` 或自然语言 `unavailable.reason`。
|
|
52
52
|
- 2026-07-02:新增 `project_brief_refresh`;在四个 canonical Project Docs 创建、同步、被成功 Run promotion 修改,或 provider 配置完成后需要 backfill 时尽力刷新 host-local Project Brief projection。provider-facing input 只包含四份 Project Docs 的 bounded source / status,输出 `product_summary / tech_summary / structure_summary / principles_summary`。
|
|
53
53
|
- 2026-07-29:新增 `artifacts/applicability.md` transient judge;Run / reconcile candidate 在 checks 前执行 Artifact gate。`task-retry` correction block 增加必填 redacted / bounded diagnostic,`promotion_failure` 改为完整对象或显式 `null`。
|
|
54
|
+
- 2026-08-01:Run pipeline 完成持久 project workspace cutover;本条取代上述历史记录中的 attempt workspace cleanup、fresh run workspace、result commit / fast-forward promotion 与 reconcile candidate 语义。initial、continuation、provider transient retry 和 self-correction 现在复用同一项目目录;candidate Artifact、checks 与正式 preview 共享目录身份,通过 gate 后创建 accepted commit + immutable activity tag。
|
|
54
55
|
|
|
55
56
|
后续逐项讨论时,默认从尚未在本节标为已完成的环节继续推进,避免重复分析已经收口的 prompt。
|
|
56
57
|
|
|
@@ -346,33 +347,33 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
346
347
|
|
|
347
348
|
### 初次 Task Run
|
|
348
349
|
|
|
349
|
-
定义:围绕单个正式 task
|
|
350
|
+
定义:围绕单个正式 task,在持久 project workspace 中实现候选改动。
|
|
350
351
|
|
|
351
|
-
功能:读取任务契约和必要 repo facts
|
|
352
|
+
功能:读取任务契约和必要 repo facts,在现有项目现场上继续修改并返回结构化 task-run result。该目录可能保留此前 failed Run 的未接受 source 与 ignored dependency/runtime state。
|
|
352
353
|
|
|
353
354
|
当前输入:
|
|
354
355
|
|
|
355
356
|
- `run_input_json.title`:短任务标题,用于快速定位任务意图。
|
|
356
357
|
- `run_input_json.goal`:正式任务目标。
|
|
357
358
|
- `run_input_json.scope`:正式任务边界,同时承接关键约束、非目标、假设和可观察验收信号。
|
|
358
|
-
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或
|
|
359
|
+
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
|
|
359
360
|
- 通过 `workspace_write_run` selection 可读取 Project Docs 与 Worklist,并可加载所有 enabled user skills;存在 user skills 时,app-server `skills/list` 会先收到当前项目 `<TUTTI_HOME>/projects/<project_id>/skills` extra user root。
|
|
360
361
|
- Reference Files 不通过 built-in skill 暴露;若任务契约或 Project Docs 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件正文。
|
|
361
362
|
- 不直接读取主群聊或 Scratchpad;这些不作为 hidden scope。
|
|
362
363
|
|
|
363
364
|
输出:根对象只包含 `result`;`result` 内四选一输出 `completed.{summary,user_note_candidate}`、`completed_no_repo_changes.{summary,user_note_candidate}`、`needs_human.{title,summary,request}` 或 `failed.summary`。`user_note_candidate` 是可选最终反馈候选,字段必填但可为 `null`;生成给用户直接查看的文件应写入 `docs/reference/tutti/`。`completed_no_repo_changes` 只用于任务契约不要求 repository file changes 的情况。`needs_human` payload 必须能直接作为 task-bound clarification request 使用:解释为什么 frozen contract 下无法安全继续,并提出一个具体、可回答、非 secret 的问题。
|
|
364
365
|
|
|
365
|
-
下游:Run pipeline 收集真实 Git diff 作为 `changed_paths`;`needs_human` 时 Control Plane 记录 `Run.needs_human`、打开 task-bound clarification 并把 task 迁回 `pending`;有 repo candidate 的 `completed`
|
|
366
|
+
下游:Run pipeline 收集真实 Git diff 作为 `changed_paths`;`needs_human` 时 Control Plane 记录 `Run.needs_human`、打开 task-bound clarification 并把 task 迁回 `pending`;有 repo candidate 的 `completed` 结果先执行 Artifact candidate gate 与 checks,再在当前 `tutti/mainline` 创建 accepted commit + immutable activity tag;空 diff 的 `completed_no_repo_changes` 结果跳过 Artifact gate、checks 与 accepted checkpoint,记录 `promotion.status = not_attempted`。
|
|
366
367
|
|
|
367
|
-
provider transient retry:如果本环节的 Codex app-server workspace-write turn 在产生可用结构化输出前因 retryable provider failure 失败,Run pipeline
|
|
368
|
+
provider transient retry:如果本环节的 Codex app-server workspace-write turn 在产生可用结构化输出前因 retryable provider failure 失败,Run pipeline 使用 `runs/task-run.md`、同一 `workspace_write_run` selection、同一 frozen task contract 和同一 project workspace 重跑一次。它不清理前一 attempt 现场,也不使用 `task-retry.md`。
|
|
368
369
|
|
|
369
370
|
当前改造结论:
|
|
370
371
|
|
|
371
372
|
- frozen task contract 是唯一正式执行范围;Worklist 上下文只用于理解顺序、相邻任务、prior result 和避免冲突。
|
|
372
373
|
- Project Docs / Worklist / repo 内相关 reference 文件 / user skills 可辅助实现和文档判断,但不能覆盖 Tutti 的任务契约、command policy、workspace path policy、checks、promotion 或 redaction 规则。
|
|
373
|
-
- task-run 不再自报 `docs` 或 `changed_paths`;Run result 的路径证据始终来自 Run pipeline 在
|
|
374
|
+
- task-run 不再自报 `docs` 或 `changed_paths`;Run result 的路径证据始终来自 Run pipeline 在 project workspace 中收集的 Git diff。
|
|
374
375
|
- `blocked` 不再属于 initial task-run 输出;无法产出可用 candidate、repo/tooling 错误或普通无 coherent diff 时返回 `failed`。
|
|
375
|
-
- 如果本次改动影响稳定项目事实、使用方式、公开行为、接口、setup、项目组织、维护上下文或项目工作规则,应在同一
|
|
376
|
+
- 如果本次改动影响稳定项目事实、使用方式、公开行为、接口、setup、项目组织、维护上下文或项目工作规则,应在同一 project workspace 更新相关项目文档。
|
|
376
377
|
- 文档更新应写稳定结论和当前事实;不得把 Run 过程记录、任务完成日志、临时推理、调试轨迹或过长实现叙事写进 project specs / README-style 文档。
|
|
377
378
|
|
|
378
379
|
### Clarification 后继续
|
|
@@ -387,16 +388,16 @@ provider transient retry:如果本环节的 Codex app-server workspace-write t
|
|
|
387
388
|
- `run_input_json.continuation.previous_run`:上一 Run 的 needs-human summary 与原 clarification request payload,说明为什么暂停。
|
|
388
389
|
- `run_input_json.continuation.clarification.resolved_rounds[]`:截至当前 round 的已提交 task-bound clarification rounds;每轮包含 request payload 和人类回答消息原文。
|
|
389
390
|
- `run_input_json.continuation.follow_up_check`:`resume` 判断的简短 summary,用于说明为什么本次可继续,但不能替代人类回答原文。
|
|
390
|
-
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或
|
|
391
|
+
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
|
|
391
392
|
- 通过 `follow_up_run` selection 可读取 Project Docs 与 Worklist,并可加载所有 enabled user skills;存在 user skills 时,app-server `skills/list` 会先收到当前项目 `<TUTTI_HOME>/projects/<project_id>/skills` extra user root。
|
|
392
393
|
- Reference Files 不通过 built-in skill 暴露;若任务契约、Project Docs 或 clarification answer 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件正文。
|
|
393
394
|
- 不直接读取主群聊或 Scratchpad;这些不作为 hidden scope。
|
|
394
395
|
|
|
395
396
|
输出:同初次 Task Run 的 `{ result: ... }` 互斥分支 schema。continuation 不再自报 `docs` 或 `changed_paths`。
|
|
396
397
|
|
|
397
|
-
下游:同初次 Task Run。Run pipeline 收集真实 Git diff;有 repo candidate 的 `completed`
|
|
398
|
+
下游:同初次 Task Run。Run pipeline 收集真实 Git diff;有 repo candidate 的 `completed` 重新经过 Artifact gate、checks 与 accepted checkpoint;空 diff 的 `completed_no_repo_changes` 跳过这些 gate;`needs_human` 时 Control Plane 继续打开 task-bound clarification。
|
|
398
399
|
|
|
399
|
-
provider transient retry:continuation 的 retryable app-server failure
|
|
400
|
+
provider transient retry:continuation 的 retryable app-server failure 只在同一 project workspace 重跑同一个 `runs/task-continuation.md` 和 `follow_up_run` selection,不清理现场、不转换为 pipeline self-correction retry,也不改变 frozen task contract。
|
|
400
401
|
|
|
401
402
|
当前改造结论:
|
|
402
403
|
|
|
@@ -412,24 +413,24 @@ provider transient retry:continuation 的 retryable app-server failure 只重
|
|
|
412
413
|
|
|
413
414
|
当前状态:active pipeline-internal path。它不等于 task-bound follow-up retry;`Run.failed` / `Task.failed` 当前仍不通过 follow-up retry 复活。如果最终失败后仍需要继续,应由用户在主群聊补充上下文或调整方向,随后重新走 Scratchpad -> Worklist 创建新任务。
|
|
414
415
|
|
|
415
|
-
|
|
416
|
+
触发条件:当前覆盖checks前后无候选diff、可自纠Artifact candidate failure、checks失败,以及accepted-checkpoint failure。
|
|
416
417
|
|
|
417
418
|
当前输入:
|
|
418
419
|
|
|
419
420
|
- `run_input_json.title` / `goal` / `scope`:同一 frozen task contract。
|
|
420
421
|
- `run_input_json.correction.summary`:上一 attempt 的 bounded failure summary。
|
|
421
|
-
- `run_input_json.correction.reason_code`:Run pipeline 生成的 feedback 短码,来源包括 Artifact gate、
|
|
422
|
+
- `run_input_json.correction.reason_code`:Run pipeline 生成的 feedback 短码,来源包括 Artifact gate、checks 前后无 candidate diff、checks 失败或 accepted-checkpoint failure。
|
|
422
423
|
- `run_input_json.correction.guidance`:Run pipeline 根据 feedback reason 生成的本次 retry 直接修正目标。
|
|
423
|
-
- `run_input_json.correction.diagnostic`:必填的 redacted / bounded 原始失败文本,包含 `source / text / truncated`,用于让模型看到 parser、package、preview process、probe 或
|
|
424
|
-
- `run_input_json.correction.promotion_failure
|
|
425
|
-
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或
|
|
424
|
+
- `run_input_json.correction.diagnostic`:必填的 redacted / bounded 原始失败文本,包含 `source / text / truncated`,用于让模型看到 parser、package、preview process、probe 或 pipeline state 的直接诊断。
|
|
425
|
+
- `run_input_json.correction.promotion_failure`:当前可自纠 feedback 都发生在 accepted checkpoint 前,因此显式为 `null`;对象分支仅作为 bounded schema 兼容位,不表示当前存在 promotion reconcile 路径。
|
|
426
|
+
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
|
|
426
427
|
- 通过 `workspace_write_run` selection 可读取 Project Docs 与 Worklist,并可加载所有 enabled user skills;存在 user skills 时,app-server `skills/list` 会先收到当前项目 `<TUTTI_HOME>/projects/<project_id>/skills` extra user root。
|
|
427
428
|
|
|
428
429
|
输出:同初次 Task Run 的 `{ result: ... }` 互斥分支 schema。retry 不自报 `docs` 或 `changed_paths`。
|
|
429
430
|
|
|
430
|
-
下游:Run pipeline
|
|
431
|
+
下游:Run pipeline 保留上一 attempt 的 source 与 ignored runtime state,在同一 project workspace 继续执行 retry 并重新收集真实 Git diff;有 repo candidate 时重新执行 Artifact gate、checks 和 accepted checkpoint,空 diff 的 `completed_no_repo_changes` 可记录为无 repo 改动完成。若 retry 仍产生可自纠 feedback 且已到上限,Run pipeline 记录最终失败;若 retry 返回 `needs_human`,才进入正常 task-bound clarification path。
|
|
431
432
|
|
|
432
|
-
provider transient retry:如果 self-correction attempt 自身遇到 retryable app-server failure,Run pipeline
|
|
433
|
+
provider transient retry:如果 self-correction attempt 自身遇到 retryable app-server failure,Run pipeline 仍在同一 project workspace 重跑同一个 `runs/task-retry.md` 和 correction block,不清理现场,也不创建第二个 correction context。
|
|
433
434
|
|
|
434
435
|
### Task-bound 回复判断
|
|
435
436
|
|
|
@@ -478,4 +479,4 @@ Provider raw 输出:根对象只包含 `result`;`result` 内三选一输出
|
|
|
478
479
|
- 是否可以接入 skill;如果可以,selection 是否只暴露该环节需要的 skills。
|
|
479
480
|
- 输出是否必须匹配固定 schema;如果是,prompt 不能要求 schema 之外的字段。
|
|
480
481
|
- 下游由哪个环节承接,以及下游如何解释 `ready`、`needs_human`、`blocked`、`failed`、`allow`、`deny` 等 decision。
|
|
481
|
-
- 是否存在 secret、路径、reference 文件正文、repo 写入、
|
|
482
|
+
- 是否存在 secret、路径、reference 文件正文、repo 写入、project workspace 或 baseline 文档生成边界。
|
package/prompts/runs/README.md
CHANGED
|
@@ -4,7 +4,7 @@ These templates are used by task `Run` execution.
|
|
|
4
4
|
|
|
5
5
|
- `task-run.md` is rendered for initial task Runs.
|
|
6
6
|
- `task-continuation.md` is rendered for Phase 8 continuation Runs after task-bound clarification.
|
|
7
|
-
- `task-retry.md` is rendered for bounded Run pipeline self-correction retries after feedback such as no candidate diff, Artifact validation failure, failed checks,
|
|
7
|
+
- `task-retry.md` is rendered for bounded Run pipeline self-correction retries after feedback such as no candidate diff before or after checks, Artifact validation failure, failed checks, or accepted-checkpoint failure. It is not a failed-task follow-up path and does not resurrect `Task.failed`.
|
|
8
8
|
Templates in this directory may describe task contracts, repo evidence, check expectations, artifact declaration rules, and documentation update responsibilities. They must never include provider credentials or host-local secret material.
|
|
9
9
|
|
|
10
10
|
`task-run.md` allows `needs_human` only for human requirement decisions, non-secret context, or risk confirmation. Unusable candidates, ordinary missing diffs, or repo/tooling errors that prevent implementation should be returned as `failed` so the Run does not open task-bound clarification incorrectly. If the task contract does not require repository file changes, the output can use `completed_no_repo_changes`; otherwise a completed implementation is expected to produce a candidate diff. If the candidate is complete but Codex self-validation commands are unavailable or blocked, the task-run output should still be `completed`; Tutti checks are the authoritative validation gate.
|
|
@@ -14,6 +14,7 @@ Run templates describe `docs/reference/` as a user-visible file exchange area. H
|
|
|
14
14
|
Initial `task-run.md`, active `task-continuation.md`, and active pipeline `task-retry.md` also instruct Codex to write or update the single active `tutti.artifact.json` manifest only when the task creates or updates a member-viewable visual artifact. Each template includes the complete strict static and server JSON shapes: every behavior field is required, `network` is always an explicit boolean, and server `script / ready_path / port` fields are forbidden. A server package instead declares the fixed `artifact:preview` npm script in its own `package.json` and listens on the injected `HOST / PORT`. The manifest remains repo truth and is not reported through the structured output schema.
|
|
15
15
|
Active task-bound follow-up still only starts continuation Runs from `Run.needs_human`. Pipeline self-correction retry happens before a terminal Run result is recorded and does not open clarification.
|
|
16
16
|
All three templates state that cwd is the persistent project workspace, may contain unaccepted source and project-local runtime/dependency state from earlier failed attempts, and must not be reset, checked out, stashed, cleaned, or otherwise discarded. Continuation, provider transient retry, and self-correction reuse that same directory and accumulated state.
|
|
17
|
+
All three templates require a final Git status inspection and make the Agent responsible for maintaining the repository's own `.gitignore` according to project conventions. They do not prescribe runtime path names or force intentional generated source out of Git.
|
|
17
18
|
|
|
18
19
|
Provider transient retry is separate from self-correction. If a retryable Codex app-server workspace-write failure occurs before usable structured output, Run pipeline may rerun the same prompt family once in the same project workspace: initial Runs stay on `task-run.md`, continuation Runs stay on `task-continuation.md`, and self-correction attempts stay on `task-retry.md`. This retry does not add `RunCorrectionContext` unless the failed attempt was already a self-correction attempt.
|
|
19
20
|
Run templates are responsible for telling Codex to update related project documentation in the same candidate workspace whenever implementation changes stable project facts. Broader cleanup, fact reconciliation, and phase-level documentation maintenance belong to the independent `context_sync` Procedure.
|
|
@@ -45,6 +45,7 @@ Human clarification answers may clarify or confirm work inside the frozen task c
|
|
|
45
45
|
- Work only inside the provided project workspace.
|
|
46
46
|
- This workspace is the persistent development state. It may retain unaccepted source changes and project-local dependency or runtime state from the paused or failed work; inspect and continue from that state within the frozen task contract.
|
|
47
47
|
- Do not reset, checkout, stash, clean, or otherwise discard existing workspace state. Do not remove changes merely because they were created before this continuation.
|
|
48
|
+
- Before returning, inspect the final Git status. Maintain the repository's own `.gitignore` for project-local state that should not be versioned, following existing project conventions; keep files Git-visible when they are intentional versioned source. Do not assume fixed runtime path names.
|
|
48
49
|
- Prefer small, reviewable changes that preserve existing style and tests.
|
|
49
50
|
|
|
50
51
|
If the formal task contract plus submitted clarification is still insufficient, return `needs_human` only for a human requirement decision, non-secret context, or risk confirmation. Return `failed` when no usable candidate can be produced.
|
|
@@ -30,10 +30,10 @@ Fields:
|
|
|
30
30
|
Use `correction` to understand why the previous attempt could not pass the acceptance gates and what this retry must fix.
|
|
31
31
|
|
|
32
32
|
- `summary`: short human-readable summary of the previous attempt failure.
|
|
33
|
-
- `reason_code`: machine-generated pipeline feedback code. Current sources include Artifact candidate validation, no candidate diff
|
|
33
|
+
- `reason_code`: machine-generated pipeline feedback code. Current sources include Artifact candidate validation, no candidate diff before or after checks, failed checks, and accepted-checkpoint failures. This code is assigned by Tutti Run pipeline, not by the model.
|
|
34
34
|
- `guidance`: direct retry instruction generated by Tutti Run pipeline for the feedback reason.
|
|
35
35
|
- `diagnostic`: required bounded diagnostic from the failed gate.
|
|
36
|
-
- `source`: stable diagnostic source such as `manifest_parser`, `package_json`, `preview_process`, `ready_probe`,
|
|
36
|
+
- `source`: stable diagnostic source such as `manifest_parser`, `package_json`, `preview_process`, `ready_probe`, or `pipeline`.
|
|
37
37
|
- `text`: redacted original parser, process, probe, diff, or pipeline error text. Use it to fix the concrete failure; do not copy it into user-facing output or project docs.
|
|
38
38
|
- `truncated`: whether Tutti had to bound the original diagnostic.
|
|
39
39
|
- `promotion_failure`: accepted-checkpoint failure details, or explicit `null` when checkpoint creation was not reached.
|
|
@@ -53,6 +53,7 @@ Correct the existing candidate in place, using `correction.summary`, `correction
|
|
|
53
53
|
- Do not use main chat or Scratchpad as hidden scope.
|
|
54
54
|
- Work only inside the provided project workspace.
|
|
55
55
|
- Do not reset, checkout, stash, clean, or otherwise discard the previous attempt's source, dependency, or runtime state. Remove or replace existing changes only when that is directly required to correct the candidate within the frozen task contract.
|
|
56
|
+
- Before returning, inspect the final Git status. Maintain the repository's own `.gitignore` for project-local state that should not be versioned, following existing project conventions; keep files Git-visible when they are intentional versioned source. Do not assume fixed runtime path names.
|
|
56
57
|
- Prefer small, reviewable changes that preserve existing style and tests.
|
|
57
58
|
|
|
58
59
|
Human clarification is not available as an interactive step inside this retry. If the formal task contract itself is insufficient, return `needs_human` with one concrete, non-secret question. Return `failed` when no usable candidate can be produced.
|
package/prompts/runs/task-run.md
CHANGED
|
@@ -32,6 +32,7 @@ Fields:
|
|
|
32
32
|
- Work only inside the provided project workspace.
|
|
33
33
|
- This workspace is the persistent development state. It may already contain unaccepted source changes or project-local dependency and runtime state left by an earlier failed Run; inspect and continue from that state when it is relevant to the frozen task contract.
|
|
34
34
|
- Do not reset, checkout, stash, clean, or otherwise discard existing workspace state. Do not remove changes merely because they predate this Run or are not part of the immediate fix.
|
|
35
|
+
- Before returning, inspect the final Git status. Maintain the repository's own `.gitignore` for project-local state that should not be versioned, following existing project conventions; keep files Git-visible when they are intentional versioned source. Do not assume fixed runtime path names.
|
|
35
36
|
- Prefer small, reviewable changes that preserve existing style and tests.
|
|
36
37
|
|
|
37
38
|
If the formal task contract is insufficient, return `needs_human` only for a human requirement decision, non-secret context, or risk confirmation. Return `failed` when no usable candidate can be produced.
|