Designing an Agentic Flywheel for iOS Development
My previous post about the agentic flywheel was intentionally generic.
This one is the follow-up: how I would design an iOS-development-specific flywheel.
The framing still comes from Kief Morris’s article, Humans and Agents in Software Engineering Loops, especially these points:
- Harness = the collection of specifications, quality checks, and workflow guidance.
- The loop improves only if agents can evaluate performance and failure scenarios.
- For each workflow step, the agent should review results and recommend harness improvements.
- Recommendations should be scored by risk, cost, and benefit, and low-risk/high-value ones can be auto-applied.
Why a domain-specific flywheel?
A generic flywheel is useful, but iOS development has domain-specific constraints:
- Figma-level state accuracy matters, not only functional behavior.
- Logging requirements are product requirements, not optional implementation details.
- Team conventions (architecture, event handling, logging format, UI framework rules) matter for maintainability.
- TDD loop quality and static checks affect long-term velocity.
If the harness does not encode these constraints, the agent can still produce code, but the loop quality will be unstable.
Human workflow I am mapping
In my real workflow, development can be summarized as:
- Estimation
- Design
- Implementation
Before coding starts, PM shares task context (PRD + design/Figma). Then:
- Estimation is split by stage:
- design
- implementation
- integration with backend/other iOS developers
- developer self-test (requirement checks, design QA, logging QA)
- Design artifacts are created and reviewed:
- feature flow charts, including A/B branches if needed
- API flow and handling flow
- request/response/path contract details
- Implementation proceeds in small requirement-level TDD commits and small PRs.
- Final checks include UI parity with Figma, logging requirements, and developer self-test.
Recasting this as AI workflow commands
I would encode the same flow into three AI-first commands:
/estimation/design/implementation
And I would treat each as a measurable loop step, not just content generation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
+-------------------+
| /estimation |
+-------------------+
|
v
+-------------------+
| /design |
+-------------------+
|
v
+-----------------------------+
| Test-case package |
| (from design output) |
+-----------------------------+
|
v
+-----------------------------+
| Human review of test cases |
+-----------------------------+
|
v
+-----------------------------+
| /implementation |
| per TC -> TDD micro-loop |
+-----------------------------+
|
v
+-------------------+
| loop review |
| + harness update |
+-------------------+
|
v
+-------------------+
| next task |
+-------------------+
Step 1: /estimation
Input:
- PRD
- Figma
- integration constraints
- team rules
Output:
- MD estimate by stage:
- design
- implementation
- integration
- developer self-test
- explicit assumptions
- risk flags
Quality checks:
- Did the estimate include all stages?
- Are assumptions explicit and testable?
- Are dependencies called out early?
Harness improvement examples:
- If estimates repeatedly miss design QA effort, update estimation rubric.
- If integration effort is underestimated, add stronger dependency prompts.
Step 2: /design
This step should produce both design artifacts and executable test intent.
Output bundle:
- Functional flow chart (including A/B branches when relevant)
- API contract spec (path, params, request/response, edge cases)
- Test cases in Given/When/Then, grouped by screen and feature
- Snapshot-style UI expectations for Figma states
- Logging test cases (“when X happens, Y log is sent”)
- Additional engineering safety behavior (for example, error alert behavior)
I treat this as the key bridge from product intent to implementation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+-------------------------+
| /design |
| PRD + Figma |
| + logging requirement |
| + QA TC |
+-------------------------+
/ \
v v
+-------------------------+ +-------------------------+
| Design artifacts | | Test-case package |
| - flow charts | | - requirement TC |
| - API contracts | | - design snapshot TC |
+-------------------------+ | - logging TC |
| - safety/edge-case TC |
+-------------------------+
Quality checks:
- Can all requirements map to at least one test case?
- Are UI states in Figma mapped to testable snapshot expectations?
- Are logging requirements represented as test cases?
- Are critical negative/error scenarios included?
Harness improvement examples:
- If a requirement repeatedly escapes to implementation without a test case, tighten design output schema.
- If logging regressions repeat, promote logging TCs to a required section.
Step 3: /implementation
The implementation skill should consume design test cases and execute a strict TDD loop.
TDD loop per requirement-level unit:
- write test case
- confirm failure
- implement
- confirm pass
- run quality checks before commit
Quality checks should include:
- a static-rules gate before commit
- lint/format checks
- code coverage checks
- globalization checks (localized strings, layout safety for longer text)
- team-enforced style/architecture checks (for example, SwiftUI requirement for new views, MVVM, event handling style, logging style)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+-------------------------+
| test-case unit |
| (from /design output) |
+-------------------------+
|
v
[TDD micro-loop]
test fail -> implement -> test pass
|
v
+-------------------------+
| pre-commit checks |
| static rules gate |
| - lint/format |
| - coverage |
| - globalization |
| - team style/arch |
+-------------------------+
|
v
+-------------------------+
| small commit / small PR |
+-------------------------+
Harness improvement examples:
- If lint failures recur, strengthen implementation prompts and pre-commit check gating.
- If generated code repeatedly deviates from team style, add explicit templates or pattern references.
- If certain rules are always violated, convert them from guidance to hard checks.
- If team style/architecture keeps drifting, check whether the project itself has inconsistent patterns across modules. In that case, invest in clearer templates and stronger harness guidance before expecting stable agent output.
This investment takes real effort, and in that sense AI development is not very different from human development: if a project is hard for humans to code consistently, it is also hard for AI to code consistently.
What “giving agents information to evaluate the loop” means in iOS
For iOS work, this usually means giving the agent:
- task specs (PRD, acceptance criteria, dependencies)
- UI truth (Figma states and behavior)
- quality truth (lint/static rules/architecture conventions)
- observability truth (logging requirements)
- test truth (required failure scenarios and expected behavior)
Without these, the agent can generate output but cannot reliably evaluate loop performance.
Scoring recommendations and auto-applying harness updates
After each step, recommendations can be scored:
- risk
- cost
- benefit
- recurrence frequency
- reversibility
Then use policy gates:
- Low risk + high recurrence + low cost + reversible -> auto-apply
- Medium risk or unclear impact -> backlog + human approval
- High risk or architecture-impacting -> manual review required
This is how the flywheel stays safe while still getting faster.
Practical questions I expect
What if PRD misses important cases?
This is critical, and it is exactly why the design step must output a structured test-case package and why a human must review it carefully.
The key review question is:
- “If these screen-by-screen and feature-by-feature TCs are implemented and combined, will the feature be correct?”
If the answer is no, the next action is to resolve the missing input, not to guess:
- missing logging requirement -> request it explicitly
- missing PRD behavior -> ask PO/PM and clarify
- unclear edge-case behavior -> add explicit test cases before implementation
The harness side should also improve: the design skill should actively flag likely missing inputs and unresolved assumptions to the developer.
What if QA TC or logging requirements arrive late during implementation?
Use an incremental loop:
- continue with available inputs
- when new QA TC/logging requirements arrive, run additional
/designand/implementationloops for the delta
This is not fundamentally different from human development. The loop should support iterative updates instead of assuming perfect upfront inputs.
What about small bug fixes or tiny features?
The same workflow still applies, just at smaller scope.
- Run
/designwith a concise problem statement. - Generate and review the resulting TCs.
- Implement via the same TDD + static-rules gate loop.
I do not want hard constraints like “must provide a Jira ticket.” The skill should represent a workflow stage, not a rigid input format. It should evolve with context.
Practical example of loop improvement
If /implementation repeatedly fails static checks:
- detect failure pattern
- propose harness change
- strengthen prompt constraints
- add missing template
- move a soft rule into hard gate
- score recommendation
- auto-apply if policy threshold is met
- verify next task passes the same check
That is the flywheel in practice: not only fixing code, but improving the system that generates code.
Closing
My goal is not to remove humans.
My goal is to move humans from repetitive correction work to harness engineering work.
For iOS development, that means encoding estimation rules, design-to-test conversion, TDD execution, and static quality gates into a loop that can measure itself and improve itself task after task.