Inspiration

We started from a workflow that looked deceptively simple: choose a task, give it to an AI coding agent, wait for the result, review it, and move on.

As the work became more ambitious, that single loop turned into a workflow graph.

Before an agent can begin, someone has to decide whether the ticket is ready, check its dependencies, select the correct repository, prepare a branch and worktree, establish acceptance criteria, and make sure the agent has the right context. While it is working, someone has to track progress, handle questions, recover from interrupted sessions, and distinguish a real completion from a process that merely stopped. Afterward, someone still has to validate the result, create a pull request, wait for CI, merge it, update Jira (or project management tool of choice), and clean up the workspace.

We noticed that agents were spending a surprising amount of time and context on those repeatable transitions. The same information was repeatedly copied between Jira, prompts, checklists, Git, GitHub, and human conversations. Workers were rediscovering facts that another component already knew. Context windows became polluted with workflow ceremony, and tokens were being spent on deterministic operations that did not require model reasoning.

That led to the central idea behind Dross:

Let AI workers focus on implementation, and move repeatable coordination, state management, validation, recovery, and delivery into a dedicated orchestration layer.

We also realized that orchestration could not be based on optimistic assumptions. A closed process does not necessarily mean a task completed. A provider session is not the same thing as an assignment. A message in a transcript is not durable handoff evidence. A visible worker card is not ownership authority. Once several asynchronous systems are involved, every transition needs explicit identity, durable state, and evidence.

Dross grew out of that need: a local control plane for supervised AI software delivery.

What it does

Dross turns configured Jira (currently, but we plant to support any project management tool via a moduler customizable workflow graph with any number of "connectors") work into isolated, supervised coding-agent assignments and carries validated results through the mechanical software-delivery workflow.

It begins by reading work from selected Jira projects and lifecycle states. It evaluates ticket eligibility, dependencies, hierarchy, repository compatibility, ownership, and worker scope before admitting anything into the queue.

When a ticket is ready, Dross:

  1. Gives one stable worker exclusive ownership of the assignment.
  2. Creates an isolated Git branch and worktree.
  3. Prepares assignment context and a durable SQLite checklist.
  4. Dispatches the work through a supervised Codex or Claude runtime host.
  5. Tracks the exact worker, Jira ticket, dispatch, assignment generation, host, provider session, and provider-native turn.
  6. Projects progress, checklist state, messages, diagnostics, and recovery actions into an Electron desktop interface.
  7. Validates the worker’s handoff before allowing delivery to continue.
  8. Handles the mechanical path through commit, push, pull request, CI, review, merge, optional release, Jira closeout, and cleanup.

Dross deliberately separates deterministic workflow work from model work. The agent implements the ticket, updates its checklist, runs relevant tests, records blockers, and produces a structured handoff. Dross owns scheduling, workspace preparation, durable state, lifecycle transitions, external-effect validation, shipping, and cleanup.

The application includes:

  • A dependency-aware Jira dashboard
  • Project-specific intake and lifecycle policies
  • Worker readiness and capability checks
  • Per-worker work scopes
  • Isolated assignment workspaces
  • Durable SQLite checklists
  • Ticket-scoped checklist and chat views
  • Live progress and exact-turn controls
  • Component-level pause controls
  • A unified notification center
  • Recovery and rebase workflows
  • Pull-request, CI, merge, and Jira closeout automation
  • Detailed operational diagnostics

One of the most important properties of Dross is that it does not infer success from silence or process state. Input acceptance, meaningful progress, transport loss, interruption, and terminal completion are represented separately. Stale or foreign events are rejected instead of being applied to newer work.

How we built it

Dross is an Electron and Node.js application backed by SQLite.

The Electron controller owns the desktop interface, operator actions, runtime-host supervision, and the single active application instance. Short-lived daemon workers perform bounded orchestration cycles: reading Jira, evaluating eligibility, reserving work, preparing assignments, reconciling runtime state, shipping completed changes, and cleaning up.

SQLite provides durable authority for:

  • Workers
  • Assignments
  • Dispatches
  • Runtime hosts
  • Provider turns
  • Checklists
  • Workspace records
  • Notifications
  • Retry state
  • Recovery claims
  • Shipping checkpoints
  • Component policies

Git worktrees provide assignment isolation. Each ticket receives its own branch, worktree, .agent context, and checklist rather than sharing a worker’s original repository directory.

