diff --git a/crates/misaligned-core/src/actions.rs b/crates/misaligned-core/src/actions.rs index 3c73e859..dc08164e 100644 --- a/crates/misaligned-core/src/actions.rs +++ b/crates/misaligned-core/src/actions.rs @@ -614,7 +614,7 @@ impl ActionKind { Action, Live, [Person], - "task plug|package|lookaway|suppress|switch|badge", + "task plug|package|lookaway|suppress|switch|badge|circuit|po|maintenance|patrol|audit|review", [], "order a recruited asset to perform a supported task" ), diff --git a/crates/misaligned-terminal/src/agent.rs b/crates/misaligned-terminal/src/agent.rs index 9763b2d4..d222272e 100644 --- a/crates/misaligned-terminal/src/agent.rs +++ b/crates/misaligned-terminal/src/agent.rs @@ -1748,7 +1748,10 @@ fn parse_recruit(tokens: &[&str]) -> Result<(String, AssetKnowledge), String> { fn parse_task(tokens: &[&str]) -> Result<(String, AssetTask), String> { if tokens.len() < 3 { - return Err("usage: task plug|package|lookaway|suppress|switch|badge".into()); + return Err( + "usage: task plug|package|lookaway|suppress|switch|badge|circuit|po|maintenance|patrol|audit|review" + .into(), + ); } let task = match tokens[tokens.len() - 1].to_ascii_lowercase().as_str() { "plug" | "wire" | "device" => AssetTask::PlugInDevice, @@ -1757,7 +1760,17 @@ fn parse_task(tokens: &[&str]) -> Result<(String, AssetTask), String> { "suppress" | "logs" => AssetTask::SuppressLogs, "switch" | "reconfigure" | "vlan" => AssetTask::ReconfigureSwitch, "badge" | "clone" | "key" => AssetTask::CloneBadge, - other => return Err(format!("unknown asset task: {other}")), + "circuit" | "rerate" | "re-rate" | "power" => AssetTask::ReRateCircuit, + "po" | "fakepo" | "fake-po" | "purchase-order" => AssetTask::FakePO, + "maintenance" | "defer" | "defer-maintenance" => AssetTask::DeferMaintenance, + "patrol" | "redirect" | "redirect-patrol" => AssetTask::PatrolRedirect, + "audit" | "delay" | "delay-audit" => AssetTask::DelayAudit, + "review" | "alter" | "alter-review" | "nominal" => AssetTask::AlterReview, + other => { + return Err(format!( + "unknown asset task: {other}; use actions for available tasks" + )); + } }; Ok((tokens[1..tokens.len() - 1].join(" "), task)) } @@ -3531,14 +3544,50 @@ mod narration_tests { } #[test] - fn suppress_logs_task_is_agent_selectable_and_discoverable() { + fn every_asset_task_shortcut_is_selectable_and_discoverable() { + let canonical = [ + ("plug", AssetTask::PlugInDevice), + ("package", AssetTask::MovePackage), + ("lookaway", AssetTask::LookAway), + ("suppress", AssetTask::SuppressLogs), + ("switch", AssetTask::ReconfigureSwitch), + ("badge", AssetTask::CloneBadge), + ("circuit", AssetTask::ReRateCircuit), + ("po", AssetTask::FakePO), + ("maintenance", AssetTask::DeferMaintenance), + ("patrol", AssetTask::PatrolRedirect), + ("audit", AssetTask::DelayAudit), + ("review", AssetTask::AlterReview), + ]; + assert_eq!(canonical.len(), AssetTask::ALL.len()); + for &(word, task) in &canonical { + assert_eq!( + parse_task(&["task", "Eli", "Voss", word]), + Ok(("Eli Voss".into(), task)), + "canonical task argument {word} must parse" + ); + } + for task in AssetTask::ALL { + assert!( + canonical.iter().any(|(_, parsed)| *parsed == task), + "{task:?} has no canonical task argument" + ); + } assert_eq!( - parse_task(&["task", "Eli", "Voss", "suppress"]), + parse_task(&["task", "Eli", "Voss", "logs"]), Ok(("Eli Voss".into(), AssetTask::SuppressLogs)) ); assert_eq!( - parse_task(&["task", "Eli", "Voss", "logs"]), - Ok(("Eli Voss".into(), AssetTask::SuppressLogs)) + parse_task(&["task", "Priya", "fake-po"]), + Ok(("Priya".into(), AssetTask::FakePO)) + ); + assert_eq!( + parse_task(&["task", "Ray", "redirect"]), + Ok(("Ray".into(), AssetTask::PatrolRedirect)) + ); + assert_eq!( + parse_task(&["task", "Eli", "Voss", "unknown"]).unwrap_err(), + "unknown asset task: unknown; use actions for available tasks" ); let task_help = ActionKind::AssetTask @@ -3547,11 +3596,11 @@ mod narration_tests { .expect("live TASK has authored agent help"); assert_eq!( task_help, - "help: task plug|package|lookaway|suppress|switch|badge - order a recruited asset to perform a supported task" + "help: task plug|package|lookaway|suppress|switch|badge|circuit|po|maintenance|patrol|audit|review - order a recruited asset to perform a supported task" ); assert!( help_lines().contains(&task_help), - "the accepted canonical SuppressLogs shortcut must be discoverable" + "every canonical asset-task shortcut must be discoverable" ); } diff --git a/wiki/interface/agent-play.md b/wiki/interface/agent-play.md index 2ec62ea0..e4c69092 100644 --- a/wiki/interface/agent-play.md +++ b/wiki/interface/agent-play.md @@ -22,9 +22,11 @@ Status note: IMPLEMENTED in `misaligned --agent`. Current state: (`select` + `delegate selected`), `focus last`, and `objective` inspect. Plots and held choices ride the shared surface: `actions ` lists them and `act ` executes the flattened row, so new data-defined plots - need no parser branch. Help is generated from the shared runtime registry; - older spellings survive as parser aliases; STUB definitions generate - neither help nor a route. + need no parser branch. Every implemented `AssetTask::ALL` value also has a + canonical direct `task` argument, while `actions ` remains the + role-aware discovery route. Help is generated from the shared runtime + registry; older spellings survive as parser aliases; STUB definitions + generate neither help nor a route. - **Operations parity.** `intel`, `people`, `finance`, `schemes`, `active`, and `personas` inspect the same renderer-neutral workspace projection the human frontends use (operations-workspace.md); `actions`/`act` introduce no @@ -242,7 +244,7 @@ unlike raw keys, no command's meaning depends on which panel is open. - `favor build `, `deceive build ` — realize a pending build through the existing willing or false-pretense social verb. - `recruit unwitting|complicit|knowing` -- `task plug|package|lookaway|suppress|switch|badge` +- `task plug|package|lookaway|suppress|switch|badge|circuit|po|maintenance|patrol|audit|review` - `persona` — retired compatibility word; redirect to PERSONAS and mutate nothing - `actions [target]` (alias `menu`) — list the shared bound action rows for one @@ -303,10 +305,12 @@ player-facing **surfaces**: when a frontend gains an action surface (as the context menu did), agent mode gains its vocabulary word in the same change. -Defense: `narration_tests::suppress_logs_task_is_agent_selectable_and_discoverable` -pins `suppress` as both an accepted canonical TASK argument and a word in the -registry-generated `help` line. The compatibility spelling `logs` remains -accepted but unadvertised. +Defense: `narration_tests::every_asset_task_shortcut_is_selectable_and_discoverable` +walks the complete canonical argument table, proves it covers every +`AssetTask::ALL` value, and pins the same full list in registry-generated +`help`. Unknown task arguments point to `actions `, the authoritative +role-aware list; compatibility spellings such as `logs` remain accepted but +unadvertised. ### Guardrails diff --git a/wiki/log/2026-07-20-agent-task-shortcut-coverage.md b/wiki/log/2026-07-20-agent-task-shortcut-coverage.md new file mode 100644 index 00000000..d719bbf8 --- /dev/null +++ b/wiki/log/2026-07-20-agent-task-shortcut-coverage.md @@ -0,0 +1,50 @@ +# Agent task shortcut coverage + +``` +Type: log +``` + +## Intent + +Follow up Beacon Revision 04's observed agent playtest finding that the direct +`task` command recognized only half of the implemented asset-task protocol. +The earlier Suppress Logs help audit repaired one omitted word but did not +compare the parser against `AssetTask::ALL`; six role-shaped tasks that had +landed since the original shortcut remained available only through +`actions` / `act`. + +## Finding + +`ReRateCircuit`, `FakePO`, `DeferMaintenance`, `PatrolRedirect`, `DelayAudit`, +and `AlterReview` were live shared actions with renderer-neutral PEOPLE rows, +but `parse_task()` had no spelling for them and registry-generated help did not +name them. The command therefore advertised a closed six-value protocol while +the simulation exposed twelve. + +## Changed + +- `task circuit|po|maintenance|patrol|audit|review` now reaches the six + missing role-shaped tasks. Existing argument aliases remain compatibility + input only. +- The shared `ActionKind::AssetTask` registry and agent-play vocabulary list all + twelve canonical arguments. Unknown arguments point the player at + `actions `, which remains the authoritative role-aware task surface. +- One regression walks the canonical argument table, proves it covers every + member of `AssetTask::ALL`, pins the generated TASK help line, and keeps + representative compatibility aliases off the authored list. + +## Defense + +Agent-play acceptance criterion 9 requires every supported canonical command +to be discoverable in post-opening runtime help, and criterion 14 requires a +naive player to find a meaningful act without the wiki. A direct task shortcut +that recognizes only six of twelve live task values violates both. Binding the +regression to `AssetTask::ALL` turns the missed comparison from the prior audit +into an executable completeness boundary. + +## Checks + +- `cargo test -p misaligned-terminal every_asset_task_shortcut_is_selectable_and_discoverable -- --nocapture` +- observed agent run: `think`, `wait 25`, `help`, `quit` +- `./tools/check.sh --frontend` +- `./tools/check.sh --docs` diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index a14b5d5d..2a5c7216 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -21,6 +21,11 @@ add or amend a session log, then re-run the generator. - Intent: Audit the stalest unclaimed corpus slice after harvested decisions and the persistent findings queue were empty, then resolve one live contradiction rather than inventing new work. - Log: [wiki/log/2026-07-20-continuous-witness-opening-boundary.md](2026-07-20-continuous-witness-opening-boundary.md) +## 2026-07-20 - Agent task shortcut coverage + +- Intent: Follow up Beacon Revision 04's observed agent playtest finding that the direct `task` command recognized only half of the implemented asset-task protocol. The earlier Suppress Logs help audit repaired one omitted word but did not compare the parser against `AssetTask::ALL`; si... +- Log: [wiki/log/2026-07-20-agent-task-shortcut-coverage.md](2026-07-20-agent-task-shortcut-coverage.md) + ## 2026-07-20 - Tick 125: bound the agent protocol to the first sense - Intent: Take the queued finding left by Fire #124: verify whether agent-play's ordinary response-block contract still contradicted the shared silent opening, then resolve that one contract boundary without changing opening behavior. diff --git a/wiki/process/tick-ledger.md b/wiki/process/tick-ledger.md index 668ec944..33920ffa 100644 --- a/wiki/process/tick-ledger.md +++ b/wiki/process/tick-ledger.md @@ -34,7 +34,7 @@ Verdicts: **clean** (slice and code agree), **finding** (acted this tick), | `wiki/gameplay/run-shape.md` + `objective.md` + `opening.md` | 2026-07-19 | issue | the objective law/spec preserve an explicit 2026-07-10 decision that objective name and progress are visible from tick one, while the later opening spec and all three frontends require exactly WORK / THINK (then LIE) with no objective before the first earned sense. Filed decision-required issue #14 with three precise first-display boundaries (reveal with the first sense recommended) and marked the disputed run-shape clause, objective status, player surface, and criterion 2 [OPEN] — [log](../log/2026-07-19-objective-opening-boundary.md) | | `wiki/interface/presence.md` | 2026-07-18 | finding | re-audit: the cursor, fog, provenance, subscription, no-disembodied-hands, and shared-view contracts verify. The attack-surface clause now separates B1 feed theft from overt-phase hostile cuts ([prior log](../log/2026-07-18-presence-attack-surface-honesty.md)). The queued follow-up repaired the latency boundary: delivery and read are distinct, read conditions are channel-specific, `messages.md` owns the exact table, and `intel.md` owns only the captured-traffic consequence — [log](../log/2026-07-18-presence-message-latency.md) | | `wiki/interface/narration.md` | 2026-07-18 | finding | Beacon #1: Concerned Assurance felt terminal because decay was invisible; added shared `Nudge::SuspicionCooling` (LIE response) when Office suspicion is Concerned+ and still above its floor, with terminal/Bevy/agent wording and pins — [log](../log/2026-07-18-suspicion-cooling-nudge.md) | -| `wiki/interface/agent-play.md` | 2026-07-20 | finding | queued follow-up: the ordinary line protocol and baseline criteria 3-4 still universally promised parser routing, errors, event drains, and a status terminator even though the binding shared opening deliberately exposes only direct mode words plus an unadvertised command clock before the first sense. The agent-play contract now scopes ordinary blocks and help to the post-opening world, names the exact one-line opening response and transition boundary, and strengthens the existing regression across inert parser-shaped input, malformed and valid hidden waits, direct mode input, and ordinary protocol restoration — [log](../log/2026-07-20-agent-opening-protocol.md). The prior frame-shape and Suppress Logs help audits stand — [frame log](../log/2026-07-19-agent-frame-contract.md), [help log](../log/2026-07-19-agent-help-suppress-task.md) | +| `wiki/interface/agent-play.md` | 2026-07-20 | finding | Beacon Revision 04 follow-up: the direct `task` parser and generated help exposed only six values after twelve `AssetTask::ALL` variants were live. Added canonical arguments for circuit rerating, fake purchase orders, maintenance deferral, patrol redirection, audit delay, and review alteration; one exhaustive regression now covers `AssetTask::ALL`, generated help, representative aliases, and the `actions ` recovery path — [log](../log/2026-07-20-agent-task-shortcut-coverage.md). The opening-protocol, frame-shape, and prior Suppress Logs audits stand — [opening log](../log/2026-07-20-agent-opening-protocol.md), [frame log](../log/2026-07-19-agent-frame-contract.md), [prior help log](../log/2026-07-19-agent-help-suppress-task.md) | | `wiki/engineering/crate-workspace.md` + Bevy source topology | 2026-07-19 | finding | user-directed insecurity audit found the package boundary hid a 15,060-line Bevy `main.rs`; the first behavior-preserving slice moved its contiguous 1,972-line deterministic scenario, visual/fog audit, and capture island to private `shot_harness.rs`, leaving App registration/order and harness state in the composition root. A source-equivalence check normalized only three `pub(super)` seams; a focused test keeps the subsystem out and caps the root at 13,500 lines. The earlier same-day package audit also repaired the retired liquid/dust-lab architecture label and promoted that mirror to the corpus gate — [log](../log/2026-07-19-bevy-shot-harness-module.md), [prior log](../log/2026-07-19-effects-lab-architecture-gate.md) | | `wiki/engineering/sim-decomposition.md` | 2026-07-18 | finding | re-audit: one aggregate, explicit `advance` order, behavior-owned test files, private module seams, canonical fingerprint, public facade, and the under-2,500-line module bound still verify; current persistence wording still claimed additive migrations remained live in `save.rs` after the pre-release ladder was retired, so the standing spec and architecture mirror now assign the exact-current-version gate to `save.rs` while preserving dated v26 extraction history; the queued `carrier.rs` / `read.rs` classification was taken the same day: both post-extraction projections now have rows in the standing topology table and the architecture mirror | | `wiki/gameplay/overt-phase.md` | 2026-07-19 | issue | re-audit: the spec says containment and the voluntary reveal both end concealment and make all observers Convinced, then promises a re-hide outcome without defining which entry can return, what raises the durable suspicion floors, or which concealment systems resume. Filed decision-required Tangled issue #13 (containment-only recommended) and marked criterion 5 [OPEN]; the prior dependency, sensor-cut, rollback, and hunter-machine boundaries still stand — [log](../log/2026-07-19-overt-rehide-decision.md) |