Every product team runs two loops that barely talk to each other. The support loop collects bug reports and feature requests, and the delivery loop ships code. Between them sits a pile of manual glue: someone reads the ticket, guesses severity, files it in a second tool, an engineer eventually picks it up, and — if the stars align — someone remembers to tell the reporter it shipped. Connect is my attempt to weld those two loops into one, with an AI in the middle and a human holding the merge gate.
This is the third essay in a series on the systems I run my own projects with — the platform underneath it is myAI, whose task queue and autonomous runner do the heavy lifting here. This post is about the support half: what Connect is, how the triage→fix loop actually works (with diagrams), and how the written plans steered it somewhere more interesting — and more conservative — than where it started.
1. The problem: a ticket is work the codebase already understands
A well-written bug report contains almost everything needed to fix it: what happened, where, and how to reproduce it. What a traditional helpdesk does with that information is summarise it for a human router. The insight behind Connect is that a code-aware AI can do dramatically better, because it can read the ticket and the source code: classify severity with a rationale, spot likely duplicates, point at candidate files from the stack scan and git history, and hand the whole enriched package to a build system that already knows how to work a scoped task on a branch.
The original vision document put it bluntly: install one command, and your app gets a support team that reads your code. The traditional pipeline — human reads, human triages, human assigns, developer fixes, developer deploys, human writes "fixed in v2.3" — collapses into a loop measured in minutes to hours instead of weeks.
2. What Connect is
Connect is an installable module plus a loop. The module drops into a host application and adds a support portal — bug reports, feature requests with voting, a searchable FAQ, and a live status page. The loop turns a triaged ticket into an autonomous build task on the myAI gateway and streams progress back onto the ticket's public timeline.
Two design commitments run through everything:
- The data lives in the host app. Models, API routes, and pages are installed into the customer's own stack and database — Connect is not a SaaS silo holding your tickets hostage. A CLI installer scans the project, detects the framework, and copies in the adapter for it.
- The loop is inert until armed. Every autonomous piece is environment-gated and a safe no-op by default. With no AI key and no gateway configured, Connect is a perfectly good manual helpdesk; each capability switches on independently when its configuration appears.
flowchart TB
subgraph host["Host application (customer's stack, customer's database)"]
P["Support portal<br/>bugs · features + voting · FAQ · live status"]
A["Admin console<br/>triage · queue · settings · loop analytics"]
API["Installed API routes<br/>server-side — secrets never reach the browser"]
DB[("Host app's database<br/>tickets · timelines · articles · settings")]
P --> API --> DB
A --> API
end
subgraph loop["The autonomous loop (env-gated, off by default)"]
GW["myAI gateway<br/>shared task queue"]
RUN["off-hours CLI runner<br/>branch → analyze → plan → code → test → PR"]
GW --> RUN
end
API -- "outbound: triaged bug → build task" --> GW
RUN -- "inbound: token-authed progress webhook" --> API
That last pair of arrows is the whole product. Outbound, a triaged bug is submitted to the gateway as an autonomous build task. Inbound, the runner posts progress callbacks as it works, which drive the ticket's timeline and lifecycle status. Support and delivery stop being separate worlds; they're two halves of one round trip.
3. The triage → fix loop
Here is the full journey of a bug report, as actually shipped:
sequenceDiagram
participant U as Reporter
participant C as Connect (in host app)
participant Ad as Admin (human)
participant AI as AI triage
participant GW as Gateway queue
participant R as Autonomous runner
U->>C: files bug — status: reported
Ad->>AI: request triage suggestion
AI-->>Ad: severity + rationale · likely duplicates<br/>candidate files · routing · root-cause hypothesis
Note over AI: advisory and read-only —<br/>never mutates the ticket
Ad->>C: apply triage — status: triaged<br/>(audit note appended, always traceable)
C->>GW: queue build (one-click, or auto when armed)<br/>status: working
GW->>R: runner claims task on its autonomous window
loop as the fix progresses
R->>C: progress webhook — stage + message
C-->>U: public timeline updates live
end
R->>C: merged → solved · verified → deployed
C-->>U: fix confirmed live, PR linked
A few of these steps deserve unpacking.
Triage is advisory by construction. The AI suggestion is codebase-aware — enriched with the project's stack scan, candidate files with git history, and recalled patterns from similar past tickets — but it is read-only. Only a human's apply mutates the ticket, and the apply appends an audit note (who, when, rationale) so every AI-assisted decision is traceable afterwards. If no AI key is configured, the endpoint politely reports itself disabled and the admin triages by hand.
Queueing has one automatic door and one manual one. An org-level setting decides whether applying triage also fires the build queue, or whether the ticket rests at triaged until an admin clicks "queue build". Both doors share one core, and both enforce the same guards: the ticket must actually be in triaged, must not already be queued, and a gateway failure leaves the ticket untouched and retryable. Severity maps onto task priority, so a critical bug outranks a cosmetic one in the runner's queue.
There are two fix paths with different trust levels. The standard path lets the loop run to deployment. A stricter sibling queues a gated task whose contract is "open a PR, never merge" — the human owns the merge. That choice — per ticket, not per installation — turned out to be the right granularity for how much autonomy to extend.
Progress flows back as a timeline, not a status flip. Each runner callback appends a stage update the reporter can watch live on the public status page — received, analyzing, planning, coding, testing, deploying, merged, verified — with a progress percentage per stage.
4. Two vocabularies of state
One of the quieter design decisions is that a ticket carries two layers of state, stored separately. The lifecycle status is coarse and user-meaningful: reported → triaged → working → solved → deployed → closed, with side exits for rejected and duplicate. The pipeline stages are fine-grained runner telemetry. A folding rule maps stages onto statuses, so users see honest granularity without the lifecycle thrashing:
flowchart LR
subgraph stages["Runner stages (fine-grained telemetry)"]
s1["received 5%"] --> s2["analyzing 15%"] --> s3["planning 25%"] --> s4["coding 50%"]
s4 --> s5["testing 70%"] --> s6["deploying 85%"] --> s7["merged 95%"] --> s8["verified 100%"]
end
subgraph status["Ticket status (coarse lifecycle)"]
W["working"] --> SO["solved"] --> D["deployed"]
end
s1 -. folds to .-> W
s6 -. folds to .-> W
s7 -. folds to .-> SO
s8 -. folds to .-> D
Status advances are forward-only: a late or out-of-order callback — a stray coding event arriving after deployed — is recorded on the timeline but never rolls a shipped ticket backwards. Distributed callbacks over the public internet will arrive late and duplicated; making the state machine monotonic was cheaper than making the network polite.
The privacy model is similarly small and load-bearing. Every ticket has a public flag (private by default); private tickets are visible only to their reporter, timeline updates inherit the parent ticket's visibility, and every query is scoped to an organisation. Reporter notifications ride on transactional email that is deliberately fire-and-forget — an email provider outage degrades notifications, never the API.
5. What this means for organisations
The reporter is finally in the loop. The most neglected person in every bug's life is the one who reported it. Connect's public timeline, live status page, and status-change emails mean "we fixed it" is something users watch happen rather than discover months later. That is a support-quality improvement even with zero autonomy armed.
Autonomy arrives as a dial, not a leap. An organisation can run Connect as a manual helpdesk, then turn on advisory triage, then one-click queueing, then auto-queue-on-triage, then per-ticket gated fixes — each step independently reversible via configuration. Nothing in the architecture forces trust before evidence earns it.
The funnel is observable. The admin analytics expose the triage→queue→PR→deploy funnel directly: the share of bugs that reached production through the loop, average time per stage (so you can find the bottleneck), and throughput per agent and per severity. When you propose letting an AI fix bugs unattended, "here is the autonomous fix rate and where tickets stall" is the difference between a pitch and a report.
Everything privileged is auditable. Triage applies carry audit notes, the runner authenticates to a single token-guarded webhook, admin endpoints refuse non-admin callers, and the queue guards make double-queueing impossible. The safety rails aren't a policy document; they're endpoint behaviour.
6. Where AI drives the growth
The economics of the loop hinge on a simple asymmetry: most support tickets are small, and small is exactly what autonomous execution is good at.
- The long tail becomes economical. A typo, a broken button state, a missing await — tickets that never justified interrupting an engineer become overnight queue items with a reviewed PR by morning.
- Triage quality compounds. Duplicate detection, severity rationales, and routing suggestions get better as the system accumulates ticket history and codebase context — and every applied suggestion is labelled training material for the next one.
- Patterns make repeat fixes fast. The vision document's design has each resolved ticket stored as a reusable pattern with a confidence score, so the second occurrence of a known failure class is resolved from memory in minutes rather than re-diagnosed from scratch [VERIFY: pattern-memory integration is the design's direction; the shipped loop currently recalls patterns at triage time].
- Cost is tiered by design. The plan routes cheap models to bulk triage and reserves the strongest models for code fixes — the same cost-law thinking as the platform underneath: spend capability where it changes outcomes, not uniformly.
7. Open problems — and an invitation
The honest list of what's unsolved, straight from my own discovery notes:
- Real-time is still polling. The live status page refreshes on an interval; server-sent events or sockets would make the timeline genuinely live.
- Attachments deserve real storage. Screenshots currently travel as inline-encoded data in the ticket document — fine at small scale, wrong at product scale.
- Inbound channels. Today tickets arrive through the portal and API; the roadmap's email/chat/issue-sync ingestion — meeting reporters where they already are — is designed but not built.
- Duplicate detection should be automatic. The schema and triage suggestions support it; closing duplicates without a human glance is a trust threshold I haven't crossed yet.
- Fix quality needs its own metric. An autonomous fix rate is necessary but not sufficient — the number I want is regression rate on autonomous fixes versus human ones, measured honestly before the auto-merge dial goes further.
- Multi-framework adapters. The installer's architecture anticipates several web frameworks; the deepest adapter today is the one I dog-food [VERIFY: adapter coverage evolves with the CLI].
If you're building in this space — support tooling, agentic delivery, or the trust-calibration problem of letting AI touch production — I'd genuinely like to compare notes. Get in touch.
8. How the plan shaped it
Connect converged across three written artifacts, and the trajectory between them is the most instructive part.
The vision document was maximalist: a fully autonomous "black box" helpdesk — user submits ticket, AI triages, fixes, tests, deploys, and notifies, with no human in the loop unless configured otherwise. Ten modules, from a CLI installer and a codebase-intelligence engine to pattern memory and an admin dashboard. It was a genuinely useful document because it was maximalist: it mapped the full territory and — crucially — inventoried how much already existed in my other projects, concluding that roughly half the product was reuse rather than invention.
Then a discovery document did something plans rarely do: it documented the version of Connect that was already running in production inside another of my apps, schema by schema, endpoint by endpoint, gotcha by gotcha. That grounded everything. The patterns that survived into the product — server-side proxying so admin secrets never reach the browser, fire-and-forget notifications, numeric rank fields for database-level severity sorting, the public/private flag, the stage pipeline — were all observed working, not designed on a whiteboard. So were the mistakes: inline-encoded screenshots, polling, two competing URL-resolution strategies. The discovery doc's gap list became the standalone product's backlog almost verbatim.
Finally, a production roadmap marked the shift from building features to operating a product. Its MoSCoW cut is telling: the must-haves were not capabilities but trust infrastructure — tests over the critical paths, a machine-readable API contract with interactive docs, a health endpoint, rate limiting, structured logging. The line I keep coming back to from that document: the app works; this push is about making it safe to leave running unattended in front of real users.
That's also the arc of the whole project. The vision said "zero human intervention"; the shipped loop says advisory triage, human apply, guarded queue, token-authed callbacks, forward-only state, and a per-ticket choice of how much autonomy to extend. The ambition didn't shrink — the default did. Full autonomy is still there, one setting away; but the architecture insists you arm it deliberately, watch the funnel, and earn each notch of the dial. Getting closer to production made the design more conservative, and I've come to think that's what maturity looks like in agentic systems: the interesting engineering isn't making the AI act — it's making every action gated, observable, and reversible enough that you can let it.
Written from the project's actual vision, discovery, and roadmap documents, and the shipped loop's design docs. The support→build loop described here runs on the same platform that built this site.