DyroEngineeringFlow: local-first automation and delivery control for multi-repository teams
Project description
DyroEngineeringFlow
English | 简体中文 | 한국어 | Español | Français | Deutsch | Português (Brasil) | Русский
DyroEngineeringFlow · dyro CLI is a local-first engineering automation and delivery control platform for multi-repository teams. It brings development lines, Git worktrees, agent launchers, task gates, independent review, and merge audit into versioned workspace configuration.
Keep engineering moving from task to delivery.
DyroEngineeringFlow is not coupled to Codex, Claude, or any business domain. Each team supplies a dyro.toml Profile for repositories, layouts, agent adapters, and delivery policy; business rules, model cost, and release practices stay in that Profile.
What it enforces
- A task belongs to exactly one development line—never a mixed feature or hotfix workspace.
- Each task runs in its own
git worktreeon atask/<id>branch. - Gates are executed by the orchestrator; an agent's self-report is not evidence of success.
- Review is bound to the execution receipt and exact per-repository task HEADs; source drift invalidates it.
- A task needs independent review before it becomes
done; merge and push require explicit confirmation by default. - A completed dependency releases downstream work only after its exact task HEADs are integrated into the owning development line.
- Executable configuration is represented as argv arrays. The core never runs TOML-provided shell strings.
Architecture and flow diagrams
The following diagrams render directly on GitHub as Mermaid (no image links). The control plane separates team Profile (repositories, adapters, gates, policy) from Dyro Core (workspace, launch, dispatch, verify, merge). Runtime state lives under .dyro/.
Layered architecture
flowchart TB
subgraph Profile["Project Profile (team-supplied)"]
P1["repositories / layout / bases"]
P2["Agent adapter argv"]
P3["gates / receipt templates / policy"]
end
subgraph Core["Dyro Core · dyro CLI (mechanism)"]
W["workspace<br/>anchors · lines · doctor"]
L["launch<br/>safe argv templates"]
D["dispatch<br/>DAG · claim · state machine"]
V["verify<br/>gates · ledger"]
M["merge<br/>preflight · recovery · push policy"]
end
subgraph Runtime["Workspace runtime .dyro/"]
R1["tasks / lines / changes"]
R2["evidence · review · ledger"]
end
Profile --> Core
Core --> Runtime
Human["Engineer / release owner"] --> Core
Agent["Local agent CLI"] --> L
Runner["Isolated runner (optional)"] -.->|"evidence ZIP"| D
Multi-repo workspace layout
flowchart TB
WS["workspace root<br/>dyro.toml"]
WS --> REPO["repositories/"]
WS --> DYRO[".dyro/"]
WS --> VER["versions/ or layout.lines"]
WS --> WT["worktrees/ or layout.tasks"]
REPO --> API["services/api · Git anchor"]
REPO --> WEB["services/web · Git anchor"]
DYRO --> LINES["lines/<id>.toml"]
DYRO --> TASKS["tasks/<id>/"]
DYRO --> CHG["changes/ · decisions · ledger"]
TASKS --> TT["task.toml · handoff.md"]
TASKS --> EV["evidence-imports/ · review.md"]
WT --> TAPI["task/API-101/services/api"]
WT --> TWEB["task/API-101/services/web"]
VER --> LAPI["release-…/services/api worktree"]
VER --> LWEB["release-…/services/web worktree"]
Task state machine
stateDiagram-v2
[*] --> backlog
backlog --> assigned: claim / next
assigned --> in_progress: run starts
in_progress --> waiting_answer: human answer needed
waiting_answer --> in_progress: task answer
in_progress --> review: gates pass · enter review
in_progress --> failed: failure
failed --> assigned: re-claim
review --> review_pending_signoff: require_external_signoff
review --> done: independent review PASS
review_pending_signoff --> done: task signoff
done --> [*]: task merge into line
Local delivery sequence
sequenceDiagram
actor Eng as Engineer
participant CLI as dyro CLI
participant FS as Workspace Git / .dyro
participant Agent as Agent adapter
Eng->>CLI: setup / doctor / line create
CLI->>FS: register line · create line worktrees
Eng->>CLI: task create · task next
CLI->>FS: write task.toml · allocate worktree
Eng->>CLI: task run / open --agent
CLI->>Agent: argv launch into task worktree
Agent-->>CLI: work finished (not gate evidence)
CLI->>CLI: run Profile gates
CLI->>FS: receipt · heads · attempt
Eng->>CLI: task review
CLI->>FS: receipt-bound review
Eng->>CLI: task merge --yes
CLI->>FS: merge into line · update ledger
External evidence sequence
sequenceDiagram
actor Ctrl as Control-plane operator
participant CLI as dyro control plane
participant Run as Isolated runner
participant Rev as Independent reviewer
Ctrl->>CLI: task claim --by runner-id
CLI-->>Run: claim active · conflict group held
Run->>Run: execute in isolation · declared gates
Run->>CLI: evidence build → ZIP
Ctrl->>CLI: evidence execution --bundle
CLI->>CLI: validate ZIP · heads · gates · signing policy
Rev->>CLI: evidence review / review-build
CLI->>CLI: bind receipt + task heads
opt require_external_signoff
Ctrl->>CLI: task signoff --by approver
end
Ctrl->>CLI: task merge --yes
Task graph
flowchart LR
subgraph Nodes
T1["Task A"]
T2["Task B"]
T3["Task C"]
D1["Decision<br/>blocked_on"]
end
T1 -->|depends_on| T2
T2 -->|depends_on| T3
T3 --> D1
CG["conflict_group: db-migrate<br/>mutex within a wave"]
T1 -.-> CG
T2 -.-> CG
Scheduling wave
flowchart TB
Snap["Immutable schedule snapshot<br/>graph + state + claims"]
Ready["ready set<br/>deps integrated · decisions OK"]
Wave["current wave<br/>--parallel × conflict_group"]
Snap --> Ready --> Wave
Use-case overview
flowchart LR
subgraph Actors
Dev["Developer"]
Lead["Release owner"]
Runner["Isolated runner"]
Reviewer["Independent reviewer"]
end
subgraph UC["Primary use cases"]
U1["Init workspace setup/init"]
U2["Create line / hotfix"]
U3["Create and schedule tasks"]
U4["Local run and gates"]
U5["Import external evidence"]
U6["Independent review and signoff"]
U7["Merge and Change Set verify"]
U8["Audit sync to Witness"]
end
Dev --> U1
Dev --> U3
Dev --> U4
Lead --> U2
Lead --> U7
Lead --> U8
Runner --> U5
Reviewer --> U6
Dev --> U6
Multi-agent layers (optional experiment)
flowchart TB
Host["Host agent<br/>current conversation"]
Disp["local_agent_dispatch<br/>contract · guards · leases"]
B1["Backend CLI A"]
B2["Backend CLI B"]
Board["Adversarial review board<br/>signed sections + final call"]
Dyro["Dyro control plane<br/>claim · gates · merge"]
Host -->|"TaskContract JSON"| Disp
Disp --> B1
Disp --> B2
B1 -->|"summary + evidence"| Host
B2 -->|"summary + evidence"| Host
Host --> Board
Board -.->|"advisory only"| Host
Host -->|"explicit dyro commands"| Dyro
Shipped with dyro (dyro dispatch …). Dispatch output is advisory; delivery still uses Dyro gates/merge. See docs/agent-orchestration-discipline.md.
Multi-agent sequence (optional experiment)
sequenceDiagram
participant H as Host agent
participant S as DispatchSupervisor
participant W as Worker or backend
participant P as Review board file
H->>S: run --wait TaskContract
S->>S: validate files · secret guard · take slot
S->>W: self-contained prompt + allowlisted context
W-->>S: ResultEnvelope
S->>S: mark locator verified
S-->>H: run_id · summary · evidence
H->>P: write own signed section
Note over H,P: Do not edit others sections - source is authority
H->>H: optional code change / PR after final call
Note over H: Delivery still uses dyro task merge
External semantic runtime (optional experiment)
flowchart TB
Sup["Trusted Supervisor"]
Sand["Workflow Sandbox<br/>pinned TS bundle · no vendor token"]
Bro["Agent Broker<br/>argv provider · raw only on tmpfs"]
HostP["Optional host provider<br/>Broker-mounted only"]
Sup -->|start · verify bundle/claim| Sand
Sup -->|start · pin| Bro
Sand -->|loopback IPC| Bro
HostP -.->|RO bind| Bro
Sup -->|after dual cleanup| Pack["local evidence pack / dry-run"]
Pack -.->|forbidden| Merge["merge / push / Core import"]
Not Core. Tree: experiments/external_workflow_runner/. Production status: Stage5 NOT_READY.
Semantic runtime sequence (optional experiment)
sequenceDiagram
participant S as Supervisor
participant B as Broker container
participant W as Sandbox container
S->>B: start internal net + pin
S->>W: start shared netns · no token
W->>B: agent.call JSON-line
B->>B: spawn provider · destroy raw
B-->>W: sanitized result
W-->>S: result-envelope + artifacts
S->>W: cleanup verify
S->>B: stop · containers absent
S->>S: pack only if dual cleanup OK
Quick start
For daily CLI use, install dyro from PyPI in an isolated pipx environment (Python 3.11 or later):
python3 -m pip install --user --upgrade pipx
python3 -m pipx ensurepath
# Open a new terminal after ensurepath, then:
pipx install dyro
dyro --version
To upgrade later, run pipx upgrade dyro. If your team manages Python packages through pip instead, use:
python3 -m pip install --user --upgrade dyro
Place your repositories in a workspace, then use the newcomer path to discover them, create the safe state directories, and create the first development line in one command:
mkdir my-workspace && cd my-workspace
# Clone or move your Git repositories under this directory first.
dyro setup . --name my-workspace --line dev --yes
setup scans local Git repositories, records their workspace-relative paths, derives their development-line mounts, and reads origin when available—no TOML editing. --yes is required only because the first line creates Git worktrees. Use --no-line when you want the Profile first and will create a line later. If the workspace has no repositories yet, use the guided fallback:
dyro init . --wizard --name my-workspace
Add a repository later without opening dyro.toml:
dyro repo add repositories/services/payments
dyro repo list
Manage common delivery policy and Agent adapters without opening dyro.toml:
dyro config set policy.execution_mode external
dyro config get policy.execution_mode
dyro agent add ci-runner --preset noop
dyro agent test ci-runner
If a Profile contains remotes, missing repository anchors can be created safely:
dyro --dry-run bootstrap
dyro bootstrap --yes
dyro doctor
For a new teammate, the normal entry point is one command. It checks the workspace, then selects a development line and local agent:
dyro start
Delivery workflow
Use explicit commands when scripting or leading a release:
dyro doctor
dyro line create release-2026-10 --base origin/main --yes
# Override the verified base only for repositories that need one.
dyro line create release-2026-10 --base origin/main --repo-base web=v2026.10.0 --yes
dyro open release-2026-10 --agent codex
dyro task create API-101 --title "Implement API contract" --line release-2026-10 --repository api
dyro task graph check --line release-2026-10
dyro task graph --line release-2026-10 --format mermaid
dyro task explain API-101
dyro task next
dyro task next --run --yes
dyro task attempts API-101
dyro task binding API-101
dyro task review API-101
dyro task merge API-101 --yes
dyro changeset create release-2026-10-ready --line release-2026-10
dyro changeset verify release-2026-10-ready
A production hotfix must state its verified production base; it never inherits a default branch implicitly:
dyro hotfix create incident-123 --base v2026.09.7 --repos api,web --yes
For a Profile whose execution and approval are run by a separate trusted system, set policy.execution_mode = "external" and policy.require_external_signoff = true. Local Dyro will then allow only planning; a review bound to the receipt and exact task HEADs must be signed explicitly before a task becomes done:
dyro task claim API-101 --by isolated-runner-1 --key-id runner-2026
# Long-running work must renew its bounded claim before expiry.
dyro task claim-renew API-101 --by isolated-runner-1 --lease-seconds 3600
# In the isolated runner: run declared gates and package receipt, logs, and exact HEADs.
dyro task evidence build API-101 --workspace /runner/workspace --receipt /runner/out/receipt.md --output /runner/out/API-101.zip
# In the control plane: validate and import the one portable package.
dyro task evidence execution API-101 --bundle /runner/out/API-101.zip
dyro task evidence review API-101 --file /review/out/review.md
dyro task signoff API-101 --by release-manager
# An abandoned assignment can be released explicitly.
dyro task claim-release API-101 --by isolated-runner-1
New evidence bundles must include provenance.json. Importing a pre-provenance legacy bundle is a deliberate migration action and requires dyro task evidence execution API-101 --bundle ... --allow-legacy. If an external runner returns QUESTION, record the answer with dyro task answer API-101 --text "..."; the existing claim is preserved and the task returns to assigned for the next evidence submission.
Inspect and safely retain immutable evidence generations:
dyro task evidence generations API-101
dyro --dry-run task evidence generations API-101 --prune --older-than-days 30 --keep 10
dyro task evidence generations API-101 --prune --older-than-days 30 --keep 10 --yes
For cryptographic runner and approver identity, generate keys outside the workspace, then install only public keys into purpose-separated trust stores:
dyro config set policy.execution_mode external
dyro config set policy.require_signed_execution true
dyro config set policy.require_signed_review true
dyro config set policy.require_external_signoff true
dyro config set policy.require_signed_signoff true
dyro key generate runner-2026 --private-key /secure/runner.pem --public-key /secure/runner.pub.pem
dyro key trust runner-2026 --purpose execution --public-key /secure/runner.pub.pem \
--not-after 2027-01-01T00:00:00+00:00
dyro task claim API-101 --by isolated-runner-1 --key-id runner-2026
dyro task evidence build API-101 --workspace /runner/workspace --receipt /runner/out/receipt.md \
--output /runner/out/API-101.zip --claim /runner/in/claim.json \
--signing-key /secure/runner.pem --key-id runner-2026
dyro key generate reviewer-2026 --private-key /secure/reviewer.pem --public-key /secure/reviewer.pub.pem
dyro key trust reviewer-2026 --purpose review --public-key /secure/reviewer.pub.pem
dyro task evidence review-build API-101 --file /review/out/review.md --reviewer independent-reviewer \
--output /review/out/review.json --signing-key /secure/reviewer.pem --key-id reviewer-2026
dyro task evidence review API-101 --file /review/out/review.json
dyro key generate approver-2026 --private-key /secure/approver.pem --public-key /secure/approver.pub.pem
dyro key trust approver-2026 --purpose signoff --public-key /secure/approver.pub.pem
dyro task signoff API-101 --by release-manager --signing-key /secure/approver.pem --key-id approver-2026
dyro key list --purpose execution --show-status
dyro key revoke runner-2026 --purpose execution --reason "runner retired"
dyro key audit
Sync the local trust audit chain to an independent Witness:
dyro key generate audit-client-2026 \
--private-key /secure/audit-client.pem \
--public-key /secure/audit-client.pub.pem
# Install audit-client.pub.pem on the Witness over an out-of-band secure channel.
dyro key trust witness-2026 \
--purpose audit-receipt \
--public-key witness-2026.pub.pem
dyro key trust witness-recovery \
--purpose audit-recovery \
--public-key witness-recovery.pub.pem
DYRO_AUDIT_TOKEN=... dyro key audit-sync \
--witness primary \
--endpoint https://audit.example.com/v1/dyro/batches \
--signing-key /secure/audit-client.pem \
--key-id audit-client-2026 \
--witness-key-id witness-2026 \
--witness-recovery-key-id witness-recovery
Even with no new events the command still sends a signed checkpoint; if a response is lost, the already-persisted pending batch is replayed as-is. The Witness must independently recompute the event chain, reject sequence or chain-head forks, issue a verifiable receipt, and write batches and receipts to immutable storage with retention lock. Protocol, key rotation, and deployment boundaries are documented in Audit Witness protocol.
The project ships a deployable standard-library Witness service: dyro witness serve. By default it requires a bearer token and TLS, and only advances the checkpoint after creating records/<batch-sha256>.json; crash recovery restores unfinished records. In production, separate mutable checkpoint storage from immutable records archives: use WORM/Object Lock only for the records archive, and durable mutable storage for the checkpoint. Key rotation, containers, and S3 Object Lock operations are covered in the Witness deployment guide.
Signature enforcement is controlled explicitly by policy.require_signed_execution, policy.require_signed_review, and policy.require_signed_signoff; deleting every trusted key never disables an enabled policy. Signed execution claims bind claim_id, generation, runner, and execution key ID. Signature messages and execution plan hashes use RFC 8785 JSON Canonicalization Scheme bytes, so non-Python runners can reproduce the exact signed payload. Independent reviewers produce a signed JSON envelope with dyro task evidence review-build. Rotation is non-disruptive: trust the new key ID before switching signers, retain the old key during the overlap window, then revoke it through the workspace's controlled key-management process.
A minimal TypeScript reference signer and Python/Node interoperability vector live in examples/typescript-runner/. It demonstrates the exact canonical bytes, signature domain, Ed25519 call, and signature envelope expected by the control plane.
Every write-capable operation has a planning mode:
dyro --dry-run line create release-2026-10 --base origin/main
dyro --dry-run task run API-101
Command map
| Command | Purpose |
|---|---|
setup / init --discover / init --wizard / repo add/list / bootstrap / start |
Onboard a teammate without TOML edits, manage anchors, and choose a line and agent. |
doctor / status |
Validate and display control-plane state. |
line create/list |
Create, register, and inspect feature development lines. |
hotfix create |
Create a hotfix line from an explicit production base. |
changeset create/list/verify |
Pin and verify the exact clean Git heads that make up a multi-repository delivery. |
config get/set / agent list/add/test / open |
Safely manage common policy and adapters, validate an executable, or open an agent in the correct development line. |
task create/list/board/status/next/graph/explain/attempts/binding |
Manage task manifests and state, compile or validate the task graph, explain scheduling decisions, inspect provenance, and output the exact review binding. |
task run/answer/gates/review/signoff |
Run tasks, resolve questions, execute gates, request independent review, and record external sign-off when a Profile requires it. |
task claim / task evidence build/execution/review |
One-time claim, portable execution-evidence build/import, and receipt-bound review import for an external isolated runner. |
task merge |
Merge a reviewed task branch into its owning development line. |
task loop/daemon/stats/decisions |
Run controlled batches, scheduling, ledger reporting, and decision gates. |
dispatch |
Optional local multi-agent dispatch (L0–L4); advisory only — not a substitute for gates/merge. |
runtime |
Optional external semantic runtime status (Stage5 production NOT_READY). |
See the architecture and Profile contract, the existing control-plane migration guide, and the PyPI publishing runbook (maintainers) for implementation detail.
Languages and documentation
This README is maintained in English, Simplified Chinese, Korean, Spanish, French, German, Brazilian Portuguese, and Russian. Commands, configuration keys, directory names, and safety rules are deliberately identical across translations. The current CLI messages and extended technical guides are primarily Chinese; multilingual README support does not claim that the runtime has language switching yet.
Current boundaries
DyroEngineeringFlow provides a complete local workflow loop and policy controls for keeping stricter teams in planning-only local mode. It does not create remote repositories, ship SaaS credentials, or provision an external runner; it does provide a portable evidence-package contract for one. Optional modules under experiments/ (external workflow runner Stage0–5, local agent dispatch L0–L4) ship in the dyro wheel and are usable after install (dyro dispatch …, import experiments…). They remain optional relative to Core: they do not replace gates, review, signoff, or merge, and the semantic-runtime path is still Stage5 NOT_READY for production—see ADRs under docs/adr/. Local multi-repository merges are preflighted and recovered as one operation; remote Git servers cannot provide atomic cross-repository push, so partial push failure is recorded for recovery. Automatic merge requires permission in both the task manifest and local policy. It is available under the MIT License and as dyro on PyPI.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dyro-0.5.0.tar.gz.
File metadata
- Download URL: dyro-0.5.0.tar.gz
- Upload date:
- Size: 217.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec9e6a736c7958c416be9e447df1303bafc6e0a22479a4265bbd1e2bbefbfae1
|
|
| MD5 |
e843912846098e8d3cf00567dc188015
|
|
| BLAKE2b-256 |
4307facb4c0306b9aaf6b09d45903ebeedfbcb0fe48cc709ed94a3e56dfda886
|
Provenance
The following attestation bundles were made for dyro-0.5.0.tar.gz:
Publisher:
pypi-publish.yml on DandreYang/DyroEngineeringFlow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dyro-0.5.0.tar.gz -
Subject digest:
ec9e6a736c7958c416be9e447df1303bafc6e0a22479a4265bbd1e2bbefbfae1 - Sigstore transparency entry: 2282278222
- Sigstore integration time:
-
Permalink:
DandreYang/DyroEngineeringFlow@a50ea629358c7ab09fa758f76d5b85da4bd0398f -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/DandreYang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@a50ea629358c7ab09fa758f76d5b85da4bd0398f -
Trigger Event:
release
-
Statement type:
File details
Details for the file dyro-0.5.0-py3-none-any.whl.
File metadata
- Download URL: dyro-0.5.0-py3-none-any.whl
- Upload date:
- Size: 216.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6eb936688e11d3f3242555b196771c9eb17478983b7341fc93b6168abaed146d
|
|
| MD5 |
4319c85d65afdb2a90f46a53081a6985
|
|
| BLAKE2b-256 |
7da7fb01801d97e6bdfaa16feae6395164998b9d6c1d311477542bf46d35c003
|
Provenance
The following attestation bundles were made for dyro-0.5.0-py3-none-any.whl:
Publisher:
pypi-publish.yml on DandreYang/DyroEngineeringFlow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dyro-0.5.0-py3-none-any.whl -
Subject digest:
6eb936688e11d3f3242555b196771c9eb17478983b7341fc93b6168abaed146d - Sigstore transparency entry: 2282278278
- Sigstore integration time:
-
Permalink:
DandreYang/DyroEngineeringFlow@a50ea629358c7ab09fa758f76d5b85da4bd0398f -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/DandreYang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@a50ea629358c7ab09fa758f76d5b85da4bd0398f -
Trigger Event:
release
-
Statement type: