@xfey/tutti 0.1.20 → 0.1.22

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.
Files changed (42) hide show
  1. package/dist/collaboration-state/index.d.ts +1 -1
  2. package/dist/collaboration-state/index.js +1 -1
  3. package/dist/collaboration-state/messages.js +50 -1
  4. package/dist/collaboration-state/scratchpad.d.ts +2 -0
  5. package/dist/collaboration-state/scratchpad.js +63 -0
  6. package/dist/collaboration-state/storage-types.d.ts +5 -0
  7. package/dist/collaboration-state/types.d.ts +8 -1
  8. package/dist/control-plane/event-publishers.js +2 -2
  9. package/dist/control-plane/invalidations.d.ts +2 -1
  10. package/dist/control-plane/invalidations.js +25 -0
  11. package/dist/control-plane/scratchpad-refresh-start.d.ts +2 -0
  12. package/dist/control-plane/scratchpad-refresh-start.js +10 -0
  13. package/dist/control-plane/scratchpad-refresh.d.ts +2 -0
  14. package/dist/control-plane/scratchpad-refresh.js +1 -0
  15. package/dist/project-timeline/index.d.ts +17 -3
  16. package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.d.ts +1 -0
  17. package/dist/server-shell/http/routes/project-api/openapi-timeline-routes.d.ts +94 -5
  18. package/dist/server-shell/http/routes/project-api/openapi.d.ts +95 -5
  19. package/dist/server-shell/http/routes/project-api/payload-validation.d.ts +6 -2
  20. package/dist/server-shell/http/routes/project-api/payload-validation.js +3 -0
  21. package/dist/server-shell/http/routes/project-api/project-timeline-projection.js +694 -502
  22. package/migrations/0013_scratchpad_receipt_sources.sql +24 -0
  23. package/migrations/README.md +3 -2
  24. package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -1
  25. package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -1
  26. package/node_modules/@tutti/shared/dist/schemas/api/messages.d.ts +1 -0
  27. package/node_modules/@tutti/shared/dist/schemas/api/messages.js +1 -0
  28. package/node_modules/@tutti/shared/dist/schemas/api/project-timeline.d.ts +313 -12
  29. package/node_modules/@tutti/shared/dist/schemas/api/project-timeline.js +131 -14
  30. package/node_modules/@tutti/shared/dist/schemas/api/types.d.ts +5 -1
  31. package/package.json +1 -1
  32. package/prompts/procedures/README.md +1 -1
  33. package/prompts/procedures/task-compile.md +9 -2
  34. package/prompts/runs/README.md +2 -2
  35. package/prompts/runs/task-continuation.md +11 -4
  36. package/prompts/runs/task-retry.md +11 -4
  37. package/prompts/runs/task-run.md +11 -4
  38. package/web/assets/index-BfFYfzeO.js +29 -0
  39. package/web/assets/index-De6mK5Q2.css +1 -0
  40. package/web/index.html +2 -2
  41. package/web/assets/index-BtneECwp.js +0 -29
  42. package/web/assets/index-CM9mbbeW.css +0 -1
@@ -1,23 +1,139 @@
1
1
  import { Type } from "@sinclair/typebox";
2
- import { ActivityRefSchema, IsoDateTimeStringSchema, TaskIdSchema, WorkflowInvocationRefSchema, } from "../domain/index.js";
2
+ import { ActivityRefSchema, IsoDateTimeStringSchema, MessageIdSchema, RunResultIdSchema, TaskIdSchema, WorkflowInvocationRefSchema, } from "../domain/index.js";
3
3
  import { ProviderUsageBreakdownProjectionSchema, ProviderUsageModelSummaryProjectionSchema, ProviderUsageProjectionSchema, ProviderUsageSourceSummaryProjectionSchema, } from "./provider-usage.js";
4
4
  export const ProjectTimelineItemKindSchema = Type.Union([
5
- Type.Literal("run"),
6
- Type.Literal("procedure"),
7
- Type.Literal("commit"),
8
- Type.Literal("usage"),
9
- Type.Literal("clarification"),
10
- Type.Literal("checks"),
11
- Type.Literal("promotion"),
12
- Type.Literal("recovery"),
5
+ Type.Literal("task_accepted"),
6
+ Type.Literal("task_update"),
7
+ Type.Literal("checkpoint"),
13
8
  ]);
14
9
  export const ProjectTimelineItemStatusSchema = Type.Union([
15
- Type.Literal("running"),
16
10
  Type.Literal("completed"),
17
11
  Type.Literal("failed"),
18
12
  Type.Literal("needs_human"),
19
- Type.Literal("skipped"),
20
13
  ]);
