修复 Trellis 空闲态治理检查(07-26-trellis-upgrade-project-audit)
这个提交包含在:
@@ -101,6 +101,8 @@ rollback and future self-maintenance.
|
|||||||
one deliberately.
|
one deliberately.
|
||||||
- Post-upgrade dry-run changes manifest again -> investigate template hash drift
|
- Post-upgrade dry-run changes manifest again -> investigate template hash drift
|
||||||
before commit.
|
before commit.
|
||||||
|
- No active task directory after the last task is archived -> valid idle state;
|
||||||
|
governance still checks core files, docs registration and sensitive content.
|
||||||
- Only documented project overlays remain modified -> acceptable after task and
|
- Only documented project overlays remain modified -> acceptable after task and
|
||||||
governance gates pass.
|
governance gates pass.
|
||||||
|
|
||||||
@@ -118,6 +120,8 @@ rollback and future self-maintenance.
|
|||||||
- Assert CLI and project versions match the intended target.
|
- Assert CLI and project versions match the intended target.
|
||||||
- Compile every Python file under `.trellis/scripts` and `.codex/hooks`.
|
- Compile every Python file under `.trellis/scripts` and `.codex/hooks`.
|
||||||
- Exercise task validate/current/list and run Trellis governance.
|
- Exercise task validate/current/list and run Trellis governance.
|
||||||
|
- Archive the final active task and assert Trellis governance still passes with
|
||||||
|
zero active task directories.
|
||||||
- Confirm no `.new`, backup, bytecode or out-of-scope platform assets are
|
- Confirm no `.new`, backup, bytecode or out-of-scope platform assets are
|
||||||
tracked; finish with `git diff --check`.
|
tracked; finish with `git diff --check`.
|
||||||
|
|
||||||
|
|||||||
+1
@@ -16,6 +16,7 @@
|
|||||||
- 四个冲突文件按设计完成合并,保留 Trellis-first overlay、Codex inline、禁止自动提交和 `workspace/` 忽略规则;未保留 `.new` 冲突副本。
|
- 四个冲突文件按设计完成合并,保留 Trellis-first overlay、Codex inline、禁止自动提交和 `workspace/` 忽略规则;未保留 `.new` 冲突副本。
|
||||||
- 0.6.9 runtime 的 `task_context.py` 包含 Python 3.9.2 不接受的嵌套多行 f-string;已改为先构造 warning 再着色,并通过全量 compileall 与 task runtime 验证。
|
- 0.6.9 runtime 的 `task_context.py` 包含 Python 3.9.2 不接受的嵌套多行 f-string;已改为先构造 warning 再着色,并通过全量 compileall 与 task runtime 验证。
|
||||||
- 升级后 dry-run 不再改变 manifest,仅报告 `task_context.py`、`config.yaml`、`.gitignore`、`workflow.md`、`AGENTS.md` 五个有意保留的项目定制。
|
- 升级后 dry-run 不再改变 manifest,仅报告 `task_context.py`、`config.yaml`、`.gitignore`、`workflow.md`、`AGENTS.md` 五个有意保留的项目定制。
|
||||||
|
- 归档最后一个 active task 后,治理检查器曾将正常 idle 状态误报为 `tasks.none`;已调整为允许零个 active task,并增加单元回归测试。
|
||||||
|
|
||||||
### 升级前版本与差异
|
### 升级前版本与差异
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,19 @@ export function contextManifestPolicy(dispatchMode) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function activeTaskDirectoryPolicy(taskCount) {
|
||||||
|
if (taskCount === 0) {
|
||||||
|
return {
|
||||||
|
valid: true,
|
||||||
|
detail: "0 active task directories; idle state after archive is valid",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
valid: true,
|
||||||
|
detail: `${taskCount} task directories have Trellis contracts`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function checkContextManifest(result, taskDir, action, dispatchMode) {
|
function checkContextManifest(result, taskDir, action, dispatchMode) {
|
||||||
const relativePath = `${taskDir}/${action}.jsonl`;
|
const relativePath = `${taskDir}/${action}.jsonl`;
|
||||||
const policy = contextManifestPolicy(dispatchMode);
|
const policy = contextManifestPolicy(dispatchMode);
|
||||||
@@ -209,7 +222,8 @@ function checkTaskContracts(result) {
|
|||||||
const config = exists(".trellis/config.yaml") ? readText(".trellis/config.yaml") : "";
|
const config = exists(".trellis/config.yaml") ? readText(".trellis/config.yaml") : "";
|
||||||
const dispatchMode = /dispatch_mode:\s*sub-agent\b/.test(config) ? "sub-agent" : "inline";
|
const dispatchMode = /dispatch_mode:\s*sub-agent\b/.test(config) ? "sub-agent" : "inline";
|
||||||
if (taskDirs.length === 0) {
|
if (taskDirs.length === 0) {
|
||||||
fail(result, "tasks.none", "no .trellis/tasks/* directories found");
|
const policy = activeTaskDirectoryPolicy(taskDirs.length);
|
||||||
|
pass(result, "task_contracts", policy.detail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +265,10 @@ function checkTaskContracts(result) {
|
|||||||
checkContextManifest(result, dir, "implement", dispatchMode);
|
checkContextManifest(result, dir, "implement", dispatchMode);
|
||||||
checkContextManifest(result, dir, "check", dispatchMode);
|
checkContextManifest(result, dir, "check", dispatchMode);
|
||||||
}
|
}
|
||||||
if (result.status === "PASS") pass(result, "task_contracts", `${taskDirs.length} task directories have Trellis contracts`);
|
if (result.status === "PASS") {
|
||||||
|
const policy = activeTaskDirectoryPolicy(taskDirs.length);
|
||||||
|
pass(result, "task_contracts", policy.detail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkDocsRegistration(result) {
|
function checkDocsRegistration(result) {
|
||||||
|
|||||||
@@ -24,4 +24,11 @@ describe("Trellis context manifest governance", () => {
|
|||||||
rejectSeedRows: true,
|
rejectSeedRows: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts the idle state after the last active task is archived", () => {
|
||||||
|
expect(governance.activeTaskDirectoryPolicy(0)).toEqual({
|
||||||
|
valid: true,
|
||||||
|
detail: "0 active task directories; idle state after archive is valid",
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户