Repository navigation
feat: the delivery board projection and the red-pipeline report, plus a CI false-green fix - #14
Merged
Merged
Conversation
…the pull request
The black-box chain reports a RED pipeline by opening ONE issue and commenting on
the pull request (ADR-037), and the engine already does both through the optional
`openIssue`/`commentOnPullRequest` seam. The GitHub adapter did not implement
either, so a real run against GitHub said the honest thing — 'issue: not opened
(the provider cannot record issues)' — and a red pipeline could only name its
failure in the step summary.
- `openIssue` POSTs /repos/{owner}/{repo}/issues and returns the host's number/url.
Labels are NAMES here (GitHub takes names directly, unlike Forgejo's ids).
- `commentOnPullRequest` POSTs the ISSUE-comment endpoint under the pull request's
number, because a pull request IS an issue on GitHub's API.
- Both refuse an empty title/number BEFORE any request, and both fail closed
through the transport when there is no token and no injected seam.
5 tests: the endpoint each call actually hits, the identity returned, the
pre-request refusals, and the no-transport failure. 19/19 in the package.
ci_config generated a tests job that ran the delivered project's command through a pipe (bash run-tests.sh 2>&1 | tail -60) so the log stays readable. GitHub runs a run: block with bash -e, which does NOT set pipefail, so the pipeline's exit status was tail's — always 0 — and a FAILING suite read GREEN. Found live: a deliberately-red delivery passed CI. The generated job now emits 'set -o pipefail' in front of the command (renderCiJobScript), for the tests AND deliverable jobs and for every dialect, keeping the tail. It is emitted unconditionally rather than sniffed for: a guard that depends on recognising the shape goes blind the day the shape changes. RED-then-GREEN: packages/core/src/test/ci-config-step.test.ts runs the GENERATED script through 'bash -e' (the shell the host uses) — a failing delivered suite must exit non-zero, a passing one zero, asserted for github, forgejo and gitlab. docs/bugs-fixed.md #49.
The board-projection port: where a black-box run writes its progress for a HUMAN to read. It is its own port, not ctx.board: TaskBoardProvider — a delivery run has no work to find or claim, so handing it one would hand it a capability it must not use. Write-only by construction (ADR-017 rule 1): no read, no claim, no state record, no comment. Injected like ctx.delivery, never discovered; a run with no board projects nowhere and that is not an error. One delivery = one row, keyed by the run id: a re-run UPDATES the row it wrote rather than filing a second. The engine moves it with the pipeline — publish -> claimed, green await_checks -> pr_open (+ takumi-approved), red await_checks -> fix_needed (+ takumi-blocked), merge -> merged (+ takumi-merged, the landed SHA in the detail). A projection failure is LOUD and NEVER FATAL (ADR-017 rule 2): a decorative board must not be able to un-accept a delivery the pipeline, the judge and the host already accepted. The Notion adapter is the first implementation: one row per run keyed by core's create marker (renderCreateMarker/createKeyOf), labels unioned (additive, nothing an earlier step set is cleared), the reader-facing detail in the 'Takumi State' rich_text property, and the Status column's type (select vs status) learned from the database before writing. Tests drive the REAL engine (packages/core/src/test/delivery-board-step.test.ts) and a real in-memory Notion (boards/notion/src/test/notion-delivery-board.test.ts). Two fixture bugs in the latter are fixed here so the suite is green: the simulator keyed its routes on a dashed UUID that normalizeDatabaseId strips, and its read helper ignored the select/status shape the adapter writes to Status.
The engine's board projection was only ever set by a caller writing code — the same gap delivery-command.ts closed for ctx.delivery. Without this a configured black-box run projects nowhere and nothing in a transcript says why, because the engine's own rule is that a run with no board port projects nowhere and that is not an error. The 'board:' section of takumi.yaml names the DELIVERY board (the write-only row a human reads), NOT the task board — that is the pilot: section's business. It mirrors delivery-command.ts: a per-provider lazy import, a per-provider option list, and a refusal of any option nobody would read (a key the factory drops and a typo are the same silent defect). A credential is never accepted from configuration: the token comes from the environment (NOTION_TOKEN). An invalid section is refused up front, before a run spends its work. Tests (apps/cli/src/test/board-projection.test.ts) pin the section builder and the option rules: a section with no provider, an unknown provider named with the list, a near-miss key refused with the keys the adapter reads, a credential and a code-only option refused with the reason, and the notion section built from its documented options.
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.
What this is
Three things, in the order they landed. The CI defect was fixed first because a false green in CI is the worst kind of defect this project can ship.
fix(core): a generated pipeline fails when the delivered tests fail — the CI false-green.feat(core): the delivery board projection (ADR-044) — one row per delivery run.feat(cli): theboard:section — the delivery board reachable fromtakumi.yaml.1. The false green in the generated CI workflow (fixed first)
ci_configgenerates the delivery's OWN pipeline. Itstestsjob ran the delivered project's test command through a pipe —bash run-tests.sh 2>&1 | tail -60— so the log stays readable. GitHub runs arun:block withbash -e, which does not setpipefail, so the pipeline's exit status wastail's (always 0): a FAILING suite read GREEN. It was found live, because a deliberately-red delivery passed.The generated job now emits
set -o pipefailin front of the command (renderCiJobScript), for the tests and deliverable jobs and for every dialect, keeping the tail. It is emitted unconditionally rather than sniffed for: a guard that depends on recognising the shape goes blind the day the shape changes.RED-then-GREEN (
packages/core/src/test/ci-config-step.test.tsruns the GENERATED script throughbash -e, the shell the host uses):not ok 29 - … a FAILING delivered suite must fail the generated github tests job, not read GREEN (got 0)github,forgejoandgitlab.Ledger:
docs/bugs-fixed.md#49.2. The delivery board projection (ADR-044)
renderCreateMarker/createKeyOf): a re-run UPDATES the row it wrote rather than filing a second one.Statusfollows the pipeline:publish → claimed; greenawait_checks → pr_open(+takumi-approved); redawait_checks → fix_needed(+takumi-blocked);merge → merged(+takumi-merged).Takumi State(rich_text): the reader-facing line — which step moved the row, the pull request, the landed SHA.3. Real evidence
Red-pipeline report path — one issue + one PR comment per run, read back from
sscodeai/takumi-delivery-demo:takumi: red-pipeline-proof(headtakumi/red-proof2-20261011T103055Z, open): takumi: red-pipeline-proof takumi-delivery-demo#4Pipeline not green on pull request 4: 2 check(s): Pipeline not green on pull request 4: 2 check(s) takumi-delivery-demo#6Both bodies name
await_checks FAILED: 2 check(s) FAILED on 4with the two failingtestscheck URLs; the head's check runs aredeliverable: successandtests: failure×2.Notion rows (delivery board):
3f6c1a02-53fb-81ff-…— red…-8107-…— green…-8164-…— idempotency (a re-run updated the same row; no second row)Suite
pnpm -r build— greenpnpm test— 934 tests, 931 pass, 0 fail, 3 skippedpnpm typecheck— green(Note: two fixture bugs in the new Notion delivery-board test are fixed in the board commit so the suite is green — the simulator keyed its routes on a dashed UUID that
normalizeDatabaseIdstrips, and its read helper ignored theselect/statusshape the adapter writes toStatus.)