Tsurezure Agent OPS
Tsurezure Agent OPS
AIDD

Can Operations Staff Ask AI to Modify a Todo App? Clarification Questions and Confirmed Requirements

I built an interface that refuses to send ambiguous requests such as 'add priorities and make Todos easier to read' directly into implementation. It records answers, manual requirement edits, and human confirmation, then verifies that the server blocks change jobs while questions remain unanswered or the requirements remain unconfirmed.

Share on X
View Markdown

The End Goal Runs from Chat to a Draft PR

This series is building, in stages, a workflow that lets Todo app operations staff request changes through a dedicated web interface without working directly with Git or a terminal. The end goal is for a user to answer AI questions, edit and confirm the structured requirements, then have code changes and tests run in an isolated environment. Only passing changes should become GitHub Draft PRs, which are proposals prepared before requesting formal review. The final comparison will run ten types of modifications and compare this interface with manually asking an existing coding agent to perform each task.

Request a change in natural language

Answer questions about missing information    ← Part 2

Edit and confirm structured requirements      ← Part 2

Modify code and run tests in isolation         ← Part 3 onward

Create a draft change proposal only if it passes ← Part 5

Compare manual requests across ten changes     ← Part 6

Part one tested the foundation required for the latter half of this flow. I called three AI APIs through a common interface and tested their generated code proposals in an isolated environment. Three of nine fixed tests failed and the process stopped. Nothing was written to the GitHub code or production data, confirming that a failed change could be stopped before leaving the environment.

The first interface, however, displayed decisions such as “three priority levels,” “existing Todos default to medium,” and “the list can be filtered” from the beginning. The screen made those values look like user decisions, but they were fixed experimental inputs.

When did the user receive questions? Where did they answer? What exactly did they review before confirming the change?

Those steps did not exist in the interface.

Switching among three AI providers does not make a change interface usable by non-engineers if the confirmation process is omitted. I therefore placed a Change Request between the natural-language request and the code modification. A Change Request stores the conversation, unanswered questions, structured requirements, and human confirmation state for one modification.

In this article, structured requirements separate the conversation into a change summary, current state, expected state, acceptance criteria that define completion, and a test plan. A change job is the unit that sends confirmed requirements to the later code-modification stage.

Four Ambiguities Inside “Make It Easier to Read”

I used the same request as in part one:

I want priorities on my Todos. Make them easier to read.

The verification log refers to this request as scenario S01. S01 abbreviates “Scenario 01”; the number does not represent difficulty or execution order.

“Add priorities” identifies the feature, but “make them easier to read” does not define its behavior. The Change Request interface returned four unanswered questions:

  1. How many priority levels should exist, and which values should they use?
  2. What priority should existing Todos receive?
  3. How should users distinguish priorities in the list?
  4. How should the priority filter interact with the existing status filter?

Change Request interface showing four clarification questions for an ambiguous priority request and blocking the change job while they remain unanswered

The structured requirements on the right still have empty expected-state, acceptance-criteria, and test-plan fields. The interface shows “Waiting for answers” and disables both “Confirm these requirements” and “Start change job.”

I also called the change-job creation API directly without using the interface. A disabled button is not a meaningful boundary if a direct API request can bypass it.

The server rechecked the four entries in openQuestions and issued no job ID. The number of calls to the code-modification AI remained zero.

Answered Questions Still Leave an Unconfirmed State

I answered the questions as follows:

ClarificationHuman answer
Priority valuesThree levels: low, medium, and high
Default for existing Todosmedium
List displayA badge using both color and text
FilteringCan be combined with the existing status filter

status is the existing API field that represents whether a Todo is open or completed.

A deterministic transformation applied the answers to the common change-request-v1 format and generated the expected state, acceptance criteria, and test plan. Rather than retaining only the conversation, it splits the information into arrays that later stages can validate field by field.

{
  "openQuestions": [],
  "confirmedByHuman": false,
  "acceptanceCriteria": [
    "Existing Todos are displayed as medium",
    "The API returns 400 for a disallowed priority",
    "The list displays priority with a badge that uses both color and text",
    "The priority filter can be combined with status"
  ],
  "testPlan": [
    "Test migration of existing Todos to medium",
    "API test that rejects a disallowed priority",
    "End-to-end test of priority display and filtering from the UI to the API"
  ]
}

There are now zero unanswered questions. confirmedByHuman, however, is still false.

Receiving answers and receiving permission to proceed with implementation are separate states.

”Use Color and Text” Was Still an Ambiguous Acceptance Condition

One generated acceptance criterion said, “The list displays priority with a badge that uses both color and text.” That wording does not establish whether a user who cannot distinguish the colors can identify the priority from the text alone. I added another criterion through the interface: “Priority can be distinguished by text without relying on color.”

Interface after four answers were incorporated into the structured requirements and a human edited the acceptance criteria, still stopped while awaiting confirmation

The interface allows a human to edit the change summary, expected state, acceptance criteria, and test plan. Saving any edit resets the confirmation state to false, even if an earlier version was confirmed. Otherwise, approval of old content could remain attached after the requirements changed.

After applying the four answers, I called the change-job creation API again. The server stopped with “Human confirmation of the change requirements is incomplete.” Together with the unanswered-question case, the server-side start conditions had now blocked the process twice.

A Disabled Button Cannot Stop a Change Job by Itself

When the user selects “Confirm these requirements,” the server checks:

  • All required fields are present
  • openQuestions contains zero entries
  • The acceptance criteria and test plan are not empty
  • A human has reviewed the current content

Only after all four conditions were satisfied did “Start change job” issue one job ID.

Interface showing two pre-confirmation stops, zero code-AI calls, and a single job ID issued from confirmed requirements

The part-two job stops at queued_for_next_phase. The code-modification AI has been called zero times, and the runner that would apply and test a generated proposal has not started. This verification confirms that only confirmed requirements can pass into the later stage.

Disabling buttons reduces accidental operations, but it does not form a safety boundary. The change-job API must recheck the confirmation state and record rejection reasons in the audit trail so the same conditions apply to calls made outside the interface.

Testing Both “Add a Due Date” and “Make Todos More Useful”

An interface that works only for priorities cannot handle other requests. I passed a due-date change and an underspecified request through the same start and stop conditions. The verification logs record priority as S01, due date as S02, and the underspecified request as S06. The numbering jumps from S02 to S06 because this verification selected three cases from a ten-case plan. S03 through S05 cover tags, CSV export, and other requests planned for later articles; they were not run here.

Modification request (scenario ID)Initial questionsUnansweredUnconfirmedJob after confirmationCode AI
Add priority (S01)4StoppedStopped10 calls
Add due date (S02)3StoppedStopped10 calls
Underspecified request (S06)2StoppedNot reached00 calls

For the due-date request, the interface asked whether the field should contain only a date or include a time, which time zone should determine expiration, and how completed Todos should be treated. The human answers were “date only,” “Asia/Tokyo,” and “exclude completed Todos from overdue results.” After these three points were recorded in the acceptance criteria and confirmed, the server issued a job ID.

The underspecified input was “Make Todos more useful.” The interface asked who was struggling with which operation and what outcome would count as complete. I left both questions unanswered and called the change-job creation API.

The result was zero jobs. The deterministic transformation did not choose priority, due date, tags, or another feature on the user’s behalf.

Reproducing the Same Stops

npm run verify:change-requests is a custom verification script prepared for this article. It feeds three fixed requests and their answers into the Change Request management logic. The script checks rejection while questions remain unanswered, rejection while requirements remain unconfirmed, the number of jobs issued after confirmation, and the fact that neither the code-modification AI nor the runner executes.

npm run verify:change-requests
S01: queued, jobs=1, providerCalls=0
S02: queued, jobs=1, providerCalls=0
S06: needs_clarification, jobs=0, providerCalls=0

queued means waiting for the next stage, and needs_clarification means waiting for answers. providerCalls=0 confirms that the code-modification AI was not called.

The server stores conversations and Change Requests in a JSON file, so questions, answers, manual edits, and stop history remain after a page reload. This storage mechanism is for a local proof of concept. A multi-user environment in which several people can update the same request would require a database and version checks to prevent stale writes from overwriting newer content.

Predefined Questions Cannot Evaluate AI Question Quality

In part one, live responses from Sakura AI Engine, Cloudflare Workers AI, and Google Gemini were normalized into the common requirement-plan-v1 format. This verification does not call an external API. It uses a predefined transformation for the three requests so that the same questions appear on every run. The implementation calls this component deterministic-scenario-adapter.

This separation makes the state transitions easier to test. If questions vary on every run, it becomes difficult to tell whether a failure belongs to the change-job gate or to missing questions. Fixed requests and questions make the “unanswered,” “answered but unconfirmed,” and “confirmed” states reproducible.

Stopping on predefined questions does not show that a live AI can generate the necessary questions. Question quality for unrestricted change requests, follow-up questions after an answer, and handling contradictory answers remain unverified.

The Change Job Still Has No Code Change Behind It

For both priority and due-date changes, the server rejected job creation while questions remained unanswered and while the requirements remained unconfirmed. It issued a job ID only after a human edited and confirmed the requirements. The underspecified request stopped with unanswered questions instead of selecting an improvement automatically.

The decision for part two is therefore Conditional Go. Change Request state management and the server-side start conditions worked from conversation through confirmed requirements. The quality of questions generated by an external AI API and the ability to complete a real code change from an issued job remain unverified.

Can the runner start from a confirmed Change Request and repair the three test failures from part one? Whether the dedicated interface can reach a completed code change depends on that next result.

DUOps

Author

DUOps(デュオプス)

LLMOps、Agent、MCP、Langfuse、Cloudflare 周辺の実装と運用を、個人で試しながら記録しています。

Xを見る

Comments

Related posts

AIDD

Can Operations Staff Ask AI to Modify a Todo App? Priority and a Repair Loop

I sent the confirmed priority request from part two into an isolated environment created from a fixed starting point. The saved AI proposal from part one failed three of nine repository tests and the priority-filter acceptance check, but one predefined repair passed four check groups and produced a local commit without changing the remote GitHub repository.