@alisio/plugin-swarm 0.0.0-stage → 0.1.1
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.
- package/.agents/agents/swarm-architect.md +20 -0
- package/.agents/agents/swarm-cleaner.md +20 -0
- package/.agents/agents/swarm-coder.md +20 -0
- package/.agents/agents/swarm-hardener.md +20 -0
- package/.agents/agents/swarm-lieutenant.md +20 -0
- package/.agents/agents/swarm-qa.md +20 -0
- package/.agents/agents/swarm-refactorer.md +20 -0
- package/.agents/agents/swarm-specifier.md +20 -0
- package/.agents/skills/swarm-architecture-rules/SKILL.md +43 -0
- package/.agents/skills/swarm-clarification/SKILL.md +42 -0
- package/.agents/skills/swarm-cleaner-metrics/SKILL.md +44 -0
- package/.agents/skills/swarm-engineering-constitution/SKILL.md +44 -0
- package/.agents/skills/swarm-gherkin-spec/SKILL.md +43 -0
- package/.agents/skills/swarm-handoff-protocol/SKILL.md +45 -0
- package/.agents/skills/swarm-lieutenant/SKILL.md +41 -0
- package/.agents/skills/swarm-mutation-hardening/SKILL.md +43 -0
- package/.agents/skills/swarm-qa-acceptance/SKILL.md +42 -0
- package/.agents/skills/swarm-tdd-slice/SKILL.md +44 -0
- package/.agents/skills/swarm-toolchain-profile/SKILL.md +41 -0
- package/LICENSE +21 -0
- package/README.es.md +337 -0
- package/README.md +322 -2
- package/assets/approval-flow.svg +1 -0
- package/assets/architecture.svg +1 -0
- package/assets/audit-states.svg +1 -0
- package/assets/dashboard.css +964 -0
- package/assets/dashboard.html +123 -0
- package/assets/dashboard.js +965 -0
- package/assets/dashboard.svg +1 -0
- package/assets/handoff-sequence.svg +1 -0
- package/assets/pack-pipelines.svg +1 -0
- package/assets/packs/four-pack/pack.json +18 -0
- package/assets/packs/six-pack/pack.json +22 -0
- package/assets/packs/two-pack/pack.json +14 -0
- package/assets/screenshots/dashboard-board-dark.png +0 -0
- package/assets/screenshots/dashboard-board-light.png +0 -0
- package/assets/screenshots/dashboard-documents-diff.png +0 -0
- package/assets/screenshots/dashboard-empty-state.png +0 -0
- package/assets/screenshots/dashboard-phone.png +0 -0
- package/assets/screenshots/dashboard-reject-dialog.png +0 -0
- package/assets/screenshots/dashboard-transcript-tail.png +0 -0
- package/assets/screenshots/dashboard-work-queue.png +0 -0
- package/assets/task-states.svg +1 -0
- package/assets/toolchains/node-ts.json +61 -0
- package/cover.svg +46 -0
- package/dist/adapters/child-session-runner.d.ts +36 -0
- package/dist/adapters/child-session-runner.d.ts.map +1 -0
- package/dist/adapters/child-session-runner.js +156 -0
- package/dist/adapters/child-session-runner.js.map +1 -0
- package/dist/adapters/fs-board-store.d.ts +11 -0
- package/dist/adapters/fs-board-store.d.ts.map +1 -0
- package/dist/adapters/fs-board-store.js +27 -0
- package/dist/adapters/fs-board-store.js.map +1 -0
- package/dist/adapters/fs-handoff-store.d.ts +36 -0
- package/dist/adapters/fs-handoff-store.d.ts.map +1 -0
- package/dist/adapters/fs-handoff-store.js +254 -0
- package/dist/adapters/fs-handoff-store.js.map +1 -0
- package/dist/adapters/fs-task-state-store.d.ts +16 -0
- package/dist/adapters/fs-task-state-store.d.ts.map +1 -0
- package/dist/adapters/fs-task-state-store.js +66 -0
- package/dist/adapters/fs-task-state-store.js.map +1 -0
- package/dist/adapters/git-worktree.d.ts +31 -0
- package/dist/adapters/git-worktree.d.ts.map +1 -0
- package/dist/adapters/git-worktree.js +209 -0
- package/dist/adapters/git-worktree.js.map +1 -0
- package/dist/adapters/process-exec.d.ts +36 -0
- package/dist/adapters/process-exec.d.ts.map +1 -0
- package/dist/adapters/process-exec.js +138 -0
- package/dist/adapters/process-exec.js.map +1 -0
- package/dist/adapters/process-gate-runner.d.ts +39 -0
- package/dist/adapters/process-gate-runner.d.ts.map +1 -0
- package/dist/adapters/process-gate-runner.js +242 -0
- package/dist/adapters/process-gate-runner.js.map +1 -0
- package/dist/adapters/unavailable-runner.d.ts +4 -0
- package/dist/adapters/unavailable-runner.d.ts.map +1 -0
- package/dist/adapters/unavailable-runner.js +12 -0
- package/dist/adapters/unavailable-runner.js.map +1 -0
- package/dist/app/audit.d.ts +23 -0
- package/dist/app/audit.d.ts.map +1 -0
- package/dist/app/audit.js +9 -0
- package/dist/app/audit.js.map +1 -0
- package/dist/app/budget.d.ts +29 -0
- package/dist/app/budget.d.ts.map +1 -0
- package/dist/app/budget.js +78 -0
- package/dist/app/budget.js.map +1 -0
- package/dist/app/chat-store.d.ts +18 -0
- package/dist/app/chat-store.d.ts.map +1 -0
- package/dist/app/chat-store.js +48 -0
- package/dist/app/chat-store.js.map +1 -0
- package/dist/app/documents.d.ts +33 -0
- package/dist/app/documents.d.ts.map +1 -0
- package/dist/app/documents.js +63 -0
- package/dist/app/documents.js.map +1 -0
- package/dist/app/forge.d.ts +106 -0
- package/dist/app/forge.d.ts.map +1 -0
- package/dist/app/forge.js +420 -0
- package/dist/app/forge.js.map +1 -0
- package/dist/app/operator.d.ts +46 -0
- package/dist/app/operator.d.ts.map +1 -0
- package/dist/app/operator.js +168 -0
- package/dist/app/operator.js.map +1 -0
- package/dist/app/pidfile.d.ts +18 -0
- package/dist/app/pidfile.d.ts.map +1 -0
- package/dist/app/pidfile.js +56 -0
- package/dist/app/pidfile.js.map +1 -0
- package/dist/app/project.d.ts +93 -0
- package/dist/app/project.d.ts.map +1 -0
- package/dist/app/project.js +291 -0
- package/dist/app/project.js.map +1 -0
- package/dist/app/prompts.d.ts +48 -0
- package/dist/app/prompts.d.ts.map +1 -0
- package/dist/app/prompts.js +88 -0
- package/dist/app/prompts.js.map +1 -0
- package/dist/app/pump.d.ts +144 -0
- package/dist/app/pump.d.ts.map +1 -0
- package/dist/app/pump.js +707 -0
- package/dist/app/pump.js.map +1 -0
- package/dist/app/services.d.ts +112 -0
- package/dist/app/services.d.ts.map +1 -0
- package/dist/app/services.js +323 -0
- package/dist/app/services.js.map +1 -0
- package/dist/app/state.d.ts +70 -0
- package/dist/app/state.d.ts.map +1 -0
- package/dist/app/state.js +96 -0
- package/dist/app/state.js.map +1 -0
- package/dist/args.d.ts +10 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +33 -0
- package/dist/args.js.map +1 -0
- package/dist/coordinator.d.ts +80 -0
- package/dist/coordinator.d.ts.map +1 -0
- package/dist/coordinator.js +481 -0
- package/dist/coordinator.js.map +1 -0
- package/dist/dashboard/api.d.ts +28 -0
- package/dist/dashboard/api.d.ts.map +1 -0
- package/dist/dashboard/api.js +178 -0
- package/dist/dashboard/api.js.map +1 -0
- package/dist/dashboard/auth.d.ts +13 -0
- package/dist/dashboard/auth.d.ts.map +1 -0
- package/dist/dashboard/auth.js +36 -0
- package/dist/dashboard/auth.js.map +1 -0
- package/dist/dashboard/open.d.ts +7 -0
- package/dist/dashboard/open.d.ts.map +1 -0
- package/dist/dashboard/open.js +17 -0
- package/dist/dashboard/open.js.map +1 -0
- package/dist/dashboard/server.d.ts +28 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +176 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/doctor.d.ts +28 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +108 -0
- package/dist/doctor.js.map +1 -0
- package/dist/domain/attention.d.ts +20 -0
- package/dist/domain/attention.d.ts.map +1 -0
- package/dist/domain/attention.js +41 -0
- package/dist/domain/attention.js.map +1 -0
- package/dist/domain/envelope.d.ts +37 -0
- package/dist/domain/envelope.d.ts.map +1 -0
- package/dist/domain/envelope.js +106 -0
- package/dist/domain/envelope.js.map +1 -0
- package/dist/domain/handoff.d.ts +57 -0
- package/dist/domain/handoff.d.ts.map +1 -0
- package/dist/domain/handoff.js +191 -0
- package/dist/domain/handoff.js.map +1 -0
- package/dist/domain/identifiers.d.ts +18 -0
- package/dist/domain/identifiers.d.ts.map +1 -0
- package/dist/domain/identifiers.js +70 -0
- package/dist/domain/identifiers.js.map +1 -0
- package/dist/domain/pack.d.ts +45 -0
- package/dist/domain/pack.d.ts.map +1 -0
- package/dist/domain/pack.js +207 -0
- package/dist/domain/pack.js.map +1 -0
- package/dist/domain/pipeline.d.ts +33 -0
- package/dist/domain/pipeline.d.ts.map +1 -0
- package/dist/domain/pipeline.js +50 -0
- package/dist/domain/pipeline.js.map +1 -0
- package/dist/domain/task.d.ts +26 -0
- package/dist/domain/task.d.ts.map +1 -0
- package/dist/domain/task.js +154 -0
- package/dist/domain/task.js.map +1 -0
- package/dist/domain/taskstate.d.ts +37 -0
- package/dist/domain/taskstate.d.ts.map +1 -0
- package/dist/domain/taskstate.js +98 -0
- package/dist/domain/taskstate.js.map +1 -0
- package/dist/gates/dry.d.ts +14 -0
- package/dist/gates/dry.d.ts.map +1 -0
- package/dist/gates/dry.js +71 -0
- package/dist/gates/dry.js.map +1 -0
- package/dist/gates/parsers.d.ts +34 -0
- package/dist/gates/parsers.d.ts.map +1 -0
- package/dist/gates/parsers.js +120 -0
- package/dist/gates/parsers.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/options.d.ts +13 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +27 -0
- package/dist/options.js.map +1 -0
- package/dist/panel.d.ts +5 -0
- package/dist/panel.d.ts.map +1 -0
- package/dist/panel.js +52 -0
- package/dist/panel.js.map +1 -0
- package/dist/ports/agent-runner.d.ts +51 -0
- package/dist/ports/agent-runner.d.ts.map +1 -0
- package/dist/ports/agent-runner.js +2 -0
- package/dist/ports/agent-runner.js.map +1 -0
- package/dist/ports/board-store.d.ts +7 -0
- package/dist/ports/board-store.d.ts.map +1 -0
- package/dist/ports/board-store.js +2 -0
- package/dist/ports/board-store.js.map +1 -0
- package/dist/ports/clock.d.ts +5 -0
- package/dist/ports/clock.d.ts.map +1 -0
- package/dist/ports/clock.js +2 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/gate-runner.d.ts +34 -0
- package/dist/ports/gate-runner.d.ts.map +1 -0
- package/dist/ports/gate-runner.js +2 -0
- package/dist/ports/gate-runner.js.map +1 -0
- package/dist/ports/handoff-store.d.ts +39 -0
- package/dist/ports/handoff-store.d.ts.map +1 -0
- package/dist/ports/handoff-store.js +2 -0
- package/dist/ports/handoff-store.js.map +1 -0
- package/dist/ports/isolation.d.ts +43 -0
- package/dist/ports/isolation.d.ts.map +1 -0
- package/dist/ports/isolation.js +2 -0
- package/dist/ports/isolation.js.map +1 -0
- package/dist/ports/notifier.d.ts +28 -0
- package/dist/ports/notifier.d.ts.map +1 -0
- package/dist/ports/notifier.js +2 -0
- package/dist/ports/notifier.js.map +1 -0
- package/dist/ports/task-state-store.d.ts +10 -0
- package/dist/ports/task-state-store.d.ts.map +1 -0
- package/dist/ports/task-state-store.js +2 -0
- package/dist/ports/task-state-store.js.map +1 -0
- package/dist/refs.d.ts +10 -0
- package/dist/refs.d.ts.map +1 -0
- package/dist/refs.js +19 -0
- package/dist/refs.js.map +1 -0
- package/dist/resources.d.ts +55 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +255 -0
- package/dist/resources.js.map +1 -0
- package/dist/status.d.ts +18 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +60 -0
- package/dist/status.js.map +1 -0
- package/dist/storage.d.ts +18 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +79 -0
- package/dist/storage.js.map +1 -0
- package/dist/toolchains/profile.d.ts +21 -0
- package/dist/toolchains/profile.d.ts.map +1 -0
- package/dist/toolchains/profile.js +60 -0
- package/dist/toolchains/profile.js.map +1 -0
- package/dist/toolchains/thresholds.d.ts +29 -0
- package/dist/toolchains/thresholds.d.ts.map +1 -0
- package/dist/toolchains/thresholds.js +45 -0
- package/dist/toolchains/thresholds.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +51 -3
package/README.md
CHANGED
|
@@ -1,3 +1,323 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @alisio/plugin-swarm
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
> Español: [README.es.md](./README.es.md). The two READMEs must be updated together.
|
|
6
|
+
|
|
7
|
+
Swarm for Alisio runs a pipeline of specialised agents. Each agent works in its own git worktree and
|
|
8
|
+
passes committed work to the next one through durable handoff files. Deterministic code owns routing,
|
|
9
|
+
state and quality gates; agents only return strict JSON envelopes that the code validates.
|
|
10
|
+
|
|
11
|
+
> **Status: pre-release.** Everything below is implemented and tested with scripted fakes, including
|
|
12
|
+
> the local dashboard. The Alisio child-session runner, background execution and the dashboard have
|
|
13
|
+
> not been exercised against a live Alisio host yet; see "Running it for real".
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
Commands, tools, the dashboard and the TUI panel are thin front ends over one services layer, which
|
|
20
|
+
drives pure domain code through ports (agent runner, isolation, stores, gate runner).
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- Node.js 22.16 or newer and `@alisio/sdk` 0.3 to 0.6.
|
|
25
|
+
- `git` 2.28 or newer on `PATH`. Run `/swarm:doctor` to check.
|
|
26
|
+
- No credentials and no network access, except when you clone a GitHub repository.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
alisio install npm:@alisio/plugin-swarm
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quickstart
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
/swarm:init
|
|
38
|
+
/swarm:doctor
|
|
39
|
+
/swarm:pack list
|
|
40
|
+
/swarm:project new demo --pack two-pack -- A small todo application
|
|
41
|
+
/swarm:task demo new -- Add a form to create todos
|
|
42
|
+
/swarm:status
|
|
43
|
+
/swarm:dashboard
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Commands
|
|
47
|
+
|
|
48
|
+
| Command | Purpose |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `/swarm:init` | Create the forge under `.alisio/swarm` in the workspace. |
|
|
51
|
+
| `/swarm:doctor` | Check Node.js, git, the toolchain commands and the workspace. |
|
|
52
|
+
| `/swarm:pack list` / `show <name>` | List shipped and workspace packs, or show one. |
|
|
53
|
+
| `/swarm:project new <name> [--pack <p>] [--github <owner/repo>] -- <mission>` | Create and open a project. |
|
|
54
|
+
| `/swarm:project open <name>` / `close <name>` / `list` | Open, close or list projects. Closing never touches project files. |
|
|
55
|
+
| `/swarm:task <project> new [name] -- <text>` | Create a task card and queue it for the first role. |
|
|
56
|
+
| `/swarm:task <project> retry <name>` / `delete <name>` / `accept <name>` | Retry a stuck task, archive and remove it, or accept its work as it is. |
|
|
57
|
+
| `/swarm:status [project]` | Show lanes, tasks and items that need your attention. |
|
|
58
|
+
| `/swarm:approve <project>/<task>` | Approve the handoff held at the approval gate. Disabled while document comments exist. |
|
|
59
|
+
| `/swarm:reject <project>/<task> retry\|delete\|accept [-- comments]` | Retry (rejected commit kept under `refs/swarm/rejected/<task>`, base restored, role re-run with your findings), delete, or accept unchanged. |
|
|
60
|
+
| `/swarm:comment <project>/<task> <document> -- <text>` / `<project>/<task> clear` | Comment on a document of a task waiting for approval, or clear the comments. |
|
|
61
|
+
| `/swarm:answer <project>/<task> -- <text>` | Answer a clarification question from a role. |
|
|
62
|
+
| `/swarm:chat [project] -- <message>` | Talk to the read-only Lieutenant of a project. |
|
|
63
|
+
| `/swarm:stop <project>` | Cancel the project's agents and halt its pump; the project stays open. |
|
|
64
|
+
| `/swarm:run <project> [--seconds <1-3600>]` | Run the pump in the foreground until the project is idle (see "Running it for real"). |
|
|
65
|
+
| `/swarm:budget` / `budget raise <tokens>` | Show the swarm token budget or raise the cap. |
|
|
66
|
+
| `/swarm:dashboard [project\|project/task]` | Start the local follow-up dashboard and print its link (see "Dashboard"). |
|
|
67
|
+
| `/swarm:teardown --confirm TEARDOWN` | Cancel every agent and stop every project. Project files stay. |
|
|
68
|
+
|
|
69
|
+
A reference is `<project>/<task>` or the id of an item under needs your attention
|
|
70
|
+
(`approval:<project>:<task>`). In an interactive session, `approve`, `reject` and `teardown` ask with
|
|
71
|
+
`ui.askQuestions` when an argument is missing; headless, the command forms above are the contract.
|
|
72
|
+
|
|
73
|
+
The tools `swarm_status`, `swarm_task_new`, `swarm_gate_run` and `swarm_doctor` expose the same
|
|
74
|
+
services to agents. `swarm_gate_run` runs one named quality gate for a role and returns its report.
|
|
75
|
+
|
|
76
|
+
## Agents
|
|
77
|
+
|
|
78
|
+
Every agent is named with the `swarm-` prefix (`swarm-specifier`, `swarm-coder`, `swarm-cleaner`,
|
|
79
|
+
`swarm-refactorer`, `swarm-architect`, `swarm-hardener`, `swarm-qa`, `swarm-lieutenant`) so the host
|
|
80
|
+
agent catalog never collides with another plugin that ships a `specifier` or `coder`. Pack role ids stay
|
|
81
|
+
short (`coder`, `qa`); one map in the plugin turns a role id into its agent name. Each agent file
|
|
82
|
+
declares its tools, turn limit, timeout and output budget; children can never call `task`, `delegate`,
|
|
83
|
+
`subagent` or `sessions_create`, and read-only roles run with `readOnly: true`.
|
|
84
|
+
|
|
85
|
+
## Packs
|
|
86
|
+
|
|
87
|
+
A pack is data: the ordered roles, which role works on the main checkout, the approval gate, quality
|
|
88
|
+
gates and thresholds. Packs ship with the plugin and can also live in `.alisio/swarm/packs/<name>.json`
|
|
89
|
+
in the workspace; a workspace pack shadows a shipped pack with the same name.
|
|
90
|
+
|
|
91
|
+

