Qualify wait states in the coordination graph (CUST-WP-0074-T04)
Task nodes carry wait_kind (external | human | both | unqualified, null unless wait): the hub field wins, otherwise derived from needs_human and dependency edges (task-level depends_on, or a workplan dependency row whose target the task cites). Workplan nodes carry blocked_kind (human | external | none, null unless blocked). Task-level depends_on becomes a task -> workplan/task depends_on edge; depends_on edges carry edge_kind commitment (cyan #0891b2), human gates are marked on the node (humanGate, rose #be123c). A needs_human=true query / "Needs human" toggle / --needs-human flag keeps only blocked_kind=human workplans and their human-wait tasks; the parameter survives in the shareable URL and mode switch like include_residuals. Fabric stays a read of State Hub. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: sonnet Assistant-Process: 237582@bnt-lap001 Assistant-Session: f2b3d9f1-8fb9-4b9c-bc2b-837ec5dfc826
This commit is contained in:
parent
b47dd43b04
commit
9dbb8f0bcb
7 changed files with 426 additions and 33 deletions
|
|
@ -16,7 +16,9 @@ def test_graph_switch_replaces_data_and_retains_previous_graph_on_failure(tmp_pa
|
|||
)[0]
|
||||
script = r'''
|
||||
const assert = require("node:assert/strict");
|
||||
let graphMode = "full", includeResidualsParam = false, activeMode = "full";
|
||||
let graphMode = "full", includeResidualsParam = false, needsHumanParam = false, activeMode = "full";
|
||||
const coordinationUrl = (includeResiduals, needsHuman) =>
|
||||
`/exports/graph-explorer?mode=coordination${includeResiduals ? "&include_residuals=true" : ""}${needsHuman ? "&needs_human=true" : ""}`;
|
||||
let selected, selectedAnchor, selectedZoneId, focusSet, manualOverrides, filterRules;
|
||||
let editingRuleId, currentProfileId, allEdgeTypes;
|
||||
const layerColors = {}, allNodeTypes = [], nodeTypeLabels = {};
|
||||
|
|
@ -43,6 +45,14 @@ let graphRequest = 0;
|
|||
assert.equal(modeSelect.value, "coordination");
|
||||
assert.equal(controls["include-residuals-wrap"].style.display, "");
|
||||
assert.match(urls[0], /include_residuals=true/);
|
||||
assert.doesNotMatch(urls[0], /needs_human/);
|
||||
await switchGraph("coordination", true, null, true);
|
||||
assert.match(urls[1], /include_residuals=true&needs_human=true/);
|
||||
assert.equal(needsHumanParam, true);
|
||||
assert.equal(controls["needs-human"].checked, true);
|
||||
assert.equal(controls["needs-human-wrap"].style.display, "");
|
||||
await switchGraph("coordination", true, null, false);
|
||||
assert.equal(needsHumanParam, false);
|
||||
response = {ok: false, status: 503};
|
||||
await switchGraph("full");
|
||||
assert.equal(data[0].data.id, "workplan:a");
|
||||
|
|
@ -54,6 +64,7 @@ let graphRequest = 0;
|
|||
assert.equal(activeMode, "by-access-zone");
|
||||
assert.equal(graphMode, "full");
|
||||
assert.equal(controls["include-residuals-wrap"].style.display, "none");
|
||||
assert.equal(controls["needs-human-wrap"].style.display, "none");
|
||||
let resolveOld;
|
||||
fetch = () => new Promise(resolve => {resolveOld = resolve;});
|
||||
const oldRequest = switchGraph("coordination");
|
||||
|
|
@ -62,7 +73,7 @@ let graphRequest = 0;
|
|||
resolveOld({ok: true, json: async () => ({elements: [{data: {id: "stale"}}]})});
|
||||
await oldRequest;
|
||||
assert.equal(data[0].data.id, "latest");
|
||||
assert.equal(updated, 3);
|
||||
assert.equal(updated, 5);
|
||||
})().catch(error => {console.error(error); process.exitCode = 1;});
|
||||
'''
|
||||
path = tmp_path / "switch.cjs"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue