“Add page-turn detection” sounds like a feature request. To a coding agent, it is an invitation to make dozens of unstated decisions.

Should the firmware inspect transcript text? Should the cloud own the decision? Does the camera capture immediately? Can two requests overlap? What happens while Ted is speaking? Does the wake word remain required? Which physical button is used? What should be logged?

The quality of an agent-generated change depends less on prompt cleverness than on how well the task captures system boundaries and acceptance evidence.

This is the workflow we now use to turn product ideas into Codex tasks.

Begin with observable behaviour

Do not begin with “add a protocol event” or “change the state machine”. Begin with what the person does and what they should experience.

For page turning, our product statement became:

During an active reading session, a child can clearly indicate that the page has changed by speaking or by pressing the designated page button. Ted captures one new page, waits for fresh context and then reads it. The child does not repeat the wake word. Duplicate inputs do not trigger duplicate captures.

That statement defines success without dictating every implementation choice. It also exposes failure cases: speech may be unclear, a button can bounce, a page capture may already be in flight and the network can drop.

Identify system invariants

The next section describes what the feature may not break.

For Tell Me Ted, common invariants include:

  • supported maintenance and recovery paths remain intact;
  • lifecycle checks stay correctly sequenced without unnecessarily blocking the core experience;
  • credentials and child content do not enter operational logs;
  • camera and microphone use remain bounded and purposeful;
  • authentication and encryption boundaries remain in place; and
  • the device stays within its resource and power budgets.

These are not generic warnings. They are testable properties of this system.

Give the agent the repository, not a story about it

Repository context should point to the current source of truth:

  • the current application entry points and state owners;
  • the relevant device, backend and hardware interfaces;
  • the security and privacy rules;
  • the relevant unit, integration and acceptance tests; and
  • the release and recovery runbooks.

This matters because architecture documents age. Older documents may describe a previous interaction model while the current product has moved on. A task should tell the agent which source wins when they disagree.

Break the work into stages

We rarely ask Codex to jump directly from product sentence to final implementation.

The first stage is investigation. Trace the current flow, list the components that own it, surface contradictions and propose a minimal design. No edits.

The second stage is the smallest coherent implementation. Make the protocol and state changes without opportunistic cleanup.

The third stage is evidence: unit tests, integration tests, the firmware build, invariant checks and resource comparisons.

The fourth stage is physical validation. Run the flow on representative hardware and record what the emulator could not prove.

The final stage is documentation and rollout. Update the protocol, runbook, release notes and rollback instructions.

This staged approach keeps uncertainty visible. It also gives the human owner clear decision points.

Specify evidence before the code exists

“Add tests” is not a useful acceptance criterion.

For page turns, the evidence includes scenarios such as:

  • a clear verbal or physical page turn produces one new capture;
  • held, repeated or overlapping input does not create duplicate work;
  • stale page context is not read after a page change;
  • speaking and listening boundaries remain clear;
  • network failure closes and cleans up the session; and
  • lifecycle and recovery invariant checks still pass.

The exact commands belong in the task. An agent should not guess which test environment is authoritative.

Ask the agent to inspect its own work

After implementation, we use a separate review prompt focused on consequences rather than completion:

  • List every removed or bypassed code path.
  • Compare the final diff with each invariant.
  • Identify assumptions that were not confirmed in source.
  • Report behaviour that was not tested.
  • Compare device resource use and memory-sensitive changes.
  • Check authentication, logging and child-data handling.
  • Explain how to roll back the change.

This review often surfaces a different set of issues from the original task. Implementation prompts reward forward motion. Review prompts reward doubt.

Run a second review through different lenses

For material changes, one review pass is not enough. We look at the same diff through four lenses.

The security and privacy lens checks credentials, public exposure, retention and logs.

The lifecycle lens checks startup, maintenance, provisioning and recovery.

The embedded-resource lens checks size, memory, power and peripheral ownership.

The user-experience lens checks what a child and caregiver actually observe when the happy path fails.

These can be separate Codex reviews, but a human remains responsible for reconciling them.

Require a rollback path

A task is incomplete if it describes only how to ship.

For cloud changes, rollback may be a previous service revision or a configuration switch. For device software, the supported recovery behaviour matters. For a risky feature, a flag or a small reversible commit can reduce the blast radius.

The task should name the condition that triggers rollback. “If it seems bad” is not operational guidance.

A reusable task template

Copy this structure and adapt it to your repository:

Objective

Describe the user-visible change in observable terms.

Current system

Link the current entry points, interfaces, protocols, architecture and tests. State which source is authoritative.

Invariants

List lifecycle, security, privacy, performance and resource behaviours that must remain unchanged.

Non-goals

Name adjacent cleanup, migrations and features that are out of scope.

Allowed change surface

List expected files and components. Require justification before changing anything outside them.

Acceptance scenarios

Describe success, failure, duplicate, timeout, recovery and rollback behaviour.

Evidence commands

Provide build, unit, integration, invariant and device-test steps.

Required review output

Ask for assumptions, deletions, resource impact, untested behaviour, residual risks and rollback instructions.

The prompt is not the control

The most important lesson from our lifecycle regression was that a good prompt is not a permanent safeguard.

Once an invariant matters, encode it in the repository. Add a test. Add a CI check. Put the rule beside the code it protects. Make the safe path easier than the unsafe one.

The prompt starts the task. The system must continue protecting itself after the conversation is gone.

That is how we try to use Codex on Tell Me Ted: not as an oracle that receives clever instructions, but as a capable engineering agent working inside boundaries that humans have made explicit and evidence that the repository can verify.

Next in the series: why our original architecture was reasonable, testable and still too complicated for the product.

Tell Me Ted is an independent, pre-launch project that I work on outside my role at HubSpot. The views expressed here are my own and do not represent HubSpot.