|
|
92
|
+
|
|
93
|
+
The shipped pipelines, in order; the approval gate sits after the specifier in four-pack and six-pack.
|
|
94
|
+
|
|
95
|
+
| Pack | Pipeline |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| `two-pack` | coder, cleaner |
|
|
98
|
+
| `four-pack` | specifier, coder, refactorer, architect (approval after the specifier) |
|
|
99
|
+
| `six-pack` | specifier, coder, cleaner, architect, hardener, qa (approval after the specifier) |
|
|
100
|
+
|
|
101
|
+
The last role's handoff is broadcast merge-only to every other role and moves the card to Done.
|
|
102
|
+
Default thresholds (coverage 80 percent, complexity 6, CRAP 8, mutation 80 percent) are pack data and
|
|
103
|
+
can be changed per pack. The CRAP formula is the published `CC^2 * (1 - coverage)^3 + CC`.
|
|
104
|
+
|
|
105
|
+
## How it works
|
|
106
|
+
|
|
107
|
+
- **Worktrees.** The master role works on the project's main checkout. Every other role gets a
|
|
108
|
+
worktree on the branch `swarm/<project>/<role>`. A `commit-msg` hook appends `By <role>.`.
|
|
109
|
+
- **Handoffs.** Work travels as a ten-character commit id inside a header-plus-body file under
|
|
110
|
+
`<project>/.alisio/swarm/handoffs/<role>/`. Files are the source of truth: after a crash the pump
|
|
111
|
+
replays the outbox and the board is rebuilt from them.
|
|
112
|
+
- **Merges.** The coordinator merges the sender's commit into the receiver's worktree before the
|
|
113
|
+
receiver runs. Conflicts are handed to the receiving role as part of its task.
|
|
114
|
+
- **Audit handshake.** The first handoff envelope is parked, the same session is asked to re-verify,
|
|
115
|
+
and an unchanged second envelope releases it.
|
|
116
|
+
- **Strict envelopes.** Invalid output (including output cut short by the turn limit) is rejected,
|
|
117
|
+
never repaired, and retried at most once before the card becomes blocked and appears under needs
|
|
118
|
+
your attention.
|
|
119
|
+
- **Approval gate.** In packs with `approval.after`, the handoff of that role is held until you
|
|
120
|
+
approve it. Reject offers retry, delete or accept unchanged.
|
|
121
|
+
- **Clarifications.** A role can ask one question; the card shows `clarifying` and the question is
|
|
122
|
+
persisted, so it survives a restart. Your answer resumes the same session (or a fresh one with the
|
|
123
|
+
question repeated after a restart).
|
|
124
|
+
- **Holds survive restarts.** Clarifications, agent-reported blocks, gate failures, approvals and
|
|
125
|
+
their comments are persisted. A runtime failure (for example output rejected twice) is retried
|
|
126
|
+
after a restart instead.
|
|
127
|
+
|
|
128
|
+
## Handoffs, audits and task states
|
|
129
|
+
|
|
130
|
+

