AI SDD ยท Episode 4

Query the specs and code

Once the spec and the code live side by side, they stop being static documents and become something you can interrogate โ€” ask a question in plain language and get an answer grounded in the real project.

๐Ÿง  Methodology: AI SDDยท ๐Ÿ”Ž Querying specs & codeยท โ™Ÿ๏ธ ChessGame ยท F0003
Part 1 โ€” Asking the specification

Asking the specification

A finished feature isn't only working software โ€” it's a written specification sitting right next to the code. The /query-specs command reads that spec and answers questions about it in plain language. Here are two real questions about how pawn promotion works for Black โ€” the answers are reproduced verbatim.

/query-specs tell me if the promotion system is implemented for Blacks

I'll check the specs for how pawn promotion is handled for Black.

Searched promot|promo

Yes โ€” promotion is implemented for Black. When Stockfish (playing Black) advances a pawn to the final rank, the app applies the promotion the engine chose: the pawn is replaced by whatever piece Stockfish promoted it to (queen, rook, bishop, or knight).

This is the one case where promotion actually works today, precisely because the engine decides for Black โ€” there's nothing for a human to pick, so the app just carries out the engine's choice.

In plain terms:

  • A Black pawn reaching the last rank in Stockfish's reply is promoted automatically, to the piece the engine selected (rule B-6a).
  • The counterpart โ€” White-side (the human player's) promotion โ€” is not implemented, and neither is a manual "choose your promotion piece" prompt; both are explicitly deferred (Out-of-scope note, building on F0002's general deferral of promotion).
  • Note the asymmetry: because Stockfish always names the promotion piece, Black promotion needs no chooser and works end to end; a human pushing a White pawn to the last rank has no way to promote yet.

Feature: F0003 โ€” play-with-stockfish โ†’ F0003.md โ†’ rule B-6a (and the Full pawn promotion item in Out of scope), extending F0002 โ€” move-a-piece, which first deferred promotion.

/query-specs this rules B-6a, is it fisher server feature (replace the pawn with another piece) with a choice of the piece given by the FS server?

Good question โ€” let me split the two parts, because the premise is half right.

Yes, it happens on the fisher-server side โ€” but the piece is chosen by Stockfish, not by fisher-server.

Rule B-6a is a fisher-server action in the sense that the fisher-server is the one that actually replaces the pawn on its stored board. But it does not decide which piece to promote to. That choice comes entirely from the Stockfish engine: when the engine plays a promoting move for Black, its reply already names the promotion piece (e.g. "promote to a queen"), and fisher-server simply reads that instruction and carries it out on the board.

In plain terms:

  • Stockfish returns Black's move, and if it's a promotion the move itself carries the chosen piece (queen, rook, bishop, or knight) โ€” the engine picks it (rule B-5, the move parsing).
  • fisher-server then applies that: it removes the pawn from the board and puts the engine's chosen piece in its place (rule B-6a).
  • So there's no independent "piece choice" made by fisher-server, and no chooser shown to anyone โ€” fisher-server is just the executor of the engine's decision. (A human/White-side promotion, where someone would need to pick, is still out of scope.)

Feature: F0003 โ€” play-with-stockfish โ†’ F0003.md โ†’ rule B-6a (with rule B-5 for where the engine's promotion choice comes from).

Part 2 โ€” Down to the code lines

Down to the code lines

The spec captures the intent; sometimes you want the exact lines that carry it out. Ask in plain English and the assistant walks straight to the Rust that implements the rule โ€” file, line number, and the code itself.

tell me the code lines where rust interprets the stockfish response to process the promotion (rule B6a)

Searched promo|from_promo|Piece::black|nth\(4\)

Here are the exact Rust lines that interpret Stockfish's reply and carry out the promotion (rule B-6a). It happens in three steps across two files:

1. Read the promotion letter from the engine's UCI move โ€” parse_uci takes the optional 5th character of the bestmove string (e.g. a2a1q โ†’ q) and turns it into a piece kind:

  • fisher-server/src/engine/mod.rs:145
    let promo = s.chars().nth(4).and_then(Kind::from_promo);

    (stored on the parsed move at fisher-server/src/engine/mod.rs:134 โ€” pub promo: Option<Kind>)

2. Translate that letter into a piece kind โ€” Kind::from_promo maps q/r/b/n โ†’ Queen/Rook/Bishop/Knight:

  • fisher-server/src/game/piece.rs:31 โ€” pub fn from_promo(c: char) -> Option<Kind>

3. Replace the pawn on the board โ€” apply_black_move puts the promoted Black piece on the target square instead of the pawn:

  • fisher-server/src/engine/mod.rs:156
    if let Some(kind) = uci.promo {
        // The promoted piece is always Black (this module only plays Black).
        next[uci.to.row][uci.to.col] = Some(Piece::black(kind));
    }

    where Piece::black(kind) (defined at fisher-server/src/game/piece.rs:76) builds the Black piece of that kind.

In short: the choice of piece is decoded from Stockfish's move at mod.rs:145 (via Kind::from_promo), and the board is actually updated at mod.rs:156โ€“158. The behaviour is pinned by the unit test apply_black_move_records_capture_and_promotion (fisher-server/src/engine/mod.rs:492), which asserts a a2a1q reply promotes to a black queen.

The specs answer back. Same knowledge base, two altitudes: /query-specs reads the written rules, and a plain code question walks straight to the lines that implement them โ€” spec and code kept in sync, so both stay trustworthy and their answers agree.
Conclusion

Why AI SDD works

Four episodes in, the pattern is clear. Spec-Driven Development isn't just a nice way to start a feature โ€” it changes what the whole project is. The specification stops being documentation that rots and becomes the thing everything else is measured against.

Spec first, always. AI implements, humans decide โ€” and because the specification stays the source of truth, the code, the tests and the logs all stay honest to it. That's what makes an AI-built system you can actually trust.