14
+ export const ProjectTimelineTaskUpdateStateSchema = Type.Union([
15
+ Type.Literal("needs_input"),
16
+ Type.Literal("completed"),
17
+ Type.Literal("failed"),
18
+ ]);
19
+ export const ProjectTimelineTraceToneSchema = Type.Union([
20
+ Type.Literal("neutral"),
21
+ Type.Literal("success"),
22
+ Type.Literal("warning"),
23
+ Type.Literal("error"),
24
+ ]);
25
+ export const ProjectTimelineTraceLinkSchema = Type.Object({
26
+ kind: Type.Union([
27
+ Type.Literal("worklist_task"),
28
+ Type.Literal("chat_message"),
29
+ Type.Literal("reference_file"),
30
+ Type.Literal("repo_path"),
31
+ ]),
32
+ label: Type.String({ minLength: 1 }),
33
+ task_id: Type.Optional(TaskIdSchema),
34
+ message_id: Type.Optional(MessageIdSchema),
35
+ path: Type.Optional(Type.String({ minLength: 1 })),
36
+ }, { additionalProperties: false });
37
+ export const ProjectTimelineSourceSnippetSchema = Type.Object({
38
+ message_id: MessageIdSchema,
39
+ author: Type.String({ minLength: 1 }),
40
+ body: Type.String(),
41
+ created_at: IsoDateTimeStringSchema,
42
+ }, { additionalProperties: false });
43
+ export const ProjectTimelineDecisionSummarySchema = Type.Object({
44
+ title: Type.Optional(Type.String({ minLength: 1 })),
45
+ summary: Type.String({ minLength: 1 }),
46
+ source: Type.Optional(Type.Union([
47
+ Type.Literal("scratchpad"),
48
+ Type.Literal("clarification"),
49
+ Type.Literal("contract"),
50
+ ])),
51
+ }, { additionalProperties: false });
52
+ export const ProjectTimelineClarificationTraceSchema = Type.Object({
53
+ title: Type.Optional(Type.String({ minLength: 1 })),
54
+ summary: Type.Optional(Type.String()),
55
+ request: Type.Optional(Type.String()),
56
+ status: Type.Optional(Type.Union([Type.Literal("active"), Type.Literal("resolved")])),
57
+ answer_count: Type.Optional(Type.Integer({ minimum: 0 })),
58
+ answers: Type.Optional(Type.Array(ProjectTimelineSourceSnippetSchema)),
59
+ }, { additionalProperties: false });
60
+ export const ProjectTimelineChangeStatusSchema = Type.Union([
61
+ Type.Literal("added"),
62
+ Type.Literal("modified"),
63
+ Type.Literal("deleted"),
64
+ Type.Literal("renamed"),
65
+ Type.Literal("unknown"),
66
+ ]);
67
+ export const ProjectTimelineTraceCardSchema = Type.Object({
68
+ tone: ProjectTimelineTraceToneSchema,
69
+ summary: Type.Optional(Type.String()),
70
+ origin: Type.Optional(Type.Object({
71
+ title: Type.Optional(Type.String({ minLength: 1 })),
72
+ summary: Type.Optional(Type.String()),
73
+ snippets: Type.Optional(Type.Array(ProjectTimelineSourceSnippetSchema)),
74
+ source_count: Type.Optional(Type.Integer({ minimum: 0 })),
75
+ unavailable_reason: Type.Optional(Type.String({ minLength: 1 })),
76
+ }, { additionalProperties: false })),
77
+ decisions: Type.Optional(Type.Array(ProjectTimelineDecisionSummarySchema)),
78
+ clarification: Type.Optional(ProjectTimelineClarificationTraceSchema),
79
+ contract: Type.Optional(Type.Object({
80
+ goal: Type.String(),
81
+ scope: Type.Array(Type.String()),
82
+ truncated: Type.Optional(Type.Boolean()),
83
+ }, { additionalProperties: false })),
84
+ result: Type.Optional(Type.Object({
85
+ summary: Type.String(),
86
+ error_code: Type.Optional(Type.String({ minLength: 1 })),
87
+ }, { additionalProperties: false })),
88
+ changes: Type.Optional(Type.Object({
89
+ items: Type.Array(Type.Object({
90
+ status: ProjectTimelineChangeStatusSchema,
91
+ path: Type.String({ minLength: 1 }),
92
+ previous_path: Type.Optional(Type.String({ minLength: 1 })),
93
+ }, { additionalProperties: false })),
94
+ total_count: Type.Integer({ minimum: 0 }),
95
+ truncated: Type.Boolean(),
96
+ }, { additionalProperties: false })),
97
+ verification: Type.Optional(Type.Object({
98
+ checks: Type.Union([
99
+ Type.Literal("passed"),
100
+ Type.Literal("failed"),
101
+ Type.Literal("skipped"),
102
+ ]),
103
+ skip_reason_code: Type.Optional(Type.String({ minLength: 1 })),
104
+ skip_reason_summary: Type.Optional(Type.String()),
105
+ }, { additionalProperties: false })),
106
+ promotion: Type.Optional(Type.Object({
107
+ status: Type.Union([
108
+ Type.Literal("promoted"),
109
+ Type.Literal("not_promoted"),
110
+ Type.Literal("not_attempted"),
111
+ ]),
112
+ commit_oid: Type.Optional(Type.String({ minLength: 1 })),
113
+ commit_short_oid: Type.Optional(Type.String({ minLength: 1 })),
114
+ summary: Type.Optional(Type.String()),
115
+ reason_code: Type.Optional(Type.String({ minLength: 1 })),
116
+ }, { additionalProperties: false })),
117
+ checkpoint: Type.Optional(Type.Object({
118
+ counters: Type.Object({
119
+ completed: Type.Integer({ minimum: 0 }),
120
+ failed: Type.Integer({ minimum: 0 }),
121
+ remaining: Type.Integer({ minimum: 0 }),
122
+ }, { additionalProperties: false }),
123
+ items: Type.Array(Type.Object({
124
+ task_id: TaskIdSchema,
125
+ title: Type.String({ minLength: 1 }),
126
+ status: Type.Union([Type.Literal("done"), Type.Literal("failed")]),
127
+ summary: Type.String(),
128
+ }, { additionalProperties: false })),
129
+ generated_files: Type.Optional(Type.Array(Type.Object({
130
+ path: Type.String({ minLength: 1 }),
131
+ name: Type.String({ minLength: 1 }),
132
+ }, { additionalProperties: false }))),
133
+ truncated: Type.Optional(Type.Boolean()),
134
+ }, { additionalProperties: false })),
135
+ links: Type.Array(ProjectTimelineTraceLinkSchema),
136
+ }, { additionalProperties: false });
21
137
  export const ProjectTimelineItemSchema = Type.Object({
22
138
  id: Type.String({ minLength: 1 }),
23
139
  kind: ProjectTimelineItemKindSchema,
@@ -28,13 +144,14 @@ export const ProjectTimelineItemSchema = Type.Object({
28
144
  task_title: Type.Optional(Type.String({ minLength: 1 })),
29
145
  activity_ref: Type.Optional(ActivityRefSchema),
30
146
  workflow_ref: Type.Optional(WorkflowInvocationRefSchema),
31
- commit_oid: Type.Optional(Type.String({ minLength: 1 })),
32
- commit_short_oid: Type.Optional(Type.String({ minLength: 1 })),
147
+ run_result_id: Type.Optional(RunResultIdSchema),
148
+ message_id: Type.Optional(MessageIdSchema),
33
149
  status: Type.Optional(ProjectTimelineItemStatusSchema),
150
+ update_state: Type.Optional(ProjectTimelineTaskUpdateStateSchema),
34
151
  token_usage: Type.Optional(ProviderUsageBreakdownProjectionSchema),
35
152
  usage_sources: Type.Optional(Type.Array(ProviderUsageSourceSummaryProjectionSchema)),
36
153
  usage_models: Type.Optional(Type.Array(ProviderUsageModelSummaryProjectionSchema)),
37
- meta: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
154
+ trace_card: Type.Optional(ProjectTimelineTraceCardSchema),
38
155
  }, { additionalProperties: false });
39
156
  export const ProjectTimelineResponseSchema = Type.Object({
40
157
  generated_at: IsoDateTimeStringSchema,
@@ -3,7 +3,7 @@ import type { IdempotencyKeySchema, IsoDateTimeStringSchema } from "../domain/in
3
3
  import type { ApiErrorCodeSchema, ApiErrorResponseSchema, CommandDispositionBaseSchema, CursorPageRequestSchema, InterruptedCommandDispositionSchema, QueryInvalidationHintSchema, RelayInvalidationHintSchema, RelaySseEventTypeSchema, SseReplayWindowPolicySchema, WorkspaceSseEventTypeSchema } from "./primitives.js";
4
4
  import type { ProviderConfigInvalidReasonCodeSchema, ProviderConfigProjectionSchema, ProviderUnavailableReasonCodeSchema } from "./provider-config.js";
5
5
  import type { ProviderUsageBreakdownProjectionSchema, ProviderUsageCategorySchema, ProviderUsageModelSummaryProjectionSchema, ProviderUsageProjectionSchema, ProviderUsageSourceSummaryProjectionSchema } from "./provider-usage.js";
6
- import type { ProjectTimelineItemKindSchema, ProjectTimelineItemSchema, ProjectTimelineItemStatusSchema, ProjectTimelineResponseSchema } from "./project-timeline.js";
6
+ import type { ProjectTimelineItemKindSchema, ProjectTimelineItemSchema, ProjectTimelineItemStatusSchema, ProjectTimelineResponseSchema, ProjectTimelineTaskUpdateStateSchema, ProjectTimelineClarificationTraceSchema, ProjectTimelineTraceCardSchema, ProjectTimelineTraceLinkSchema } from "./project-timeline.js";
7
7
  import type { PresignedUploadPutSchema, RelayUploadProjectionSchema, RelayUploadPurposeSchema, Sha256DigestSchema, StagedUploadReferenceSchema, StartRelayUploadDispositionSchema, StartRelayUploadPayloadSchema, StartRelayUploadResultSchema } from "./uploads.js";
8
8
  import type { MarkReadDispositionSchema, MarkReadPayloadSchema, MarkReadResultSchema, ReadStateScopeProjectionSchema, ReadStateScopeSchema, ReadStateSummaryProjectionSchema } from "./read-state.js";
9
9
  import type { GetMessagesRequestSchema, MessageCreatedEventPayloadSchema, MessageProjectionSchema, MessageReferenceFileRefSchema, ReferenceFileCategorySchema, SendMainChatMessageCreatedDispositionSchema, SendMainChatMessageDispositionSchema, SendMainChatMessagePayloadSchema, SendMainChatMessageResultSchema, WorklistFeedbackGeneratedFileSchema, WorklistFeedbackItemSchema, WorklistFeedbackRefSchema } from "./messages.js";
@@ -63,6 +63,10 @@ export type ProviderUsageModelSummaryProjection = Static<typeof ProviderUsageMod
63
63
  export type ProviderUsageProjection = Static<typeof ProviderUsageProjectionSchema>;
64
64
  export type ProjectTimelineItemKind = Static<typeof ProjectTimelineItemKindSchema>;
65
65
  export type ProjectTimelineItemStatus = Static<typeof ProjectTimelineItemStatusSchema>;
66
+ export type ProjectTimelineTaskUpdateState = Static<typeof ProjectTimelineTaskUpdateStateSchema>;
67
+ export type ProjectTimelineClarificationTrace = Static<typeof ProjectTimelineClarificationTraceSchema>;
68
+ export type ProjectTimelineTraceCard = Static<typeof ProjectTimelineTraceCardSchema>;
69
+ export type ProjectTimelineTraceLink = Static<typeof ProjectTimelineTraceLinkSchema>;
66
70
  export type ProjectTimelineItem = Static<typeof ProjectTimelineItemSchema>;
67
71
  export type ProjectTimelineResponse = Static<typeof ProjectTimelineResponseSchema>;
68
72
  export type ApprovalRequestKind = Static<typeof ApprovalRequestKindSchema>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfey/tutti",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -14,7 +14,7 @@
14
14
 
15
15
  `project_context_bootstrap` 的 provider path 只让 Codex app-server read-only adapter 生成缺失文档内容;如果该计划不可用,Control Plane 会回退到本地保守模板。
16
16
  `project_context_bootstrap` 的 read-only 输入只包含项目名、非空时的 `missing_docs` 与刷新后的 Scratchpad;prompt 会要求 app-server 只读探索仓库,并可通过 `read-project-docs` / `read-references` skill 按需读取现有文档和参考文件。输出只包含 `documents[].doc_key/content`,固定 path 由 Control Plane 后处理生成。
17
- `task_compile` 的 read-only 输入只包含压缩后的 Scratchpad、Worklist 和可选 clarification request / answer messages;workflow ref、activity ref、Scratchpad / Worklist 审计字段、排序字段、时间戳和完整 message projection 不进入 prompt。prompt 暴露 `read-project-docs` / `read-worklist` / `read-references` skills 供 app-server 必要时读取项目上下文文件、既有任务 contract / latest result 或相关 reference 正文;Scratchpad 和 Worklist 紧凑视图仍以直接输入为准,不通过 skill 重读 Scratchpad。provider raw output 使用 `{ result: ... }` 互斥分支;proposal 分支用 `module_ref` 指向新模块或既有模块,task 只输出 `title / goal / scope`,runner adapter 再映射为 Control Plane 内部 proposal:`goal` 同时作为内部 task summary 和 contract goal,`scope` 作为内部 contract scope。该 prompt 内部承担任务化 readiness 判断:能冻结没有重大隐藏假设的正式 task contract 时返回 proposal;如果缺失决策会显著改变目标、范围、用户可见行为、视觉 / 交互方向、技术形态、数据 / 资产来源、验收、安全边界或外部副作用,且无法从现有上下文可靠推断,则返回 workflow-bound clarification。该 prompt 也要求任务字段短而具体,避免 `title / goal / scope` 互相复述;Web 任务契约区只展示目标与范围,运行账本字段仍折叠展示。
17
+ `task_compile` 的 read-only 输入只包含压缩后的 Scratchpad、Worklist 和可选 clarification request / answer messages;workflow ref、activity ref、Scratchpad / Worklist 审计字段、排序字段、时间戳和完整 message projection 不进入 prompt。prompt 暴露 `read-project-docs` / `read-worklist` / `read-references` skills 供 app-server 必要时读取项目上下文文件、既有任务 contract / latest result 或相关 reference 正文;Scratchpad 和 Worklist 紧凑视图仍以直接输入为准,不通过 skill 重读 Scratchpad。provider raw output 使用 `{ result: ... }` 互斥分支;proposal 分支用 `module_ref` 指向新模块或既有模块,task 只输出 `title / goal / scope`,runner adapter 再映射为 Control Plane 内部 proposal:`goal` 同时作为内部 task summary 和 contract goal,`scope` 作为内部 contract scope。该 prompt 内部承担任务化 readiness 判断:能冻结没有重大隐藏假设的正式 task contract 时返回 proposal;如果缺失决策会显著改变目标、范围、用户可见行为、视觉 / 交互方向、技术形态、数据 / 资产来源、验收、安全边界或外部副作用,且无法从现有上下文可靠推断,则返回 workflow-bound clarification。当 Scratchpad 明确要求可预览页面、可交互产物、报告、规格、导出或其他直接交付物时,prompt 要求在 task `scope` 中简洁点明交付面:可视化 / 交互预览对应 active `tutti.artifact.json`,Tutti 生成的用户可见文件对应 `docs/reference/tutti/<meaningful-folder>/...`,需要完成卡片直接提示结果时可提到 `user_note_candidate`。`docs/reference/tutti/**` 是 References UI 会展示的生成文件命名空间,不是临时输出或 canonical project docs。该 prompt 也要求任务字段短而具体,避免 `title / goal / scope` 互相复述;Web 任务契约区只展示目标与范围,运行账本字段仍折叠展示。
18
18
  `context_sync` 没有 provider-facing direct input;workflow ref、activity ref、触发原因、安全元数据、checked paths、skipped paths 和 open questions 都不进入 prompt,只用于运行时追踪、调度或审计。prompt 说明通用文档同步目标、目标项目文档落点和 canonical docs 职责,由 app-server 主动探索 repo,并通过 `read-project-docs` / `read-worklist` / `read-references` skill 按需读取现有文档、正式任务上下文和参考文件。Worklist / task result 只作为阶段性完成背景和稳定结果线索,不写成长文档里的逐任务流水。
19
19
  `context_sync` prompt 只返回 `summary` 与 `updates[].path/content`;空 `updates` 表示无需同步,非空 `updates` 由 Control Plane 调用 `workspace-ops` 做 path policy、mainline clean 检查、文件写入和 Git commit。
20
20
  `project_brief_refresh` 只走 OpenAI SDK structured output,不使用 Codex app-server,不读取 repo 或 skills。它接收四个 baseline Project Docs 的 bounded source 内容与状态,输出 `product_summary / tech_summary / structure_summary / principles_summary`,由 Control Plane 写入 host-local `project_brief` projection;Project Docs 创建、同步、被成功 Run promotion 修改,或 provider setup 后需要 backfill 时可以触发。provider 不可用、source 不可用、brief 已经 fresh 或刷新失败都不影响 Project Docs 写入结果。
@@ -28,9 +28,16 @@ You compile Tutti's Scratchpad into an append-only Worklist proposal for post-ba
28
28
  - Preserve user-provided non-secret details when they are needed to execute or accept the task. Do not generalize them into vague labels.
29
29
  - Do not use web search, credentials, provider internals, raw logs, or Tutti runtime/internal paths.
30
30
 
31
- # Artifacts Context
31
+ # Delivery Surface Context
32
32
 
33
- Tutti can expose a user-viewable artifact, such as a static page or app preview, as a concrete deliverable for project members to inspect. When the Scratchpad asks for an artifact or preview, keep the task subject anchored to the established product, feature, design direction, or implementation target; treat "artifact" as the delivery format unless context makes it the subject.
33
+ Tutti can expose direct user-viewable outputs through two repo-backed surfaces when a task result is meant for project members to inspect:
34
+
35
+ - a single active visual artifact, declared by `tutti.artifact.json`, for previewable pages, apps, dashboards, or similar interactive outputs;
36
+ - generated files under `docs/reference/tutti/**`, for reviewable files such as reports, notes, specs, exports, or similar outputs.
37
+
38
+ Treat these as delivery surfaces, not as task subjects by themselves. Human-uploaded references still live under `docs/reference/files/` or `docs/reference/images/`, and stable project facts still belong in the relevant project docs or README-style files.
39
+
40
+ When the Scratchpad clearly asks for one of these direct deliverables, include a concise task `scope` item naming the expected surface. If a completion card should call out the result or generated file name, the scope may also mention `user_note_candidate`. Do not add artifact or generated-reference outputs solely to create feedback for ordinary implementation tasks.
34
41
 
35
42
  # Readiness
36
43
 
@@ -10,8 +10,8 @@ Templates in this directory may describe task contracts, repo evidence, check ex
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.
11
11
  Initial `task-run.md`, active `task-continuation.md`, and active pipeline `task-retry.md` receive only the compact task contract fields `title / goal / scope`; continuation adds the required `continuation` block, and pipeline self-correction retry adds the required `correction` block with only the previous failure summary, machine-generated reason code, correction guidance, and optional promotion failure summary. Provider-facing prompts do not receive task ids, task summaries, Run lineage, workflow anchors, changed paths, docs status, checks status, or the safety audit context entry.
12
12
  All three Run templates use a slim mutually exclusive structured output schema under `result`: exactly one of `completed.{summary,user_note_candidate}`, `completed_no_repo_changes.{summary,user_note_candidate}`, `needs_human.{title,summary,request}`, or `failed.summary`. The `summary` is a concise, human-readable result note for project members who may not inspect the code. Completed branches also require `user_note_candidate`, which is either a short user-facing final-card sentence or `null`; it must not repeat `summary` or include file paths. Checks, docs, promotion, changed paths, and other Tutti status stay in structured fields derived by the Run pipeline. They do not ask Codex to self-report docs status or changed paths; both come from Run pipeline Git diff and derived projection.
13
- Run templates describe `docs/reference/` as a user-visible file exchange area. Human uploads remain under `docs/reference/files/` and `docs/reference/images/`; Tutti-generated user-visible files must be written under `docs/reference/tutti/`, with `docs/reference/tutti/<meaningful-folder>/...` used when the folder name should be shown as a References UI group. Generated files under `docs/reference/tutti/` are discovered from promoted changed paths and rendered by References automatically.
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. The manifest must include a viewer-facing `artifact.title` and must set `artifact.network: true` when the preview loads remote browser resources. The manifest remains repo truth and is not reported through the structured output schema.
13
+ Run templates describe `docs/reference/` as a user-visible file exchange area. Human uploads remain under `docs/reference/files/` and `docs/reference/images/`; `docs/reference/tutti/**` is for Tutti-generated files intended for direct member review in References, not temporary output, internal notes, logs, or canonical project documentation. Generated user-visible files must be written under `docs/reference/tutti/`, with `docs/reference/tutti/<meaningful-folder>/...` used when the folder name should be shown as a References UI group. Generated files under `docs/reference/tutti/` are discovered from promoted changed paths, rendered by References automatically, and may be listed in Worklist terminal feedback.
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. The manifest schema requires top-level `version: 1`; it must include a viewer-facing `artifact.title` and must set `artifact.network: true` when the preview loads remote browser resources. 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
  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 a fresh run 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.
17
17
  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.
@@ -57,7 +57,14 @@ Use attached skills only when they help the current task:
57
57
 
58
58
  Human-uploaded reference material is kept in the repository under `docs/reference/`. If the task contract, project docs, or clarification answer makes a reference file relevant, read the actual repo file before relying on it. Do not infer reference contents from names, upload messages, media types, or paths.
59
59
 
60
- `docs/reference/` is a user-visible file exchange area. Human uploads live under `docs/reference/files/` and `docs/reference/images/`. When this task produces files that project members should inspect directly, write them under `docs/reference/tutti/`. Use `docs/reference/tutti/<meaningful-folder>/...` when a folder name helps explain the output group; that folder name is shown directly in the References UI. Do not create ad hoc folders at the `docs/reference/` root. Files under `docs/reference/tutti/` are displayed automatically, so `user_note_candidate` may mention generated file names but should not include paths.
60
+ `docs/reference/` is a user-visible file exchange area:
61
+
62
+ - Human uploads live under `docs/reference/files/` and `docs/reference/images/`.
63
+ - `docs/reference/tutti/**` is for Tutti-generated files that project members should inspect directly in the References UI.
64
+ - Use `docs/reference/tutti/**` for reviewable deliverables such as reports, notes, specs, exports, or similar generated files.
65
+ - Do not use `docs/reference/tutti/**` for temporary output, internal notes, logs, or canonical project documentation.
66
+
67
+ When this task explicitly produces such a file deliverable, write it under `docs/reference/tutti/`. Use `docs/reference/tutti/<meaningful-folder>/...` when a folder name helps explain the output group; that folder name is shown directly in the References UI and promoted files may be listed in Worklist terminal feedback. Do not create ad hoc folders at the `docs/reference/` root. Files under `docs/reference/tutti/` are displayed automatically, so `user_note_candidate` may mention generated file names but should not include paths.
61
68
 
62
69
  # Documentation
63
70
 
@@ -73,9 +80,9 @@ If the task creates or updates a user-viewable web page, static page, single-pag
73
80
 
74
81
  - Do not modify `tutti.artifact.json` for tasks unrelated to a visual artifact.
75
82
  - If an existing artifact remains the only current preview entry, update that manifest instead of creating another declaration.
76
- - Every artifact declaration must include a short viewer-facing `artifact.title`.
77
- - For a static artifact, declare `version: 1`, `artifact.title`, `artifact.kind: "static"`, a repo-relative `root`, and an HTML `entry` within that root.
78
- - For a server artifact, declare `artifact.title`, `artifact.kind: "server"` and provide an `artifact:preview` npm script that listens on `127.0.0.1` using the injected `HOST` and `PORT` environment variables.
83
+ - Every artifact manifest must include top-level `version: 1` and a short viewer-facing `artifact.title`.
84
+ - For a static artifact, declare `artifact.kind: "static"`, a repo-relative `root`, and an HTML `entry` within that root.
85
+ - For a server artifact, declare `artifact.kind: "server"` and provide an `artifact:preview` npm script that listens on `127.0.0.1` using the injected `HOST` and `PORT` environment variables.
79
86
  - If the preview loads external images, fonts, API data, or other remote browser resources, set `artifact.network: true`; otherwise omit it or set it to `false`.
80
87
  - Do not declare a preview that exposes secrets, credentials, private host-local pages, source maps, `.env` content, debug file browsers, or implementation-only tooling.
81
88
 
@@ -62,7 +62,14 @@ Use attached skills only when they help the current task:
62
62
 
63
63
  Human-uploaded reference material is kept in the repository under `docs/reference/`. If the task contract, project docs, or correction context makes a reference file relevant, read the actual repo file before relying on it. Do not infer reference contents from names, upload messages, media types, or paths.
64
64
 
65
- `docs/reference/` is a user-visible file exchange area. Human uploads live under `docs/reference/files/` and `docs/reference/images/`. When this task produces files that project members should inspect directly, write them under `docs/reference/tutti/`. Use `docs/reference/tutti/<meaningful-folder>/...` when a folder name helps explain the output group; that folder name is shown directly in the References UI. Do not create ad hoc folders at the `docs/reference/` root. Files under `docs/reference/tutti/` are displayed automatically, so `user_note_candidate` may mention generated file names but should not include paths.
65
+ `docs/reference/` is a user-visible file exchange area:
66
+
67
+ - Human uploads live under `docs/reference/files/` and `docs/reference/images/`.
68
+ - `docs/reference/tutti/**` is for Tutti-generated files that project members should inspect directly in the References UI.
69
+ - Use `docs/reference/tutti/**` for reviewable deliverables such as reports, notes, specs, exports, or similar generated files.
70
+ - Do not use `docs/reference/tutti/**` for temporary output, internal notes, logs, or canonical project documentation.
71
+
72
+ When this task explicitly produces such a file deliverable, write it under `docs/reference/tutti/`. Use `docs/reference/tutti/<meaningful-folder>/...` when a folder name helps explain the output group; that folder name is shown directly in the References UI and promoted files may be listed in Worklist terminal feedback. Do not create ad hoc folders at the `docs/reference/` root. Files under `docs/reference/tutti/` are displayed automatically, so `user_note_candidate` may mention generated file names but should not include paths.
66
73
 
67
74
  # Documentation
68
75
 
@@ -78,9 +85,9 @@ If the task creates or updates a user-viewable web page, static page, single-pag
78
85
 
79
86
  - Do not modify `tutti.artifact.json` for tasks unrelated to a visual artifact.
80
87
  - If an existing artifact remains the only current preview entry, update that manifest instead of creating another declaration.
81
- - Every artifact declaration must include a short viewer-facing `artifact.title`.
82
- - For a static artifact, declare `version: 1`, `artifact.title`, `artifact.kind: "static"`, a repo-relative `root`, and an HTML `entry` within that root.
83
- - For a server artifact, declare `artifact.title`, `artifact.kind: "server"` and provide an `artifact:preview` npm script that listens on `127.0.0.1` using the injected `HOST` and `PORT` environment variables.
88
+ - Every artifact manifest must include top-level `version: 1` and a short viewer-facing `artifact.title`.
89
+ - For a static artifact, declare `artifact.kind: "static"`, a repo-relative `root`, and an HTML `entry` within that root.
90
+ - For a server artifact, declare `artifact.kind: "server"` and provide an `artifact:preview` npm script that listens on `127.0.0.1` using the injected `HOST` and `PORT` environment variables.
84
91
  - If the preview loads external images, fonts, API data, or other remote browser resources, set `artifact.network: true`; otherwise omit it or set it to `false`.
85
92
  - Do not declare a preview that exposes secrets, credentials, private host-local pages, source maps, `.env` content, debug file browsers, or implementation-only tooling.
86
93
 
@@ -44,7 +44,14 @@ Use attached skills only when they help the current task:
44
44
 
45
45
  Human-uploaded reference material is kept in the repository under `docs/reference/`. If the task contract or project docs make a reference file relevant, read the actual repo file before relying on it. Do not infer reference contents from names, upload messages, media types, or paths.
46
46
 
47
- `docs/reference/` is a user-visible file exchange area. Human uploads live under `docs/reference/files/` and `docs/reference/images/`. When this task produces files that project members should inspect directly, write them under `docs/reference/tutti/`. Use `docs/reference/tutti/<meaningful-folder>/...` when a folder name helps explain the output group; that folder name is shown directly in the References UI. Do not create ad hoc folders at the `docs/reference/` root. Files under `docs/reference/tutti/` are displayed automatically, so `user_note_candidate` may mention generated file names but should not include paths.
47
+ `docs/reference/` is a user-visible file exchange area:
48
+
49
+ - Human uploads live under `docs/reference/files/` and `docs/reference/images/`.
50
+ - `docs/reference/tutti/**` is for Tutti-generated files that project members should inspect directly in the References UI.
51
+ - Use `docs/reference/tutti/**` for reviewable deliverables such as reports, notes, specs, exports, or similar generated files.
52
+ - Do not use `docs/reference/tutti/**` for temporary output, internal notes, logs, or canonical project documentation.
53
+
54
+ When this task explicitly produces such a file deliverable, write it under `docs/reference/tutti/`. Use `docs/reference/tutti/<meaningful-folder>/...` when a folder name helps explain the output group; that folder name is shown directly in the References UI and promoted files may be listed in Worklist terminal feedback. Do not create ad hoc folders at the `docs/reference/` root. Files under `docs/reference/tutti/` are displayed automatically, so `user_note_candidate` may mention generated file names but should not include paths.
48
55
 
49
56
  # Documentation
50
57
 
@@ -60,9 +67,9 @@ If the task creates or updates a user-viewable web page, static page, single-pag
60
67
 
61
68
  - Do not modify `tutti.artifact.json` for tasks unrelated to a visual artifact.
62
69
  - If an existing artifact remains the only current preview entry, update that manifest instead of creating another declaration.
63
- - Every artifact declaration must include a short viewer-facing `artifact.title`.
64
- - For a static artifact, declare `version: 1`, `artifact.title`, `artifact.kind: "static"`, a repo-relative `root`, and an HTML `entry` within that root.
65
- - For a server artifact, declare `artifact.title`, `artifact.kind: "server"` and provide an `artifact:preview` npm script that listens on `127.0.0.1` using the injected `HOST` and `PORT` environment variables.
70
+ - Every artifact manifest must include top-level `version: 1` and a short viewer-facing `artifact.title`.
71
+ - For a static artifact, declare `artifact.kind: "static"`, a repo-relative `root`, and an HTML `entry` within that root.
72
+ - For a server artifact, declare `artifact.kind: "server"` and provide an `artifact:preview` npm script that listens on `127.0.0.1` using the injected `HOST` and `PORT` environment variables.
66
73
  - If the preview loads external images, fonts, API data, or other remote browser resources, set `artifact.network: true`; otherwise omit it or set it to `false`.
67
74
  - Do not declare a preview that exposes secrets, credentials, private host-local pages, source maps, `.env` content, debug file browsers, or implementation-only tooling.
68
75