Repository navigation
Conversation
knihit
force-pushed
the
wc/03-api-contract
branch
2 times, most recently
from
October 24, 2026 04:58
ac20dc4 to
84da3ee
Compare
knihit
force-pushed
the
wc/03-api-contract
branch
from
October 24, 2026 13:12
84da3ee to
8521072
Compare
knihit
force-pushed
the
wc/03-api-contract
branch
2 times, most recently
from
October 24, 2026 18:25
393f220 to
6a848d6
Compare
7 of 11 tasks
knihit
marked this pull request as ready for review
October 25, 2026 18:18
knihit
requested review from
georgebearden,
ihmaws,
shsenior and
simonkrol
as code owners
October 25, 2026 18:18
Describe the first-release API in workflow-canvas/api/openapi.yaml (OpenAPI 3.1): load, save and check a workflow, start a run, and get a run's status. A workflow is a name, an intent and stages of name and agent; the only harness is kiro-cli. Every error response uses one Error schema. A vitest test validates the file against the OpenAPI 3.1 specification, pins the operation list, requires an operationId, summary and example on every operation, and checks each example against its schema. It is also available as `npm run api:lint`, which CI runs. Adds @apidevtools/swagger-parser, ajv and ajv-formats as exact-pinned dev dependencies.
Add POST /api/session, so a client can get the token that every other call needs. Say how the contract grows: a response may gain fields and a client ignores the ones it does not know, so the response schemas no longer forbid extra properties. A request still refuses them. State what a backend has to decide: which workflow is loaded, saved and run (the one the server started on, and a 404 for another name or for a run with no saved file), the accepted workflow text, the checks that make a text invalid, and a table of the diagnostic codes. Add the request guards, the retry rule for a lost save, the size limits, the run invariants and the exit codes. A check without errors has a view, and one with errors has none. Note that a later version will refuse an untrusted run with 409. Declare the X-Konductor-Api header on every response. Replace the invalid example with a one-error case. Extend the contract test: schema-level examples, the code that fits each error status, open response and closed request schemas, the diagnostic codes against their table, and the rules that the examples must obey (a hash is the SHA-256 of its text, counts add up, a run's stages follow its status). api:lint now runs only the contract test.
Describe what a run does stage by stage: the order, what each stage is given, what makes a stage pass or block, the exit code of a halted run, an unknown agent and a run left running by a server stop. State that a file that is not a plain readable file is 404 and that the server writes text as sent. Also fix the accepted Host and Origin values, the order of checks, the launch code, bad_name for a body name, the run id in already_running, the goal limit in characters, UTC timestamps, and the open cases of the check rules. The test now ties each view and diagnostic position to the example text.
State that the workflow text is YAML 1.2 read with the core schema, and add a DUPLICATE_KEY diagnostic for a key that appears twice in one mapping. Also say how a call is checked when it is a run, that a null base_hash on an existing file is a conflict, that a load returns the file's bytes unchanged, what a character, column and line are, when a suggestion is given, which Content-Type values are accepted, what a crashed run reads as when every stage had passed, and how strong a launch code and token are. Make the tests pair each view and diagnostic with its own text.
A save with a base_hash for a file that does not exist is a 409 conflict without current_hash, shown by a second example. The repeated key test now checks the exact line and columns, and the contract says keys are compared as strings and how an unknown repeated key is reported.
…I contract Keys compare by their text before typing, a non-scalar key is unsupported, the base_hash check and the write are one step with an exclusive create for null, and the 60 second window starts when the launch address is printed. Each rule has a check example or a test, and the unsupported running-run check is dropped.
…e API contract The order of checks now names the unknown path (404) and the wrong method (405) between Host and Origin. A second YAML document is reported at its --- line. The README and CHANGELOG no longer describe the stub as a later change, and the root README lists workflow-canvas in the project layout.
The prose promised a 405 with an Allow header and the error code was listed, but no operation had a 405 response. Add a shared MethodNotAllowed response and an Allow header, reference them from every operation, and check that every status with an error code is documented and that each operation documents the Allow header.
The one shared Allow example said GET, PUT for every path, but only /api/workflow accepts both. Each path now points at a 405 response whose Allow header names its real methods, and the contract test compares that header to the methods the path declares. In each operation the 405 entry now follows 404.
knihit
force-pushed
the
wc/03-api-contract
branch
from
October 25, 2026 20:05
1bedac4 to
3db3e30
Compare
Contributor
Author
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
API contract (
workflow-canvas/api/openapi.yaml, OpenAPI 3.1):POST /api/session), load a workflow (GET /api/workflow), save it (PUT /api/workflow), check it (POST /api/validate), start a run (POST /api/run) and get the status of a run (GET /api/runs/{id}). Anything else is left out until it is needed, so the contract only grows.name, anintentandstages, and each stage is anameand anagent. The only harness iskiro-cli. The file holds small named schemas (Name,Stage,WorkflowView,Diagnostic,Runand so on) that the operations reuse through$ref.onandnoare strings andtrueis a boolean; keys, limits, reserved names, the plain YAML subset), the checks that make a text invalid, and a table of the diagnostic codes with the path and position each reports. A key that appears twice in one mapping is the newDUPLICATE_KEYdiagnostic, reported at the later key. Keys compare by their text before it is read as a number, boolean or null (1and'1'are one key;trueandTrue, or1and1.0, are two), a key that is not a scalar isYAML_UNSUPPORTED, and an unknown key that is repeated hasUNKNOWN_KEYat the first andDUPLICATE_KEYat each later one. I chose a new code overYAML_SYNTAXbecauseYAML_SYNTAXreports where a parser stopped, which differs between parsers, whileDUPLICATE_KEYhas one position the stub and the backend can both give.kiro-clisession given the intent's outcome and the goal; a stage passes on exit status 0 and is otherwise blocked (including an agent id that does not exist), which halts the run withexit_code1; a run leftrunningby a server stop reads as halted after the restart.not_foundon load, save and run. The server writestextexactly as sent and loads it unchanged, so ahashis the hash of that text. Abase_hashofnullon an existing file is a 409conflict, and so is abase_hashthat is a hash for a file that no longer exists (that one has nocurrent_hash). A length counts Unicode code points, and a line and column are defined. It also gives the acceptedHostandOrigin, the order in which a call is checked (a run checks the saved file first, then the workflow, then whether a run is active, then the harness), the strength of the launch code and token, where the launch code is found (the 60 second window starts when the server prints the launch address), and the run id in a 409already_running.status,exit_code,finished_atand the stages.Errorschema: a sentence for a person (error), a stablecode, and a few optional extras such ascurrent_hashfor a save conflict. Common responses are defined once and referenced. Every response declares theX-Konductor-Apiheader.operationId, a summary and examples for each request and response body.base_hashmust match the hash that load returned, or the save is a 409conflict. Abase_hashofnullcreates a file that must not exist yet. Checkingbase_hashand writing are one step with respect to other saves, so of two saves with the samebase_hashone is a 409, and a create is exclusive.GET /api/runs/{id}, about once a second. A push stream for run events is not part of this version.Contract test (
workflow-canvas/api/openapi.test.ts):@apidevtools/swagger-parser, which also fails on a$refthat does not resolve.operationIdand summary on every operation, an example on every request and response body, the version header on every response, and the oneErrorschema on every error status.ajv(JSON Schema 2020-12, the dialect of OpenAPI 3.1) andajv-formats.npm testand on its own asnpm run api:lint, which runs only this test file. Vitest also picks upapi/**/*.test.ts, andtsconfig.node.jsonand ESLint coverapi/.Dependencies:
@apidevtools/swagger-parser13.1.0,ajv8.20.0 andajv-formats3.0.1, exact-pinned dev dependencies in the existingpackage.json(still one package). ESLint keeps its ownajv6, which npm now nests undereslint.npm auditreports 0 vulnerabilities.CI:
.github/workflows/workflow-canvas.yml: added anAPI contractstep (npm run api:lint) to the existing lint/typecheck/test/build job, so it runs on Node 24 and 26. It repeats the contract test thatnpm testruns, to give a failure its own label.Docs:
not_found) and the wrong method (405method_not_allowed) betweenHostandOrigin, and theYAML_UNSUPPORTEDrow says a second YAML document is reported at its---line.workflow-canvas/README.md: an "API contract" section (what the file is, how to validate it, and that every server of the API follows it), andapi/moved out of the "later PRs" list. The rootREADME.mdproject layout listsworkflow-canvas/.CHANGELOG.md: entry under Unreleased.VERSIONis not bumped.Screenshots
No UI change in this PR, so there are no new screenshots. The Designer and Execution screenshots in the previous PR still apply.
Type of Change
package.json,Cargo.toml, or CLI dependency)workflow-canvas/Testing
npm test(runstests/scripts/**/*.test.js) gives 119 passing and 17 failing. The 17 failures are the same ones as before this PR, inclaude-code-agent-runner.test.js,generate-agent-files.test.jsandrun-claude-subset.test.js, which this PR does not touch. It is not one of the CI checks.workflow-canvas/:npm run lint,npm run typecheck,npm test(39 tests: 3 existing and 36 for the contract),npm run buildandnpm run test:e2e(5 tests) pass locally on Node 24DUPLICATE_KEYin the schema, a repeated-key diagnostic at the first key, a save answer with a different view than its text, a missing YAML statement and a check answer without a request of its name. I reverted each edit.Checklist
Notes for Reviewers
integration/workflow-canvas<- Add workflow-canvas scaffold: Vite, React, Cloudscape, CI #77 (wc/01-scaffold) <- Add Playwright end-to-end tests and screenshots for workflow-canvas #78 (wc/02-e2e) <- this PR. Base iswc/02-e2e; GitHub retargets it as Add Playwright end-to-end tests and screenshots for workflow-canvas #78 merges.info.descriptionlists the request checks, the size limits, the workflow text and the diagnostic codes.POST /api/sessionis in the contract so the stub and the real server hand out the token the same way; a check with errors has noview; the diagnostic codes are a closed list for this version that clients treat as open; the run state keepsorderplus astagesmap keyed by stage name; times are ISO 8601 strings;base_hash,text,hashandvieware present-but-nullrather than absent where a file does not exist yet.package-lock.jsonaccounts for about 200 of the added lines.