Teach Skill to wait for Plan analysis - #9
Conversation
Technical reviewThe consumer side of firstdraft/cli#8, teaching the Skill to wait for analysis and branch on what comes back. Verification reproducedThe pinned baseline The cross-repo binding still bites. Pointed at the previous merged CLI commit it exits 1, so a rename on the CLI side would fail this repository's CI rather than surfacing to an agent at runtime. The check also grew to exercise the new surface, driving the real CLI runner with an injected fetch to produce The evidence boundary is stated honestlyWorth quoting, because it is an unusual thing to volunteer:
So the CLI can poll, the Skill knows how to react, and nothing has ever talked to a real analysis endpoint because one does not exist yet. Saying that plainly in the PR that adds the client is the right call, and it keeps the eval outcomes from reading as proof of a working pipeline. An earlier finding is closedFor the record, since I raised it on #6: the three discovery strings that promised "Create and deploy a Rails app for web, iOS, and Android" now describe what the Skill actually does. That fix is already in Finding: the one status code with opposite advice is not bound
Those two are a matched pair, and cli#8's README gives them deliberately opposite guidance:
The retryable half is verified against the real CLI. The do-not-retry half is documented in The consequence is bounded rather than dangerous, because the Skill's fail-closed rule catches an unrecognized code and stops. But stopping is what it does for any unknown output, so a silently dead branch costs exactly the actionable distinction this design was built to provide: an agent that could have said "the server's response is malformed, retrying will not help" instead says "something unknown happened." The fix is small given what is already there. The check injects |
Lesson: building the client before the server existsThis PR teaches an agent how to wait for an analysis to finish and what to do with each result. There is one detail that makes it interesting: the server endpoint it talks to has not been built. That sounds backwards. It is a real technique, it has real benefits, and it has one failure mode that ruins it if you are not careful. Why anyone would do thisTwo teams need to agree on how a feature works. The usual order is server first, then client, and it has a cost you have probably felt: by the time the client team touches it, the shape is fixed. Every awkwardness in the response is now expensive to change, and you route around it in client code forever. Writing the client first inverts that. You discover what the client actually needs while changing it is still free. Look at what this Skill discovered by trying to use an endpoint nobody has built. It needs the analysis to carry an identity, so a poller can tell "your analysis finished" from "a different analysis finished." It needs a Those are requirements on the server, found by writing the consumer. If the server had shipped first, some of them would have been missing and the client would have papered over the gaps with guesswork. This is the honest version of what people mean by contract-first or API-design-first. Write down the interaction, let both sides build against it, and discover the disagreements early. The failure modeHere is what goes wrong. You write the client. You write tests. The tests pass, because they run against your own idea of what the server will send. Everything is green, and you start believing the feature works. Then the server ships, and it returns Green tests against a fake server tell you your client is self-consistent, not that it is correct. Which is why the sentence in this PR is the most important thing in it:
They wrote down that the proof is partial. Nobody reading those green evals will mistake them for a working pipeline. That costs one sentence and prevents the exact misunderstanding this technique invites. How to do it without lying to yourselfWrite the contract down somewhere both sides read. Not in your client's code. A schema, a shared document, an example response committed where the server team will see it. In this repository the equivalent is a reference document plus a script that checks the real CLI matches it. Say which parts are verified against reality. "Verified against the real CLI" and "verified against a response I made up" are different claims and should not sit in the same list without a label. Plan the day the real thing arrives. The moment the server exists, run the client against it. Not a mock, the actual endpoint. That is when you find out whether the contract survived contact. Fail closed on anything unexpected. Since you are guessing, guess safely. This Skill treats any unrecognized status as "stop and report" rather than assuming it resembles a case it knows. When your assumptions are wrong, and some will be, that turns a wrong action into a halt. The everyday versionYou do not need two teams for this to be useful. Next time you integrate a third-party API, write the client and its tests before wiring it up. You will discover what you actually need from the response, and you will notice the mismatch when you finally call it for real, which is exactly when you can still choose a different provider. Same when you build a UI against an endpoint a colleague is writing. Stub it, build the screen, and you will find the missing field in an afternoon rather than a week after the endpoint is frozen. Just keep a clear line in your head between "my code works against what I imagined" and "my code works." Both are worth having. Only one of them is worth telling other people about. |
A successful import is not enough to establish graph validity. Require the Skill to wait for the current AnalysisRun, branch on domain status, and stop at operational or concurrency boundaries. Pin the merged CLI contract and add fixtures and evals for bounded repair and recovery behavior.
a7acc67 to
2788cae
Compare
|
Resolved in The cross-repository contract check now drives both previously uncovered status paths through the real CLI pinned at
Both cases assert one fetch, byte-identical private state, and absence of the project path, pinned origin, private Proving the shared Verification:
|
Summary
Evidence boundary
This teaches the client-side contract only. The matching First Draft AnalysisRun API is still pending, so valid
server-backed eval outcomes are not yet end-to-end evidence. Compilation remains unavailable.
Verification
sh script/check(13 tests)node script/check-cli-contract.mjs <firstdraft/cli at 74e3d42>Part of firstdraft/firstdraft#133.