|
|
131
|
+
|
|
132
|
+
A handoff is parked, audited with a second envelope, gated by code, then delivered and merged.
|
|
133
|
+
|
|
134
|
+

|
|
135
|
+
|
|
136
|
+
A card is `queued`, `working`, `merging`, `waiting_approval`, `clarifying`, `blocked`, `rejected` or `done`.
|
|
137
|
+
|
|
138
|
+

|
|
139
|
+
|
|
140
|
+
The audit releases a handoff only when the second envelope names the same commit and the gates pass.
|
|
141
|
+
|
|
142
|
+

|
|
143
|
+
|
|
144
|
+
Approval is blocked while document comments exist; reject offers retry, delete or accept unchanged.
|
|
145
|
+
|
|
146
|
+
## Quality gates
|
|
147
|
+
|
|
148
|
+
After the audit is unchanged, the coordinator runs the role's gates from the pack (`gates` block)
|
|
149
|
+
with the `node-ts` toolchain profile. A failing gate returns its report to the same role, which fixes
|
|
150
|
+
it and goes through the audit again. After `limits.maxBounces` (default 2) failures the task is
|
|
151
|
+
blocked and you decide: retry (fresh allowance), accept as it is, or delete.
|
|
152
|
+
|
|
153
|
+
| Gate | What it checks |
|
|
154
|
+
| --- | --- |
|
|
155
|
+
| `tests-green` | The profile's `test` command exits 0. |
|
|
156
|
+
| `test-first` | A test file is part of the role's diff since its base commit. |
|
|
157
|
+
| `coverage` | Overall line coverage from the coverage summary meets `thresholds.coverage`. |
|
|
158
|
+
| `crap` | For changed functions, complexity and CRAP (`CC^2 * (1 - coverage)^3 + CC`, using the file's coverage) stay under `thresholds.complexity` and `thresholds.crap`. |
|
|
159
|
+
| `dry` | No block of 6 identical significant lines duplicated against a changed file. |
|
|
160
|
+
| `mutation` | Differential: Stryker runs on the changed source files only and the score meets `thresholds.mutation`. |
|
|
161
|
+
| `acceptance` | The profile's `acceptance` command (falling back to `test`) exits 0. |
|
|
162
|
+
| `structure` | Skipped with a stated reason: there is no deterministic structure checker yet. |
|
|
163
|
+
|
|
164
|
+
Thresholds come from the pack, never from constants. Gate processes run from argument arrays with a
|
|
165
|
+
timeout, an output cap and a scrubbed environment. A gate that cannot run at all (missing tool,
|
|
166
|
+
unparseable report) does not bounce the role: it blocks the task with the reason.
|
|
167
|
+
|
|
168
|
+
QA rejection: when the last role reports `blocked`, its findings go back to the coder by default (or
|
|
169
|
+
to the role named by `rejectTo` on that role, or by a `route: <role>` line in the findings), bounded
|
|
170
|
+
by `maxBounces`. A pack may declare `parallel` stages (adjacent roles that are not the master or the
|
|
171
|
+
last role): they run concurrently and the next role receives all their commits, merged in pack
|
|
172
|
+
order, once every role of the stage has handed off.
|
|
173
|
+
|
|
174
|
+
## Toolchain configuration
|
|
175
|
+
|
|
176
|
+
v1 ships one toolchain profile, `node-ts` (`assets/toolchains/node-ts.json`). It declares argument
|
|
177
|
+
arrays and output parsers, never shell strings. Your project must provide:
|
|
178
|
+
|
|
179
|
+
| Gate input | Command run | Needs |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| tests | `npm test --silent` | a `test` script |
|
|
182
|
+
| coverage | `npx vitest run --coverage --coverage.reporter=json-summary` | Vitest with a coverage provider |
|
|
183
|
+
| complexity (CRAP) | `npx eslint --format json --rule complexity ...` | ESLint |
|
|
184
|
+
| mutation | `npx stryker run --incremental` | Stryker with the JSON reporter |
|
|
185
|
+
| acceptance | `npm run --if-present test:acceptance --silent` | optional script; falls back to `test` |
|
|
186
|
+
|
|
187
|
+
`/swarm:doctor` reports which commands are missing. Thresholds and limits (`coverage`, `complexity`,
|
|
188
|
+
`crap`, `mutation`, `maxBounces`, `maxAuditRounds`) are pack data. Other toolchains (go, java, python,
|
|
189
|
+
clojure) are not shipped in v1.
|
|
190
|
+
|
|
191
|
+
## Token budget
|
|
192
|
+
|
|
193
|
+
`options.tokenBudget` is a soft cap on total tokens across the swarm. When it is reached the pumps
|
|
194
|
+
stop starting new runs (runs in flight finish) and a decision appears under needs your attention. Raise
|
|
195
|
+
the cap with `/swarm:budget raise <tokens>`. Idle roles never run: there are no eager agents.
|
|
196
|
+
|
|
197
|
+
## Running it for real
|
|
198
|
+
|
|
199
|
+
Child sessions are created lazily from the session that last issued a `/swarm` command, with the
|
|
200
|
+
role's worktree as the workspace, and are cancelled on close, stop, teardown and dispose. The pump
|
|
201
|
+
runs in the background of the host process. Whether a promise that outlives its command keeps running,
|
|
202
|
+
how the host schedules concurrent child runs, and how headless `permission: ask` behaves are not
|
|
203
|
+
verified against a live host yet. If the background pump stalls, `/swarm:run <project>` drives it in
|
|
204
|
+
the foreground for up to an hour; a one-second safety tick restarts stalled work when the process is
|
|
205
|
+
alive. A pidfile under `.alisio/swarm` flags a previous process that died without cleaning up.
|
|
206
|
+
|
|
207
|
+
## Options
|
|
208
|
+
|
|
209
|
+
Set them under `pluginOverrides.swarm.options` in the Alisio configuration:
|
|
210
|
+
|
|
211
|
+
| Option | Default | Meaning |
|
|
212
|
+
| --- | --- | --- |
|
|
213
|
+
| `maxConcurrent` | `3` | Roles running at the same time (1 to 8). |
|
|
214
|
+
| `roles.<role>.model` | session model | Model for one role. |
|
|
215
|
+
| `tokenBudget` | none | Soft cap on total tokens (at least 1000). |
|
|
216
|
+
|
|
217
|
+
## Dashboard
|
|
218
|
+
|
|
219
|
+
The dashboard is a **follow-up view** of the swarm running in your workspace. Work is started and
|
|
220
|
+
managed from the Alisio chat with `/swarm:*` commands; the page only offers what the chat does
|
|
221
|
+
poorly: watching many roles at once, reading evidence, and making review decisions next to it.
|
|
222
|
+
Every role, the Lieutenant included, runs as an Alisio child session.
|
|
223
|
+
|
|
224
|
+
`/swarm:dashboard [project | project/task]` starts a local web page on `127.0.0.1` (ephemeral port),
|
|
225
|
+
prints its link and tries to open your browser; the optional argument deep-links to a project or card
|
|
226
|
+
(`#project/task`). When nothing is running the page tells you to start from the chat
|
|
227
|
+
(`/swarm:project new`, `/swarm:task <project> new`).
|
|
228
|
+
|
|
229
|
+
The board with the Attention strip, in the light theme. One Approval, one Clarification and one
|
|
230
|
+
failed gate wait for you; the `shuffle` card is highlighted while it merges.
|
|
231
|
+
|
|
232
|
+

|
|
233
|
+
|
|
234
|
+
The same view in the dark theme, which follows the system setting unless you override it.
|
|
235
|
+
|
|
236
|
+

|
|
237
|
+
|
|
238
|
+
The Work Queue lists every role with a live, idle or none marker (a text label as well as a colour),
|
|
239
|
+
an activity meter and its Alisio session id; the Activity log records handoffs, merges, gates and
|
|
240
|
+
bounces.
|
|
241
|
+
|
|
242
|
+

|
|
243
|
+
|
|
244
|
+
Select a role to read the tail of its Alisio session: the recent prompts and replies.
|
|
245
|
+
|
|
246
|
+

|
|
247
|
+
|
|
248
|
+
Documents shows the files held for approval, a side-by-side diff from the role base to the held
|
|
249
|
+
commit, and your comments. Approve stays disabled while comments exist.
|
|
250
|
+
|
|
251
|
+

|
|
252
|
+
|
|
253
|
+
Reject lets you retry with your comments, delete the task or accept the work unchanged.
|
|
254
|
+
|
|
255
|
+

|
|
256
|
+
|
|
257
|
+
When nothing is running, the page tells you to start from the Alisio chat.
|
|
258
|
+
|
|
259
|
+

|
|
260
|
+
|
|
261
|
+
It also works at phone width.
|
|
262
|
+
|
|
263
|
+

|
|
264
|
+
|
|
265
|
+
All screenshots use synthetic demo data served by `demo/dashboard-demo.mjs`.
|
|
266
|
+
|
|
267
|
+
| Part | What it shows or does |
|
|
268
|
+
| --- | --- |
|
|
269
|
+
| Top bar | Live chip, a "needs your decision" count (also in the tab title and favicon badge), token budget, pause refresh, theme and chime. |
|
|
270
|
+
| Filters | Project, role and status; pause refresh while you read a long diff or transcript. |
|
|
271
|
+
| Attention strip | Approval, Clarification, Blocked and Gate failed items with Documents, Approve, Reject, Answer, Retry and Delete, plus a button that copies the equivalent chat command. |
|
|
272
|
+
| Board | One band per running project, one column per pack role plus DONE; cards show audit count, a status snippet, a merging highlight and a copy-command button. |
|
|
273
|
+
| Work Queue | Task, role, age, a live/idle/none marker with a text label, a 0 to 6 activity meter, the Alisio session id with a copy button, and the recent prompts and replies of a role. |
|
|
274
|
+
| Activity | Recent handoffs, merges, gate results, bounces and approval waits. |
|
|
275
|
+
| Documents | Task files, a side-by-side or unified diff from the role base to the held commit, and per-document comments (Approve stays disabled while comments exist). |
|
|
276
|
+
|
|
277
|
+
It follows the system light or dark setting (with an explicit override), uses design tokens aligned
|
|
278
|
+
with the Alisio web app, works at phone width and never relies on colour alone. The only changes it
|
|
279
|
+
can make are the gate decisions above, and they call the same services as the commands. It cannot
|
|
280
|
+
create, open, close or tear down projects or tasks, and has no chat: that is an owner decision, so
|
|
281
|
+
the page never duplicates a command.
|
|
282
|
+
|
|
283
|
+

|
|
284
|
+
|
|
285
|
+
The page polls `/api/state` every two seconds. Without a host that can show it, the same data is
|
|
286
|
+
available as `/swarm:status` (tables and a mermaid pipeline), a `ui.panel` tree (projects, roles,
|
|
287
|
+
tasks) and the read-only `swarm-board` data view; each is registered only when the host offers it.
|
|
288
|
+
To inspect the UI without a host, from a repository checkout build the package and run `node demo/dashboard-demo.mjs`: it serves
|
|
289
|
+
the page with synthetic data.
|
|
290
|
+
|
|
291
|
+
## Security
|
|
292
|
+
|
|
293
|
+
Git and gate commands run with argument arrays and a scrubbed environment, never through a shell.
|
|
294
|
+
Identifiers and paths are validated, project paths cannot escape their root through symlinks, and
|
|
295
|
+
persisted files are written atomically with private permissions and a schema version.
|
|
296
|
+
|
|
297
|
+
The dashboard binds to loopback only. Every request needs a random 256-bit token (a cookie for
|
|
298
|
+
reading, a header for changes), a loopback `Host` and, when present, a local `Origin`; there is no
|
|
299
|
+
CORS, the content security policy is `default-src 'self'`, bodies are capped at 256 KiB, every
|
|
300
|
+
identifier is validated and all agent and task text is rendered as text. The link printed by the
|
|
301
|
+
command carries the token: do not share it. Documents are read from the git object store, so no path
|
|
302
|
+
can leave the repository. The plugin never pushes or opens pull requests.
|
|
303
|
+
|
|
304
|
+
## Limits
|
|
305
|
+
|
|
306
|
+
- Not verified against a live host: background pump execution, concurrent child runs, headless
|
|
307
|
+
`permission: ask`, and a child workspace that is a worktree (see "Running it for real").
|
|
308
|
+
- The SDK has no transcript API: the role activity shown in the dashboard is what the plugin recorded
|
|
309
|
+
(bounded prompts and replies), not the host transcript.
|
|
310
|
+
- Child agents cannot call plugin tools; they answer with JSON envelopes only.
|
|
311
|
+
- v1 ships the `node-ts` toolchain only; the `structure` gate is skipped with a stated reason.
|
|
312
|
+
- No tmux or external CLI agents; no pushes or pull requests; Windows is not a target beyond not crashing.
|
|
313
|
+
- Thresholds are our defaults, not SwarmForge's, which publishes none.
|
|
314
|
+
|
|
315
|
+
## Attribution
|
|
316
|
+
|
|
317
|
+
Inspired by SwarmForge by Robert C. Martin (`unclebob/swarm-forge`). This is a clean-room
|
|
318
|
+
implementation of the ideas; no upstream text or code is copied, and the upstream licence has not
|
|
319
|
+
been confirmed.
|
|
320
|
+
|
|
321
|
+
## License
|
|
322
|
+
|
|
323
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="flowchart" style="max-width: 1067.4px; background-color: #ffffff;" viewBox="-24 -24 1067.3984 1078" role="graphics-document document" aria-roledescription="flowchart-v2"><rect x="-24" y="-24" width="1067.3984" height="1078" fill="#ffffff"/><style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#333333;stroke:#333333;}#my-svg .marker.cross{stroke:#333333;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span{color:#333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#333;color:#333;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#my-svg .arrowheadPath{fill:#333333;}#my-svg .edgePaths .path{stroke:#333333;stroke-width:1px;}#my-svg .flowchart-link{stroke:#333333;fill:none;}#my-svg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#my-svg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#my-svg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#my-svg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#my-svg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span{color:#333;}#my-svg .node .collapsed-indicator{fill:#aaaa33;stroke:none;opacity:0.6;}#my-svg .node .collapsed-separator{stroke:#aaaa33;stroke-width:0.75px;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#my-svg .icon-shape .label rect,#my-svg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg .node .neo-node{stroke:#9370DB;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].swimlane.cluster rect{filter:none;}#my-svg [data-look="neo"].node path{stroke:#9370DB;stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#9370DB;filter:none;}#my-svg [data-look="neo"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><marker id="my-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-pointEnd-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="11.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-pointStart-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="1" refY="7" markerUnits="userSpaceOnUse" markerWidth="11.5" markerHeight="14" orient="auto"><polygon points="0,7 11.5,14 11.5,0" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleEnd-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refY="5" refX="12.25" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleStart-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-2" refY="5" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossEnd-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="17.7" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5;"/></marker><marker id="my-svg_flowchart-v2-crossStart-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="-3.5" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5; stroke-dasharray: 1, 0;"/></marker><g class="root"><g class="clusters"/><g class="edgePaths"><path d="M447.5,86L447.5,90.167C447.5,94.333,447.5,102.667,447.5,110.333C447.5,118,447.5,125,447.5,128.5L447.5,132" id="my-svg-L_H_P_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_H_P_0" data-points="W3sieCI6NDQ3LjUsInkiOjg2fSx7IngiOjQ0Ny41LCJ5IjoxMTF9LHsieCI6NDQ3LjUsInkiOjEzNn1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M447.5,214L447.5,218.167C447.5,222.333,447.5,230.667,447.5,238.333C447.5,246,447.5,253,447.5,256.5L447.5,260" id="my-svg-L_P_A_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_P_A_0" data-points="W3sieCI6NDQ3LjUsInkiOjIxNH0seyJ4Ijo0NDcuNSwieSI6MjM5fSx7IngiOjQ0Ny41LCJ5IjoyNjR9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M357.5,327.563L333.417,334.136C309.333,340.709,261.167,353.854,237.083,363.927C213,374,213,381,213,384.5L213,388" id="my-svg-L_A_D_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_A_D_0" data-points="W3sieCI6MzU3LjUsInkiOjMyNy41NjI4OTk3ODY3ODA0fSx7IngiOjIxMywieSI6MzY3fSx7IngiOjIxMywieSI6MzkyfV0=" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M213,494L213,498.167C213,502.333,213,510.667,213,518.333C213,526,213,533,213,536.5L213,540" id="my-svg-L_D_C_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_D_C_0" data-points="W3sieCI6MjEzLCJ5Ijo0OTR9LHsieCI6MjEzLCJ5Ijo1MTl9LHsieCI6MjEzLCJ5Ijo1NDR9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M167.641,696.641L156.035,710.368C144.428,724.094,121.214,751.547,109.607,770.774C98,790,98,801,98,806.5L98,812" id="my-svg-L_C_X_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_C_X_0" data-points="W3sieCI6MTY3LjY0MTQzNDI2Mjk0ODIsInkiOjY5Ni42NDE0MzQyNjI5NDgyfSx7IngiOjk4LCJ5Ijo3Nzl9LHsieCI6OTgsInkiOjgxNn1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M258.359,696.641L269.965,710.368C281.572,724.094,304.786,751.547,316.393,772.774C328,794,328,809,328,816.5L328,824" id="my-svg-L_C_Ok_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_C_Ok_0" data-points="W3sieCI6MjU4LjM1ODU2NTczNzA1MTgsInkiOjY5Ni42NDE0MzQyNjI5NDgyfSx7IngiOjMyOCwieSI6Nzc5fSx7IngiOjMyOCwieSI6ODI4fV0=" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M328,882L328,888.167C328,894.333,328,906.667,328,916.333C328,926,328,933,328,936.5L328,940" id="my-svg-L_Ok_Rel_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Ok_Rel_0" data-points="W3sieCI6MzI4LCJ5Ijo4ODJ9LHsieCI6MzI4LCJ5Ijo5MTl9LHsieCI6MzI4LCJ5Ijo5NDR9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M537.5,327.895L561.061,334.413C584.622,340.93,631.745,353.965,655.306,367.983C678.867,382,678.867,397,678.867,404.5L678.867,412" id="my-svg-L_A_Rej_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_A_Rej_0" data-points="W3sieCI6NTM3LjUsInkiOjMyNy44OTU0OTIxNDkyNDg3fSx7IngiOjY3OC44NjcxODc1LCJ5IjozNjd9LHsieCI6Njc4Ljg2NzE4NzUsInkiOjQxNn1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M598.27,470L573.891,478.167C549.513,486.333,500.757,502.667,476.378,518.333C452,534,452,549,452,556.5L452,564" id="my-svg-L_Rej_R1_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Rej_R1_0" data-points="W3sieCI6NTk4LjI2OTYzNDA0NjA1MjYsInkiOjQ3MH0seyJ4Ijo0NTIsInkiOjUxOX0seyJ4Ijo0NTIsInkiOjU2OH1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M679.98,470L680.317,478.167C680.653,486.333,681.327,502.667,681.663,524.333C682,546,682,573,682,586.5L682,600" id="my-svg-L_Rej_R2_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Rej_R2_0" data-points="W3sieCI6Njc5Ljk4MDE2MDM2MTg0MjEsInkiOjQ3MH0seyJ4Ijo2ODIsInkiOjUxOX0seyJ4Ijo2ODIsInkiOjYwNH1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M761.691,470L786.742,478.167C811.794,486.333,861.897,502.667,886.948,522.333C912,542,912,565,912,576.5L912,588" id="my-svg-L_Rej_R3_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Rej_R3_0" data-points="W3sieCI6NzYxLjY5MDY4NjY3NzYzMTYsInkiOjQ3MH0seyJ4Ijo5MTIsInkiOjUxOX0seyJ4Ijo5MTIsInkiOjU5Mn1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M915.133,86L915.133,90.167C915.133,94.333,915.133,102.667,915.133,110.333C915.133,118,915.133,125,915.133,128.5L915.133,132" id="my-svg-L_Q_QA_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Q_QA_0" data-points="W3sieCI6OTE1LjEzMjgxMjUsInkiOjg2fSx7IngiOjkxNS4xMzI4MTI1LCJ5IjoxMTF9LHsieCI6OTE1LjEzMjgxMjUsInkiOjEzNn1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M915.133,214L915.133,218.167C915.133,222.333,915.133,230.667,915.133,238.333C915.133,246,915.133,253,915.133,256.5L915.133,260" id="my-svg-L_QA_Ans_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_QA_Ans_0" data-points="W3sieCI6OTE1LjEzMjgxMjUsInkiOjIxNH0seyJ4Ijo5MTUuMTMyODEyNSwieSI6MjM5fSx7IngiOjkxNS4xMzI4MTI1LCJ5IjoyNjR9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M915.133,342L915.133,346.167C915.133,350.333,915.133,358.667,915.133,368.333C915.133,378,915.133,389,915.133,394.5L915.133,400" id="my-svg-L_Ans_Res_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Ans_Res_0" data-points="W3sieCI6OTE1LjEzMjgxMjUsInkiOjM0Mn0seyJ4Ijo5MTUuMTMyODEyNSwieSI6MzY3fSx7IngiOjkxNS4xMzI4MTI1LCJ5Ijo0MDR9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/></g><g class="edgeLabels"><g class="edgeLabel"><g class="label" data-id="L_H_P_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_P_A_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_A_D_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_D_C_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(98, 779)"><g class="label" data-id="L_C_X_0" transform="translate(-12.453125, -12)"><foreignObject width="24.90625" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"><p>yes</p></span></div></foreignObject></g></g><g class="edgeLabel" transform="translate(328, 779)"><g class="label" data-id="L_C_Ok_0" transform="translate(-8.8984375, -12)"><foreignObject width="17.796875" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"><p>no</p></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Ok_Rel_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_A_Rej_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Rej_R1_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Rej_R2_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Rej_R3_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Q_QA_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_QA_Ans_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Ans_Res_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node default" id="my-svg-flowchart-H-0" data-look="classic" transform="translate(447.5, 47)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Gate role hands off</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-P-1" data-look="classic" transform="translate(447.5, 175)"><rect class="basic label-container" style="" x="-93.609375" y="-39" width="187.21875" height="78"/><g class="label" style="" transform="translate(-63.609375, -24)"><rect/><foreignObject width="127.21875" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Handoff held in pending_approval</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-A-3" data-look="classic" transform="translate(447.5, 303)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Attention: Approval</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-D-5" data-look="classic" transform="translate(213, 443)"><rect class="basic label-container" style="" x="-90" y="-51" width="180" height="102"/><g class="label" style="" transform="translate(-60, -36)"><rect/><foreignObject width="120" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Documents view: files, diff, comments</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-C-7" data-look="classic" transform="translate(213, 643)"><polygon points="99,0 198,-99 99,-198 0,-99" class="label-container" transform="translate(-98.5, 99)"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Comments exist?</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-X-9" data-look="classic" transform="translate(98, 855)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Approve disabled</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Ok-11" data-look="classic" transform="translate(328, 855)"><rect class="basic label-container" style="" x="-90" y="-27" width="180" height="54"/><g class="label" style="" transform="translate(-60, -12)"><rect/><foreignObject width="120" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: nowrap; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Approve</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Rel-13" data-look="classic" transform="translate(328, 983)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Release to the next role</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Rej-15" data-look="classic" transform="translate(678.8671875, 443)"><rect class="basic label-container" style="" x="-90" y="-27" width="180" height="54"/><g class="label" style="" transform="translate(-60, -12)"><rect/><foreignObject width="120" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: nowrap; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Reject</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-R1-17" data-look="classic" transform="translate(452, 643)"><rect class="basic label-container" style="" x="-90" y="-75" width="180" height="150"/><g class="label" style="" transform="translate(-60, -60)"><rect/><foreignObject width="120" height="120"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Retry: keep rejected commit,<br />restore base, re-run with comments</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-R2-19" data-look="classic" transform="translate(682, 643)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Delete: archive and remove</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-R3-21" data-look="classic" transform="translate(912, 643)"><rect class="basic label-container" style="" x="-90" y="-51" width="180" height="102"/><g class="label" style="" transform="translate(-60, -36)"><rect/><foreignObject width="120" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Accept unchanged: release</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Q-22" data-look="classic" transform="translate(915.1328125, 47)"><rect class="basic label-container" style="" x="-96.265625" y="-39" width="192.53125" height="78"/><g class="label" style="" transform="translate(-66.265625, -24)"><rect/><foreignObject width="132.53125" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Role returns needs_clarification</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-QA-23" data-look="classic" transform="translate(915.1328125, 175)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Attention: Clarification</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Ans-25" data-look="classic" transform="translate(915.1328125, 303)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Operator answers</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Res-27" data-look="classic" transform="translate(915.1328125, 443)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Same session resumes</p></span></div></foreignObject></g></g></g></g></g><defs><filter id="my-svg-drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><defs><filter id="my-svg-drop-shadow-small" height="150%" width="150%"><feDropShadow dx="2" dy="2" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="flowchart" style="max-width: 1569px; background-color: #ffffff;" viewBox="-24 -24 1569 900" role="graphics-document document" aria-roledescription="flowchart-v2"><rect x="-24" y="-24" width="1569" height="900" fill="#ffffff"/><style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#333333;stroke:#333333;}#my-svg .marker.cross{stroke:#333333;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span{color:#333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#333;color:#333;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#my-svg .arrowheadPath{fill:#333333;}#my-svg .edgePaths .path{stroke:#333333;stroke-width:1px;}#my-svg .flowchart-link{stroke:#333333;fill:none;}#my-svg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#my-svg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#my-svg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#my-svg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#my-svg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span{color:#333;}#my-svg .node .collapsed-indicator{fill:#aaaa33;stroke:none;opacity:0.6;}#my-svg .node .collapsed-separator{stroke:#aaaa33;stroke-width:0.75px;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#my-svg .icon-shape .label rect,#my-svg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg .node .neo-node{stroke:#9370DB;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].swimlane.cluster rect{filter:none;}#my-svg [data-look="neo"].node path{stroke:#9370DB;stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#9370DB;filter:none;}#my-svg [data-look="neo"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g><marker id="my-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-pointEnd-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="11.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-pointStart-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="1" refY="7" markerUnits="userSpaceOnUse" markerWidth="11.5" markerHeight="14" orient="auto"><polygon points="0,7 11.5,14 11.5,0" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleEnd-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refY="5" refX="12.25" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-circleStart-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-2" refY="5" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"/></marker><marker id="my-svg_flowchart-v2-crossEnd-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="17.7" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5;"/></marker><marker id="my-svg_flowchart-v2-crossStart-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="-3.5" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5; stroke-dasharray: 1, 0;"/></marker><g class="root"><g class="clusters"><g class="cluster" id="my-svg-Adapters" data-look="classic"><rect style="" x="1283" y="8" width="230" height="520"/><g class="cluster-label" transform="translate(1365.9765625, 8)"><foreignObject width="64.046875" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel"><p>Adapters</p></span></div></foreignObject></g></g><g class="cluster" id="my-svg-Ports" data-look="classic"><rect style="" x="1003" y="20" width="230" height="496"/><g class="cluster-label" transform="translate(1099.328125, 20)"><foreignObject width="37.34375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel"><p>Ports</p></span></div></foreignObject></g></g><g class="cluster" id="my-svg-Core" data-look="classic"><rect style="" x="518" y="536" width="715" height="224"/><g class="cluster-label" transform="translate(728.8984375, 536)"><foreignObject width="293.203125" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel"><p>Application and domain (pure TypeScript)</p></span></div></foreignObject></g></g><g class="cluster" id="my-svg-Front" data-look="classic"><rect style="" x="8" y="336" width="230" height="508"/><g class="cluster-label" transform="translate(26.078125, 336)"><foreignObject width="193.84375" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table-cell; white-space: nowrap; line-height: 1.5;"><span class="nodeLabel"><p>Front ends (same services)</p></span></div></foreignObject></g></g></g><g class="edgePaths"><path d="M213,410L217.167,410C221.333,410,229.667,410,238,410C246.333,410,254.667,410,270.48,430.255C286.294,450.511,309.587,491.022,321.234,511.277L332.881,531.532" id="my-svg-L_Cmd_Services_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Cmd_Services_0" data-points="W3sieCI6MjEzLCJ5Ijo0MTB9LHsieCI6MjM4LCJ5Ijo0MTB9LHsieCI6MjYzLCJ5Ijo0MTB9LHsieCI6MzM0Ljg3NSwieSI6NTM1fV0=" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M213,526L217.167,526C221.333,526,229.667,526,238,526C246.333,526,254.667,526,262.462,528.65C270.257,531.301,277.513,536.601,281.142,539.251L284.77,541.902" id="my-svg-L_Tools_Services_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Tools_Services_0" data-points="W3sieCI6MjEzLCJ5Ijo1MjZ9LHsieCI6MjM4LCJ5Ijo1MjZ9LHsieCI6MjYzLCJ5Ijo1MjZ9LHsieCI6Mjg4LCJ5Ijo1NDQuMjYwODY5NTY1MjE3NH1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M213,642L217.167,642C221.333,642,229.667,642,238,642C246.333,642,254.667,642,262.358,641.019C270.049,640.039,277.098,638.077,280.622,637.096L284.146,636.116" id="my-svg-L_Dash_Services_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Dash_Services_0" data-points="W3sieCI6MjEzLCJ5Ijo2NDJ9LHsieCI6MjM4LCJ5Ijo2NDJ9LHsieCI6MjYzLCJ5Ijo2NDJ9LHsieCI6Mjg4LCJ5Ijo2MzUuMDQzNDc4MjYwODY5Nn1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M213,770L217.167,770C221.333,770,229.667,770,238,770C246.333,770,254.667,770,268.627,756.375C282.586,742.749,302.173,715.499,311.966,701.873L321.759,688.248" id="my-svg-L_Panel_Services_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Panel_Services_0" data-points="W3sieCI6MjEzLCJ5Ijo3NzB9LHsieCI6MjM4LCJ5Ijo3NzB9LHsieCI6MjYzLCJ5Ijo3NzB9LHsieCI6MzI0LjA5Mzc1LCJ5Ijo2ODV9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M468,610L472.167,610C476.333,610,484.667,610,493,610C501.333,610,509.667,610,517.333,610C525,610,532,610,535.5,610L539,610" id="my-svg-L_Services_Forge_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Services_Forge_0" data-points="W3sieCI6NDY4LCJ5Ijo2MTB9LHsieCI6NDkzLCJ5Ijo2MTB9LHsieCI6NTE4LCJ5Ijo2MTB9LHsieCI6NTQzLCJ5Ijo2MTB9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M723,610L727.167,610C731.333,610,739.667,610,747.333,610C755,610,762,610,765.5,610L769,610" id="my-svg-L_Forge_Pump_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Forge_Pump_0" data-points="W3sieCI6NzIzLCJ5Ijo2MTB9LHsieCI6NzQ4LCJ5Ijo2MTB9LHsieCI6NzczLCJ5Ijo2MTB9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M953,641.304L957.167,642.754C961.333,644.203,969.667,647.101,978,648.551C986.333,650,994.667,650,1002.333,650C1010,650,1017,650,1020.5,650L1024,650" id="my-svg-L_Pump_Domain_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Pump_Domain_0" data-points="W3sieCI6OTUzLCJ5Ijo2NDEuMzA0MzQ3ODI2MDg3fSx7IngiOjk3OCwieSI6NjUwfSx7IngiOjEwMDMsInkiOjY1MH0seyJ4IjoxMDI4LCJ5Ijo2NTB9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M953,573.217L957.167,571.514C961.333,569.812,969.667,566.406,978,564.703C986.333,563,994.667,563,1016.769,487.982C1038.872,412.963,1074.743,262.927,1092.679,187.909L1110.615,112.89" id="my-svg-L_Pump_PRun_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Pump_PRun_0" data-points="W3sieCI6OTUzLCJ5Ijo1NzMuMjE3MzkxMzA0MzQ3OX0seyJ4Ijo5NzgsInkiOjU2M30seyJ4IjoxMDAzLCJ5Ijo1NjN9LHsieCI6MTExMS41NDQ2OTg1NDQ2OTg2LCJ5IjoxMDl9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M1208,82L1212.167,82C1216.333,82,1224.667,82,1233,82C1241.333,82,1249.667,82,1258,82C1266.333,82,1274.667,82,1282.333,82C1290,82,1297,82,1300.5,82L1304,82" id="my-svg-L_PRun_ARun_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_PRun_ARun_0" data-points="W3sieCI6MTIwOCwieSI6ODJ9LHsieCI6MTIzMywieSI6ODJ9LHsieCI6MTI1OCwieSI6ODJ9LHsieCI6MTI4MywieSI6ODJ9LHsieCI6MTMwOCwieSI6ODJ9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M953,588.87L957.167,587.891C961.333,586.913,969.667,584.957,978,583.978C986.333,583,994.667,583,1016.465,523.972C1038.263,464.944,1073.527,346.888,1091.159,287.861L1108.79,228.833" id="my-svg-L_Pump_PIso_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Pump_PIso_0" data-points="W3sieCI6OTUzLCJ5Ijo1ODguODY5NTY1MjE3MzkxM30seyJ4Ijo5NzgsInkiOjU4M30seyJ4IjoxMDAzLCJ5Ijo1ODN9LHsieCI6MTEwOS45MzUwNjQ5MzUwNjUsInkiOjIyNX1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M1208,198L1212.167,198C1216.333,198,1224.667,198,1233,198C1241.333,198,1249.667,198,1258,198C1266.333,198,1274.667,198,1282.333,198C1290,198,1297,198,1300.5,198L1304,198" id="my-svg-L_PIso_AGit_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_PIso_AGit_0" data-points="W3sieCI6MTIwOCwieSI6MTk4fSx7IngiOjEyMzMsInkiOjE5OH0seyJ4IjoxMjU4LCJ5IjoxOTh9LHsieCI6MTI4MywieSI6MTk4fSx7IngiOjEzMDgsInkiOjE5OH1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M953,610L957.167,610C961.333,610,969.667,610,978,610C986.333,610,994.667,610,1014.308,571.785C1033.949,533.569,1064.898,457.138,1080.373,418.923L1095.847,380.708" id="my-svg-L_Pump_PStore_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Pump_PStore_0" data-points="W3sieCI6OTUzLCJ5Ijo2MTB9LHsieCI6OTc4LCJ5Ijo2MTB9LHsieCI6MTAwMywieSI6NjEwfSx7IngiOjEwOTcuMzQ4NTkxNTQ5Mjk1OSwieSI6Mzc3fV0=" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M1208,326L1212.167,326C1216.333,326,1224.667,326,1233,326C1241.333,326,1249.667,326,1258,326C1266.333,326,1274.667,326,1282.333,326C1290,326,1297,326,1300.5,326L1304,326" id="my-svg-L_PStore_AFs_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_PStore_AFs_0" data-points="W3sieCI6MTIwOCwieSI6MzI2fSx7IngiOjEyMzMsInkiOjMyNn0seyJ4IjoxMjU4LCJ5IjozMjZ9LHsieCI6MTI4MywieSI6MzI2fSx7IngiOjEzMDgsInkiOjMyNn1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M953,625.652L957.167,626.377C961.333,627.101,969.667,628.551,978,629.275C986.333,630,994.667,630,1014.695,605.725C1034.723,581.45,1066.447,532.899,1082.308,508.624L1098.17,484.349" id="my-svg-L_Pump_PGate_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_Pump_PGate_0" data-points="W3sieCI6OTUzLCJ5Ijo2MjUuNjUyMTczOTEzMDQzNX0seyJ4Ijo5NzgsInkiOjYzMH0seyJ4IjoxMDAzLCJ5Ijo2MzB9LHsieCI6MTEwMC4zNTc5NTQ1NDU0NTQ1LCJ5Ijo0ODF9XQ==" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/><path d="M1208,454L1212.167,454C1216.333,454,1224.667,454,1233,454C1241.333,454,1249.667,454,1258,454C1266.333,454,1274.667,454,1282.333,454C1290,454,1297,454,1300.5,454L1304,454" id="my-svg-L_PGate_AProc_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" data-edge="true" data-et="edge" data-id="L_PGate_AProc_0" data-points="W3sieCI6MTIwOCwieSI6NDU0fSx7IngiOjEyMzMsInkiOjQ1NH0seyJ4IjoxMjU4LCJ5Ijo0NTR9LHsieCI6MTI4MywieSI6NDU0fSx7IngiOjEzMDgsInkiOjQ1NH1d" data-look="classic" marker-end="url(#my-svg_flowchart-v2-pointEnd)"/></g><g class="edgeLabels"><g class="edgeLabel"><g class="label" data-id="L_Cmd_Services_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Tools_Services_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Dash_Services_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Panel_Services_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Services_Forge_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Forge_Pump_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Pump_Domain_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Pump_PRun_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_PRun_ARun_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Pump_PIso_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_PIso_AGit_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Pump_PStore_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_PStore_AFs_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_Pump_PGate_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g><g class="edgeLabel"><g class="label" data-id="L_PGate_AProc_0" transform="translate(0, 0)"><foreignObject width="0" height="0"><div xmlns="http://www.w3.org/1999/xhtml" class="labelBkg" style="display: table-cell; white-space: nowrap; line-height: 1.5; max-width: 200px; text-align: center;"><span class="edgeLabel"></span></div></foreignObject></g></g></g><g class="nodes"><g class="node default" id="my-svg-flowchart-Cmd-0" data-look="classic" transform="translate(123, 410)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>/swarm:* commands</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Tools-1" data-look="classic" transform="translate(123, 526)"><rect class="basic label-container" style="" x="-90" y="-27" width="180" height="54"/><g class="label" style="" transform="translate(-60, -12)"><rect/><foreignObject width="120" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: nowrap; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>swarm_* tools</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Dash-2" data-look="classic" transform="translate(123, 642)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Dashboard (HTTP + UI)</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Panel-3" data-look="classic" transform="translate(123, 770)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>ui.panel and views</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Services-4" data-look="classic" transform="translate(378, 610)"><rect class="basic label-container" style="" x="-90" y="-75" width="180" height="150"/><g class="label" style="" transform="translate(-60, -60)"><rect/><foreignObject width="120" height="120"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>SwarmServices<br />one implementation of every decision</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Forge-5" data-look="classic" transform="translate(633, 610)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Forge and ProjectRuntime</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Pump-6" data-look="classic" transform="translate(863, 610)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Pump, audit, gates, approval</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-Domain-7" data-look="classic" transform="translate(1118, 650)"><rect class="basic label-container" style="" x="-90" y="-75" width="180" height="150"/><g class="label" style="" transform="translate(-60, -60)"><rect/><foreignObject width="120" height="120"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Packs, envelopes, pipeline,<br />task state, attention</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-PRun-8" data-look="classic" transform="translate(1118, 82)"><rect class="basic label-container" style="" x="-90" y="-27" width="180" height="54"/><g class="label" style="" transform="translate(-60, -12)"><rect/><foreignObject width="120" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: nowrap; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>AgentRunner</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-PIso-9" data-look="classic" transform="translate(1118, 198)"><rect class="basic label-container" style="" x="-90" y="-27" width="180" height="54"/><g class="label" style="" transform="translate(-60, -12)"><rect/><foreignObject width="120" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: nowrap; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Isolation</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-PStore-10" data-look="classic" transform="translate(1118, 326)"><rect class="basic label-container" style="" x="-90" y="-51" width="180" height="102"/><g class="label" style="" transform="translate(-60, -36)"><rect/><foreignObject width="120" height="72"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>HandoffStore, BoardStore,<br />TaskStateStore</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-PGate-11" data-look="classic" transform="translate(1118, 454)"><rect class="basic label-container" style="" x="-90" y="-27" width="180" height="54"/><g class="label" style="" transform="translate(-60, -12)"><rect/><foreignObject width="120" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: nowrap; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>GateRunner</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-ARun-12" data-look="classic" transform="translate(1398, 82)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Alisio child sessions</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-AGit-13" data-look="classic" transform="translate(1398, 198)"><rect class="basic label-container" style="" x="-90" y="-27" width="180" height="54"/><g class="label" style="" transform="translate(-60, -12)"><rect/><foreignObject width="120" height="24"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: nowrap; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>git worktrees</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-AFs-14" data-look="classic" transform="translate(1398, 326)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Atomic JSON files</p></span></div></foreignObject></g></g><g class="node default" id="my-svg-flowchart-AProc-15" data-look="classic" transform="translate(1398, 454)"><rect class="basic label-container" style="" x="-90" y="-39" width="180" height="78"/><g class="label" style="" transform="translate(-60, -24)"><rect/><foreignObject width="120" height="48"><div xmlns="http://www.w3.org/1999/xhtml" style="display: table; white-space: break-spaces; line-height: 1.5; max-width: 120px; text-align: center; width: 120px;"><span class="nodeLabel"><p>Process gates (node-ts)</p></span></div></foreignObject></g></g></g></g></g><defs><filter id="my-svg-drop-shadow" height="130%" width="130%"><feDropShadow dx="4" dy="4" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs><defs><filter id="my-svg-drop-shadow-small" height="150%" width="150%"><feDropShadow dx="2" dy="2" stdDeviation="0" flood-opacity="0.06" flood-color="#000000"/></filter></defs></svg>
|