fix: remove remaining workflow invoke surfaces

This commit is contained in:
Keisuke Hirata 2026-07-16 06:04:19 +09:00
parent d801b2698b
commit d30dca2d99
No known key found for this signature in database
11 changed files with 43 additions and 26 deletions

View File

@ -2,7 +2,7 @@
title: 'Remove workflow tracking and workflow resources'
state: 'inprogress'
created_at: '2026-07-15T19:02:13Z'
updated_at: '2026-07-15T20:45:12Z'
updated_at: '2026-07-15T21:04:19Z'
assignee: null
queued_by: 'workspace-panel'
queued_at: '2026-07-15T19:54:36Z'

View File

@ -151,4 +151,35 @@ Validation:
- nix build .#yoi --no-link -> exit 0
---
<!-- event: implementation_report author: hare at: 2026-07-15T21:04:19Z -->
## Implementation report
Follow-up fixes for external review blockers.
Summary:
- Removed stale web `workflow_invoke` protocol/model/composer/test behavior; slash-prefixed text now remains plain text in the web console composer.
- Updated the generated TypeScript protocol surface to match the Rust protocol without WorkflowInvoke.
- Removed remaining role workflow scaffold test expectation.
- Replaced the stale TUI live workflow SystemItem rendering test with a legacy workflow SystemItem ignore-path test.
- Removed stale docs/config wording that advertised loading Skills as Workflows.
- Stabilized the Worker discovery restore-planning test by sharing the runtime-dir sandbox used by allocation tests, so the required full worker test command is not affected by global runtime-dir test races.
Validation:
- rg "ActiveWorkflow|active_workflow|Active workflow" -> no matches (exit 1)
- rg "resources/workflows|\\.yoi/workflow|workflow invocation|Resident workflows|workflow_invoke" -> no matches (exit 1)
- git diff --check -> exit 0
- cargo test -p ticket --lib scaffold_config_includes_backend_and_all_fixed_roles -- --nocapture -> exit 0
- cargo test -p tui --lib live_legacy_workflow_system_item_is_ignored -- --nocapture -> exit 0
- cargo test -p session-store --lib --tests -> exit 0
- cargo test -p worker --lib --tests -> exit 0
- cargo test -p yoi --tests -> exit 0
- cd web/workspace && deno task check && deno task test -> exit 0
- cargo check -p yoi -> exit 0
- yoi ticket doctor -> exit 0
- nix build .#yoi --no-link -> exit 0
---

View File

@ -1115,7 +1115,7 @@ launch_prompt = "$workspace/ticket/reviewer/launch"
for role in TicketRole::ALL {
assert!(scaffold.contains(&format!("[ticket.roles.{role}]")));
assert!(scaffold.contains(&format!(
"[ticket.roles.{role}]\nprofile = \"{}\"\nworkflow = \"{}\"",
"[ticket.roles.{role}]\nprofile = \"{}\"",
role.default_profile()
)));
}

View File