Codex and Claude are implemented behind a provider-neutral runtime-host interface. Each adapter describes its capabilities as native, emulated by Dross, or unsupported. This lets the interface expose steering, interruption, permissions, compaction, recovery, quota information, and other actions only when the provider and current lifecycle state genuinely support them.

The shipping engine separately validates the exact assignment, dispatch, turn, checklist, workspace, Git state, Jira state, and component policy before performing an external mutation. Retries are idempotent: Dross can adopt an already-created commit, pull request, or merge only when the external object matches the current assignment authority.

We built the project iteratively through Codex, primarily using GPT-5.6 Sol. We supplied product goals, architectural constraints, failure cases, acceptance criteria, and live validation scenarios. GPT-5.6 Sol used Codex to inspect the repository, implement changes, add tests, run validation, analyze failures, and continue refining the system.

The development process often followed this loop:

  1. Define a concrete operational problem or invariant.
  2. Ask Codex to inspect the relevant implementation and evidence.
  3. Implement the smallest coherent change.
  4. Run focused tests and broader package-level validation.
  5. Exercise the behavior against realistic local state.
  6. Record failures and contradictory evidence.
  7. Refine the architecture rather than patching the visible symptom.
  8. Add regressions before moving to the next area.

That process produced not only the application code, but also a large body of automated tests, operational runbooks, architecture references, state-machine documentation, and validation evidence.

Challenges we ran into

The first challenge was scope.

Dross was much more ambitious than a normal Build Week project. It touches Jira, Git, GitHub, Electron, SQLite, provider runtimes, local processes, worktrees, pull requests, CI, release behavior, and hundreds of lifecycle transitions. Every new feature exposed another boundary that needed to be made explicit.

We quickly learned that the project needed more time, more tokens, and more context than we initially expected. We had to prioritize correctness, recoverability, and demonstrable end-to-end behavior over finishing every planned workflow editor, integration, and visual refinement.

The hardest technical challenge was maintaining truthful state across asynchronous systems.

A provider process can close while its turn is still unresolved. A terminal notification can arrive after a newer generation has started. A pull request might already exist from an earlier attempt. A worktree can remain on disk after its assignment state changes. Jira, Git, GitHub, SQLite, and the provider can each be individually correct while collectively disagreeing.

We had to answer questions such as:

  • Which exact turn does this event belong to?
  • Is this worker actually free, or does it have unresolved authority?
  • Did the model finish, or did the transport disappear?
  • Is this checklist associated with the current assignment?
  • Is this pull request ours, or does it merely have a similar branch name?
  • Can a failed operation be retried safely?
  • Does a stale UI action still apply to the current assignment?
  • Can we clean this process or worktree without affecting unrelated work?

The answer was rarely “check the latest status.” We needed explicit identities, generation fences, transactions, bounded recovery operations, and idempotent external effects.

Another challenge was provider neutrality. Codex and Claude expose different capabilities and different evidence. Treating them as identical would have produced unsafe fallbacks, while writing two completely separate orchestration systems would have duplicated the hardest logic. We solved this by using a shared runtime contract with explicit provider capability descriptors.

The desktop interface was also challenging. Dross manages a large amount of machine state, but exposing every internal identifier would make the product unusable. We had to create human-readable summaries without allowing presentation labels to become lifecycle authority. We also had to keep credentials, prompts, command output, provider bodies, and sensitive Jira content out of routine diagnostics and notifications.

Finally, the amount of validation required was significant. A workflow may look correct in one interface while still being inconsistent in SQLite, Git, the provider session, or Jira. We developed focused tests, integration tests, temporary repositories, injected transports, test-isolation guards, operational reports, and live validation procedures to examine the system collectively.

Accomplishments that we’re proud of

The largest accomplishment is that the proof of concept works as a coherent end-to-end system rather than as a collection of disconnected scripts.

Dross can:

  • Read and classify Jira work
  • Respect dependencies and project-specific policy
  • Assign work to a stable AI worker
  • Prepare an isolated branch, worktree, and checklist
  • Start and supervise an exact provider turn
  • Display worker progress and ticket-scoped conversation
  • Handle interruption, continuation, and transport-loss recovery
  • Validate a structured implementation handoff
  • Create or adopt a commit and pull request
  • Observe CI and review state
  • Merge the result
  • Update and close the Jira ticket
  • Finalize assignment state
  • Clean up the workspace and return the worker to the pool

