Inkitt developed a one-shot PR creator that automates small, low-risk code changes using an event-driven orchestrator. This system coordinates short-lived agent containers, manages persistent workflow state, and integrates robust safeguards for permissions and idempotency, reducing manual developer overhead for routine tasks. The architecture emphasizes separating decision-making from side effects and ensuring resumable execution.
Read original on InfoQ ArchitectureInkitt's one-shot PR creator is an automated system designed to handle small, low-risk software changes from task intake to a draft pull request. The core of this system is an event-driven orchestrator that manages the lifecycle of various AI agents, eliminating the need for developers to locally supervise these agents. This approach frees up developer time and streamlines the delivery of minor code updates, ensuring daily code shipments.
Unlike fixed pipelines, the orchestrator coordinates short-lived, ephemeral agent containers, each responsible for a specific stage like specification, implementation, verification, or CI failure repair. A crucial design decision is the persistence of each run's state in a database, allowing workflows to resume from their recorded state. This provides resilience against failures and ensures long-running processes can pick up where they left off.
Idempotency and Resilience
Designing for idempotency is critical in event-driven systems to handle duplicate events or retries gracefully. Inkitt's system addresses this through deduplication and conditional database writes, ensuring that operations can be safely re-applied without adverse side effects. This is particularly important for tasks like CI completion, where the orchestrator queries GitHub for final status rather than relying on individual job events, preventing premature workflow completion or unnecessary retries.
A strong security model is fundamental. The orchestrator isolates decision-making from side effects, with a core transition function that maps state to actions without direct database or network access. Agent containers receive only short-lived, restricted credentials (e.g., repository tokens, model credentials), preventing them from accessing sensitive system credentials like Slack, Linear, or cloud identities. Additionally, a separate check inspects Git diffs to ensure changes do not affect restricted paths, and automation is strictly limited to predefined boundaries, rejecting high-risk changes like database migrations or authentication code.
# Conceptual simplified state transition for the orchestrator
def transition_state(current_state, event):
if event.type == 'TASK_RECEIVED':
return {'status': 'SPEC_GENERATING', 'task_id': event.task_id}
elif current_state['status'] == 'SPEC_GENERATING' and event.type == 'SPEC_COMPLETED':
return {'status': 'CODE_IMPLEMENTING', 'spec': event.spec}
elif current_state['status'] == 'CODE_IMPLEMENTING' and event.type == 'CODE_COMMIT_SUCCESS':
return {'status': 'PR_DRAFTED', 'pr_url': event.pr_url}
# ... handle other transitions and errors
return current_state