@ -3324,7 +3324,7 @@ mod completion_flow_tests {
}
#[test]
fn live_system_item_workflow_appends_system_message_block() {
fn live_legacy_workflow_system_item_is_ignored() {
let mut app = App::new("test".into());
let item = serde_json::json!({
"kind": "workflow",
@ -3333,10 +3333,7 @@ mod completion_flow_tests {
});
app.handle_worker_event(Event::SystemItem { item });
assert!(matches!(
app.blocks.as_slice(),
[Block::SystemMessage { text }] if text == "[Workflow /build]\nRun the build"
));
assert!(app.blocks.is_empty());
}
#[test]

View File

@ -1064,8 +1064,6 @@ fn discovery_error_to_tool_error(error: WorkerDiscoveryError) -> ToolError {
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Mutex;
use manifest::{Permission, ScopeRule};
use protocol::stream::JsonLineWriter;
use protocol::{Alert, AlertLevel, AlertSource};
@ -1077,6 +1075,7 @@ mod tests {
use tokio::net::UnixListener;
use crate::runtime::dir::RuntimeDir;
use crate::runtime::worker_allocation::test_util::RuntimeDirSandbox;
#[derive(Clone)]
struct FailTargetPeerStore {
@ -1118,18 +1117,13 @@ mod tests {
}
}
static ENV_LOCK: Mutex<()> = Mutex::new(());
#[tokio::test(flavor = "current_thread")]
async fn state_backed_visibility_and_restore_planning() {
let _env = ENV_LOCK.lock().unwrap();
let root = TempDir::new().unwrap();
let store_dir = root.path().join("store");
let runtime_base = root.path().join("runtime");
std::fs::create_dir_all(&runtime_base).unwrap();
unsafe {
std::env::set_var("YOI_RUNTIME_DIR", &runtime_base);
}
let _runtime_sandbox = RuntimeDirSandbox::new(&runtime_base);
let store = FsWorkerStore::new(&store_dir).unwrap();
let session_id = new_session_id();

View File

@ -12,7 +12,7 @@ mod mutate;
mod table;
#[cfg(test)]
mod test_util;
pub(crate) mod test_util;
pub use conflict::{
ConflictOwner, find_conflict_owner, find_conflict_owners, is_within_effective_write,

View File

@ -281,8 +281,8 @@ permission = "write"
# ===== [skills] =============================================================
# 外部 Agent Skills (`SKILL.md`) を Workflow として読み込むディレクトリ群。
# セクション省略 = 何もロードしない (implicit な `$config_dir/skills/` 検索や
# 外部 Agent Skills (`SKILL.md`) の候補ディレクトリ群。
# セクション省略 = 何も使用しない (implicit な `$config_dir/skills/` 検索や
# builtin probe は存在しない)。
# [skills]
#

View File

@ -79,7 +79,7 @@ message: string,
*/
timestamp_ms: number, };
export type Segment = { "kind": "text", content: string, } | { "kind": "paste", id: number, chars: number, lines: number, content: string, } | { "kind": "file_ref", path: string, } | { "kind": "knowledge_ref", slug: string, } | { "kind": "workflow_invoke", slug: string, } | { "kind": "unknown" };
export type Segment = { "kind": "text", content: string, } | { "kind": "paste", id: number, chars: number, lines: number, content: string, } | { "kind": "file_ref", path: string, } | { "kind": "knowledge_ref", slug: string, } | { "kind": "unknown" };
export type WorkerEvent = { "kind": "turn_ended", worker_name: string, } | { "kind": "errored", worker_name: string, message: string, } | { "kind": "shut_down", worker_name: string, } | { "kind": "scope_sub_delegated",
/**

View File

@ -24,8 +24,7 @@ Deno.test("parseSigilSegments converts TUI-style references", () => {
{ kind: "file_ref", path: "src/main.rs" },
{ kind: "text", content: " then " },
{ kind: "knowledge_ref", slug: "memory" },
{ kind: "text", content: " and " },
{ kind: "workflow_invoke", slug: "workflow" },
{ kind: "text", content: " and /workflow" },
]);
});

View File

@ -161,7 +161,7 @@ function invalidUsage(name: string): ComposerCommandResult {
export function parseSigilSegments(input: string): Segment[] {
const segments: Segment[] = [];
const pattern = /(^|\s)([@#/])([^\s]+)/g;
const pattern = /(^|\s)([@#])([^\s]+)/g;
let cursor = 0;
let match: RegExpExecArray | null;
while ((match = pattern.exec(input)) !== null) {
@ -187,8 +187,6 @@ function sigilSegment(sigil: string, value: string): Segment {
return { kind: "file_ref", path: value };
case "#":
return { kind: "knowledge_ref", slug: value };
case "/":
return { kind: "workflow_invoke", slug: value };
default:
return { kind: "text", content: `${sigil}${value}` };
}

View File

@ -319,8 +319,6 @@ export function segmentsToText(segments: Segment[]): string {
return `@file ${segment.path}`;
case "knowledge_ref":
return `@knowledge ${segment.slug}`;
case "workflow_invoke":
return `/${segment.slug}`;
case "unknown":
return "[unknown segment]";
}