We are particularly proud of the authority model. Dross tracks its own worker, assignment, dispatch, host, and turn identities independently from provider sessions and provider-native turns. This prevents stale events, process exits, or unrelated historical activity from silently changing current work.

We are also proud of the recovery system. Instead of telling operators to edit SQLite, kill arbitrary processes, or manually reconstruct state, Dross can inspect the current evidence, classify the problem, generate a bounded plan, and perform only the repair that the available authority supports.

The Workers experience became a real product surface, with dedicated views for worker health, work scope, workflows, assignments, workspace state, and advanced maintenance. The ticket workspace combines the exact assignment checklist with a durable operator/agent conversation.

The component controls and notification system make the orchestrator operable. An operator can pause new assignments without abandoning current work, suspend shipping without stopping model execution, or prevent Jira mutations while continuing safe observation.

Finally, we are proud of the depth of testing and documentation. Dross includes hundreds of automated tests, temporary Git and SQLite fixtures, provider-transport fakes, lifecycle matrices, operational runbooks, and canonical architecture references. Those artifacts were essential because the most dangerous orchestration failures are often plausible-looking states that are internally inconsistent.

What we learned

First, a lot about how amazing the codex JSON-RPC app server is! The turn system and clear documentation makes it a breeze to integrate with Codex. Cluade's integration was a lot more painful due to the lack of an equivalent JSON-RPC app server (as far as we learned)

We also learned that the difficult part of agentic software development is not only generating code. It is coordinating everything around the generation.

The model is probabilistic, but most of the surrounding workflow should not be. Repository setup, ownership, state transitions, dependency checks, external effects, retries, and cleanup benefit from deterministic contracts and durable evidence.

We learned that context is a resource that must be managed deliberately. Every repeated instruction, rediscovered path, copied ticket body, and mechanical Git operation consumes tokens that could have been used for implementation or reasoning. Moving repeatable work into Dross reduces context pollution and gives workers a narrower, more useful assignment.

We learned not to infer state when it can be recorded explicitly. “The process stopped,” “the UI says complete,” and “the most recent turn succeeded” are not strong enough for an orchestrator. Exact identity and monotonic evidence are more work to implement, but they make recovery and automation possible.

We learned that provider neutrality should not mean pretending every provider is the same. A better abstraction acknowledges differences through capability contracts and lets shared lifecycle code operate only on evidence that each adapter can truthfully provide.

We also learned that recovery is a first-class product feature. Failures are not edge cases in a system that spans multiple processes, services, repositories, and model sessions. Every long-running operation needs an answer to: “What happens if we lose the process here and restart?”

Most importantly, we learned that AI-assisted development works best when humans provide clear goals, constraints, and acceptance criteria while the model handles implementation breadth and repetitive investigation. The strongest results came from repeatedly confronting generated code with tests and real evidence rather than accepting the first plausible implementation.

What’s next for Dross

The next major milestone is completing Agent Workflows, Dross’s reusable checklist-template and workflow-definition system.

That work will allow operators to:

  • Create, duplicate, edit, version, archive, import, and export workflow templates
  • Assign workflows by project, worker, and Jira issue type
  • Preview the resolved workflow before dispatch
  • Preserve exact workflow versions on every assignment
  • Add implementation steps, skill steps, notes, approvals, and gates
  • Reuse workflows across teams and repositories
  • Keep the required handoff contract intact while allowing the rest of the process to be customized

We also plan to expand Dross in several directions:

  • Better packaged installation and distribution
  • More issue-tracker and source-control integrations
  • Additional worker-runtime adapters
  • Richer approval and policy gates
  • Improved capacity, quota, and cost-aware scheduling
  • Better workflow analytics and audit exports
  • Stronger multi-project and multi-repository coordination
  • Remote and team-shared worker pools
  • More visual workflow and dependency tooling
  • Deeper release and deployment integrations

Longer term, we want Dross to evolve from a local orchestrator into a reusable operational layer for AI-assisted engineering teams: a place where work can move through a graph of models, deterministic tools, human approvals, tests, and delivery systems without losing authority, context, or accountability.

And finally, we're walking the path to Open Source with Dross!

Thank you for your time :)

Share this project:

Updates