Tablet landscape — floating station bar, log rail, wide band #16

Closed
opened 2026-07-29 17:32:07 +00:00 by aiko · 4 comments
Owner

What to build

Card 1c, at 1024×640. The same chrome as mobile with one band added and one changed — collapse by adding/removing bands, not by reflowing.

  • Full-bleed stage; the station bar floats over the top on a gradient rather than sitting in its own row.
  • A 320px log rail on the right, always present, showing the running transmission log.
  • The transmission band moves bottom-left over the free stage width, at a much larger type size capped at 34ch, with wider keys and a right-aligned hands-free/VAD readout.

Design reference: docs/design/denpa-receiver/README.md (card ids 1a, 4a… index into Denpa Receiver.dc.html, openable in a browser).

Acceptance criteria

  • Layout switches on viewport, sharing components with the mobile chrome — no forked implementations
  • Log rail renders live and does not overlap the transmission band
  • Transmission text caps at 34ch
  • Rotating a tablet moves between 1c and the mobile chrome without losing state

Blocked by

## What to build Card 1c, at 1024×640. The same chrome as mobile with one band added and one changed — **collapse by adding/removing bands, not by reflowing**. - Full-bleed stage; the station bar floats over the top on a gradient rather than sitting in its own row. - A 320px **log rail** on the right, always present, showing the running transmission log. - The **transmission band** moves bottom-left over the free stage width, at a much larger type size capped at `34ch`, with wider keys and a right-aligned hands-free/VAD readout. Design reference: `docs/design/denpa-receiver/README.md` (card ids `1a`, `4a`… index into `Denpa Receiver.dc.html`, openable in a browser). ## Acceptance criteria - [ ] Layout switches on viewport, sharing components with the mobile chrome — no forked implementations - [ ] Log rail renders live and does not overlap the transmission band - [ ] Transmission text caps at 34ch - [ ] Rotating a tablet moves between 1c and the mobile chrome without losing state ## Blocked by - #12
Author
Owner

Branch issue/denpa-16-tablet-landscape.

What landed. 1a and 1c are one component set over a plan table. chrome-plan.ts maps a viewport to a ChromePlan — which bands exist, where the keys live, the station bar's placement and meter size, the transmission band's type scale and measure. ReceiverChrome assembles the bands; StationBar, TransmissionBand/KeyRow and LogRail draw them. Nothing is forked per breakpoint: the tablet plan adds rail, drops dock, and moves the keys into the wide band.

  • Station bar floats over a full-bleed stage on a scrim.station gradient at 1c, banded under a hairline on mobile. Callsign 900 14px / .2em, meter 5 bars 4x18 gap 3 at 1s.
  • 320px log rail, a flex column beside the stage rather than a layer over it — message entries plus one-line relay rows, reading ChatHistoryContext's Message[].
  • Transmission band bottom-left over the free stage: Archivo 800 34px/1.2, letter-spacing: -.025em, capped at 34ch, keys 56px with PTT at 230px and the 常時受信 ON · VAD 0.62 / 0.28 readout right-aligned.
  • 記録 LOG is dropped at 1c — the rail already is the log.

Tests (npm test: 81 passed in 10 files, up from 60 in 8; nothing skipped or deleted). 13 cases on the plan: which layout each viewport picks including the rotated 640x1024 tablet and an 800x420 phone on its side, that the band lists differ only by adding and removing bands, the 704px free stage, the 34ch cap, the PTT width, and the hands-free readout formatter. 8 on the render: the rail draws the running log and grows with it, the rail is a sized flex sibling while the band is inside the flex:1 min-width:0 stage column so their boxes cannot overlap, the 34ch/34px body on tablet against 21px uncapped on mobile, and that the four chrome files contain no useState/useRef — which is what makes rotation lossless, since the transmission, log, hands-free state and AI state all arrive as props.

Not verified. I could not render this. Every visual claim above is a reading of the design doc, not an observation of the UI. In particular "the rail does not overlap the band" is established structurally — the band is absolutely positioned inside the stage column, which is the rail's flex sibling — and not by looking at 1024x640. Type sizes, paddings and the scrim gradients are transcribed from § 1c and unchecked against the mock.

Deliberately left out. Nothing mounts ReceiverChrome: #12 owns the App.tsx mount point and was still unmerged, so wiring it here would have ripped out the surviving sidebar/footer and guaranteed a conflict. The useViewport hook ships alongside; the mount is <ReceiverChrome viewport={useViewport()} ... />. Also out: the mobile 記録 log overlay (#12/#17), the unprompted break-in band, the scanline sweep, and the rail's 思考 rows and chain summary from 4a — the rail draws message entries and relay rows only.

Assumed. 1c applies to any landscape viewport at least 900px wide, desktop included, since it is the only card with a rail and "desktop pal = bar only" is a window mode rather than a breakpoint. Both assumptions are in .denpa-work/QUESTIONS.md.

Shared files touched, minimally: carrier-bars.ts gained an optional durationMs so 1c's meter can run at 1s; faceplate-spec.ts gained keyTreatmentStyles so the dock and the wide band cannot disagree about a lit PTT key; denpa-tokens.ts/system.ts gained scrim.*, hairline.rule and two transmission text-shadows rather than local constants.

npm run typecheck reports no errors in any file this branch touches. npm run lint is still broken on main for unrelated reasons.

Branch `issue/denpa-16-tablet-landscape`. **What landed.** 1a and 1c are one component set over a plan table. `chrome-plan.ts` maps a viewport to a `ChromePlan` — which bands exist, where the keys live, the station bar's placement and meter size, the transmission band's type scale and measure. `ReceiverChrome` assembles the bands; `StationBar`, `TransmissionBand`/`KeyRow` and `LogRail` draw them. Nothing is forked per breakpoint: the tablet plan adds `rail`, drops `dock`, and moves the keys into the wide band. - Station bar floats over a full-bleed stage on a `scrim.station` gradient at 1c, banded under a hairline on mobile. Callsign 900 14px / .2em, meter 5 bars 4x18 gap 3 at 1s. - 320px log rail, a flex column beside the stage rather than a layer over it — message entries plus one-line relay rows, reading `ChatHistoryContext`'s `Message[]`. - Transmission band bottom-left over the free stage: Archivo 800 34px/1.2, `letter-spacing: -.025em`, capped at `34ch`, keys 56px with PTT at 230px and the `常時受信 ON · VAD 0.62 / 0.28` readout right-aligned. - 記録 LOG is dropped at 1c — the rail already is the log. **Tests** (`npm test`: 81 passed in 10 files, up from 60 in 8; nothing skipped or deleted). 13 cases on the plan: which layout each viewport picks including the rotated 640x1024 tablet and an 800x420 phone on its side, that the band lists differ only by adding and removing bands, the 704px free stage, the 34ch cap, the PTT width, and the hands-free readout formatter. 8 on the render: the rail draws the running log and grows with it, the rail is a sized flex sibling while the band is inside the `flex:1 min-width:0` stage column so their boxes cannot overlap, the 34ch/34px body on tablet against 21px uncapped on mobile, and that the four chrome files contain no `useState`/`useRef` — which is what makes rotation lossless, since the transmission, log, hands-free state and AI state all arrive as props. **Not verified.** I could not render this. Every visual claim above is a reading of the design doc, not an observation of the UI. In particular "the rail does not overlap the band" is established structurally — the band is absolutely positioned inside the stage column, which is the rail's flex sibling — and not by looking at 1024x640. Type sizes, paddings and the scrim gradients are transcribed from § 1c and unchecked against the mock. **Deliberately left out.** Nothing mounts `ReceiverChrome`: #12 owns the App.tsx mount point and was still unmerged, so wiring it here would have ripped out the surviving sidebar/footer and guaranteed a conflict. The `useViewport` hook ships alongside; the mount is `<ReceiverChrome viewport={useViewport()} ... />`. Also out: the mobile 記録 log overlay (#12/#17), the unprompted break-in band, the scanline sweep, and the rail's 思考 rows and chain summary from 4a — the rail draws message entries and relay rows only. **Assumed.** 1c applies to any landscape viewport at least 900px wide, desktop included, since it is the only card with a rail and "desktop pal = bar only" is a window mode rather than a breakpoint. Both assumptions are in `.denpa-work/QUESTIONS.md`. **Shared files touched, minimally:** `carrier-bars.ts` gained an optional `durationMs` so 1c's meter can run at 1s; `faceplate-spec.ts` gained `keyTreatmentStyles` so the dock and the wide band cannot disagree about a lit PTT key; `denpa-tokens.ts`/`system.ts` gained `scrim.*`, `hairline.rule` and two transmission text-shadows rather than local constants. `npm run typecheck` reports no errors in any file this branch touches. `npm run lint` is still broken on main for unrelated reasons.
Author
Owner

Review-findings pass on issue/denpa-16-tablet-landscape (86913b8).

Addressed

  • blocker — missing 4b relay glyphs. Relay rows now carry the status glyph slot: acid on 完了, magenta on 失敗, and the live cyan mini-meter on 実行中. Under reduced motion the mini-meter holds at a single static half-height bar in signal, per 4b — done through the same pure-motion-plan mechanism #10 used, not a CSS media block. The mini-meter's geometry lives in carrier-bars.ts beside the station/faceplate/pal meters. A row whose status never arrived draws no glyph rather than a it cannot support.
  • hairline opacity. Added hairline.rail at .24 and pointed the rail's border-left at it; the station bar keeps .22.

Skipped, with reason

  • self-triggered agent messages in acid. Design 4a does specify an acid speaker label for a 自発-triggered agent message, but Build status defers all of 自発送信 ("the adapter that carries a pushed turn does not exist yet") and the governing rule is leave it out entirely / building UI that does nothing is not acceptable. ProactiveSpeakContext carries only allowProactiveSpeak / idleSecondsToSpeak / allowButtonTrigger — no per-turn trigger, no per-message attribution — so an isProactive field on Message would have no producer and the acid branch would be dead. faceplate-spec.ts already records the same decision for the 自発 faceplate row. Logged in the questions ledger with the five-line change to make once the trigger exists.
    • One correction: the finding asked for a different body colour on those messages. 4a gives both agent variants the same #f4ecf6 body; only the speaker label differs.

Tests — 5 new assertions, each confirmed red against the pre-fix code (stashed the source, ran, unstashed): the two glyphs and their colours, the running row's meter + empty duration slot, the rail's border token, and both branches of relayMeterBars.

 Test Files  11 passed (11)
      Tests  87 passed (87)

npm run typecheck adds no errors in any touched file (grepped for receiver, theme/, log-rail, carrier-bars, denpa-tokens, system.ts — no hits).

Review-findings pass on `issue/denpa-16-tablet-landscape` (86913b8). **Addressed** - *blocker — missing 4b relay glyphs.* Relay rows now carry the status glyph slot: acid `✓` on 完了, magenta `✕` on 失敗, and the live cyan mini-meter on 実行中. Under reduced motion the mini-meter holds at a single static half-height bar in `signal`, per 4b — done through the same pure-motion-plan mechanism #10 used, not a CSS media block. The mini-meter's geometry lives in `carrier-bars.ts` beside the station/faceplate/pal meters. A row whose `status` never arrived draws no glyph rather than a `✓` it cannot support. - *hairline opacity.* Added `hairline.rail` at `.24` and pointed the rail's `border-left` at it; the station bar keeps `.22`. **Skipped, with reason** - *self-triggered agent messages in acid.* Design 4a does specify an acid speaker label for a 自発-triggered agent message, but Build status defers all of 自発送信 ("the adapter that carries a pushed turn does not exist yet") and the governing rule is *leave it out entirely / building UI that does nothing is not acceptable*. `ProactiveSpeakContext` carries only `allowProactiveSpeak` / `idleSecondsToSpeak` / `allowButtonTrigger` — no per-turn trigger, no per-message attribution — so an `isProactive` field on `Message` would have no producer and the acid branch would be dead. `faceplate-spec.ts` already records the same decision for the 自発 faceplate row. Logged in the questions ledger with the five-line change to make once the trigger exists. - One correction: the finding asked for a different *body* colour on those messages. 4a gives both agent variants the same `#f4ecf6` body; only the speaker label differs. **Tests** — 5 new assertions, each confirmed red against the pre-fix code (stashed the source, ran, unstashed): the two glyphs and their colours, the running row's meter + empty duration slot, the rail's border token, and both branches of `relayMeterBars`. ``` Test Files 11 passed (11) Tests 87 passed (87) ``` `npm run typecheck` adds no errors in any touched file (grepped for `receiver`, `theme/`, `log-rail`, `carrier-bars`, `denpa-tokens`, `system.ts` — no hits).
Author
Owner

Branch: issue/denpa-16-tablet-landscape (pushed, no PR, not merged).

What was built

The 1c tablet-landscape receiver chrome, as components plus a viewport hook — but nothing mounts it (see below). chrome-plan.ts is a pure table mapping a viewport to a layout decision: which layout, whether the log rail is present, and whether the keys live in the dock or in the transmission band. receiver-chrome.tsx renders either the mobile-portrait shape or the 1c shape from that plan; station-bar.tsx, log-rail.tsx and transmission-band.tsx are the pieces. use-viewport.ts reports width/height/orientation. carrier-bars.ts gained relayMeterBars(). denpa-tokens.ts and system.ts gained a hairline.rail colour (rgba(255,45,149,.24)) for the rail's left border; the station bar keeps .22.

The four chrome files contain no useState and no useRef — the chrome is a pure render of props.

Tests

npm test: 11 files, 87 passed.

 Test Files  11 passed (11)
      Tests  87 passed (87)
   Duration  3.16s

npm run typecheck adds no new errors in the paths touched (the 585 pre-existing errors on main are untouched).

Coverage is over the plan table and the emitted markup: which layout each viewport selects, that the rail is present at 1c and absent at mobile, the 704px free-stage arithmetic, that the transmission band sits in a flex:1; min-width:0; position:relative stage column that is the 320px rail's flex sibling, max-width:34ch on the large body, the VAD-threshold formatter's three cases (both thresholds / positive only / omitted entirely when VAD has reported none), and the relay-row status glyphs including the reduced-motion branch. The new log-rail.test.tsx (4 cases) and the relayMeterBars block in carrier-bars.test.ts (2 cases) were confirmed red against the pre-fix source by stashing the four source files and re-running: 5 failures, all in the new assertions.

Visual claims that were never observed rendering

I never rendered any of this. No browser, no .dc.html mock, no device. Every size, padding, gradient and colour is transcribed from docs/design/denpa-receiver/README.md §1a and §1c and cross-checked against the token file. Specifically:

  • "The log rail does not overlap the transmission band" is established structurally only — from the flex shape described above and the 704px arithmetic asserted in the tests. It was not observed at 1024x640.
  • The 34ch cap is asserted as the string max-width:34ch in the emitted markup. No line length was measured.
  • "Rotating between 1c and mobile without losing state" is inferred from the chrome being a pure render of props plus both layouts consuming the same props. No device was rotated.

Anything that depends on how it actually looks needs a human with eyes on it before merge.

Deliberately left out

Nothing mounts ReceiverChrome. #12 (mobile chrome) has not landed on main despite being listed as this issue's blocker — its branch is still at main's tip — and App.tsx still carries the pre-Denpa sidebar/footer layout. Wiring the chrome in would have torn that out and guaranteed a conflict with the sibling working #12, so this branch ships the components and the hook and leaves the mount point to #12 or to the merge. The mount is one line: <ReceiverChrome viewport={useViewport()} ... />.

Also out of scope and absent: the mobile 記録 log overlay, the unprompted break-in band, the scanline sweep, and 4a's 思考 rows and chain summary (the rail draws message entries and one-line relay rows only). Screen-reader and keyboard behaviour was not extended beyond aria-pressed on the hands-free key and the faceplate live region that already existed.

Assumptions

  1. #12 owns the App.tsx mount point for the receiver chrome, so #16 mounts nothing. If wrong, it is a one-line change at the mount point.
  2. The 1c chrome applies to any landscape viewport at least 900px wide, desktop widths included. 1c is the only card with a log rail, and the design's "desktop pal = bar only" reads as a window mode rather than a breakpoint. "Never a fixed-width sidebar" is read as a warning against the rail at narrow widths, which is why the breakpoint also requires landscape. If wrong: a third row in the plan table, or an upper bound on TABLET_LANDSCAPE_MIN_WIDTH.
  3. The dock's controls move into the wide band on tablet, so 1c has no dock band. The plan carries a keys: 'dock' | 'transmission' field rather than duplicating the key definitions.
  4. On mobile the log is reached through 記録 LOG rather than displayed, so rotating from 1c to portrait hides the rail without losing log data. The tests assert the key is present at mobile and absent at 1c.
  5. The rail border gets a new token at .24 as the design specifies, rather than reusing the existing .22 hairline or leaving the mismatch.
  6. Both repo VAD thresholds are 0–1 in the readout. The formatter shows both on 1c, only the positive one on mobile, and omits them entirely rather than printing NaN when VAD has reported none.

Review

No code-review agent ran — this subagent context has no Task/subagent-spawn tool, so that gate is unmet. Assume one pair of eyes on this, not two. I self-reviewed the diff and found four things; three were fixed, one was skipped.

Fixed: the missing 4b relay glyphs (acid ✓ on completed, magenta ✕ on error, live cyan mini-meter on running, with reduced motion collapsing the meter to one static half-height bar in signal via a pure branch of relayMeterBars() rather than a CSS media block, matching #10's useReducedMotion → motion-plan mechanism); the .24 vs .22 hairline mismatch; and a test gap. Also fixed: a relay row's data attribute defaulted an absent status to running, contradicting how the row actually drew — a row whose status never arrived now draws no glyph rather than a ✓ it cannot support.

Skipped — isProactive on Message and acid #eaff3c 自発 speaker labels in the rail. Design 4a does specify an acid speaker label for a 自発-triggered agent message, but the design's own build-status table defers all of 自発送信 ("the adapter that carries a pushed turn does not exist yet"), and the governing rule is "leave it out entirely — no placeholder" / "Building UI that does nothing is not [acceptable]". ProactiveSpeakContext (src/renderer/src/context/proactive-speak-context.tsx) carries only allowProactiveSpeak / idleSecondsToSpeak / allowButtonTrigger — no per-turn trigger and no per-message attribution — so an isProactive field on Message would have no producer and the acid branch would be unreachable dead code. faceplate-spec.ts already records the identical decision for the 自発 faceplate row. The finding also asked for a different body colour; 4a gives both agent variants the same #f4ecf6 body, so only the speaker label would ever change. The exact five-line change to make once the trigger exists is logged in .denpa-work/QUESTIONS.md.

Branch: `issue/denpa-16-tablet-landscape` (pushed, no PR, not merged). ## What was built The 1c tablet-landscape receiver chrome, as components plus a viewport hook — but nothing mounts it (see below). `chrome-plan.ts` is a pure table mapping a viewport to a layout decision: which layout, whether the log rail is present, and whether the keys live in the dock or in the transmission band. `receiver-chrome.tsx` renders either the mobile-portrait shape or the 1c shape from that plan; `station-bar.tsx`, `log-rail.tsx` and `transmission-band.tsx` are the pieces. `use-viewport.ts` reports width/height/orientation. `carrier-bars.ts` gained `relayMeterBars()`. `denpa-tokens.ts` and `system.ts` gained a `hairline.rail` colour (`rgba(255,45,149,.24)`) for the rail's left border; the station bar keeps `.22`. The four chrome files contain no `useState` and no `useRef` — the chrome is a pure render of props. ## Tests `npm test`: 11 files, 87 passed. ``` Test Files 11 passed (11) Tests 87 passed (87) Duration 3.16s ``` `npm run typecheck` adds no new errors in the paths touched (the 585 pre-existing errors on `main` are untouched). Coverage is over the plan table and the emitted markup: which layout each viewport selects, that the rail is present at 1c and absent at mobile, the 704px free-stage arithmetic, that the transmission band sits in a `flex:1; min-width:0; position:relative` stage column that is the 320px rail's flex sibling, `max-width:34ch` on the large body, the VAD-threshold formatter's three cases (both thresholds / positive only / omitted entirely when VAD has reported none), and the relay-row status glyphs including the reduced-motion branch. The new `log-rail.test.tsx` (4 cases) and the `relayMeterBars` block in `carrier-bars.test.ts` (2 cases) were confirmed red against the pre-fix source by stashing the four source files and re-running: 5 failures, all in the new assertions. ## Visual claims that were never observed rendering I never rendered any of this. No browser, no `.dc.html` mock, no device. Every size, padding, gradient and colour is transcribed from `docs/design/denpa-receiver/README.md` §1a and §1c and cross-checked against the token file. Specifically: - **"The log rail does not overlap the transmission band"** is established structurally only — from the flex shape described above and the 704px arithmetic asserted in the tests. It was not observed at 1024x640. - **The 34ch cap** is asserted as the string `max-width:34ch` in the emitted markup. No line length was measured. - **"Rotating between 1c and mobile without losing state"** is inferred from the chrome being a pure render of props plus both layouts consuming the same props. No device was rotated. Anything that depends on how it actually looks needs a human with eyes on it before merge. ## Deliberately left out **Nothing mounts `ReceiverChrome`.** #12 (mobile chrome) has not landed on `main` despite being listed as this issue's blocker — its branch is still at `main`'s tip — and `App.tsx` still carries the pre-Denpa sidebar/footer layout. Wiring the chrome in would have torn that out and guaranteed a conflict with the sibling working #12, so this branch ships the components and the hook and leaves the mount point to #12 or to the merge. The mount is one line: `<ReceiverChrome viewport={useViewport()} ... />`. Also out of scope and absent: the mobile 記録 log overlay, the unprompted break-in band, the scanline sweep, and 4a's 思考 rows and chain summary (the rail draws message entries and one-line relay rows only). Screen-reader and keyboard behaviour was not extended beyond `aria-pressed` on the hands-free key and the faceplate live region that already existed. ## Assumptions 1. **#12 owns the `App.tsx` mount point** for the receiver chrome, so #16 mounts nothing. If wrong, it is a one-line change at the mount point. 2. **The 1c chrome applies to any landscape viewport at least 900px wide, desktop widths included.** 1c is the only card with a log rail, and the design's "desktop pal = bar only" reads as a window mode rather than a breakpoint. "Never a fixed-width sidebar" is read as a warning against the rail at narrow widths, which is why the breakpoint also requires landscape. If wrong: a third row in the plan table, or an upper bound on `TABLET_LANDSCAPE_MIN_WIDTH`. 3. **The dock's controls move into the wide band on tablet**, so 1c has no dock band. The plan carries a `keys: 'dock' | 'transmission'` field rather than duplicating the key definitions. 4. **On mobile the log is reached through 記録 LOG rather than displayed**, so rotating from 1c to portrait hides the rail without losing log data. The tests assert the key is present at mobile and absent at 1c. 5. **The rail border gets a new token at `.24`** as the design specifies, rather than reusing the existing `.22` hairline or leaving the mismatch. 6. **Both repo VAD thresholds are 0–1 in the readout.** The formatter shows both on 1c, only the positive one on mobile, and omits them entirely rather than printing `NaN` when VAD has reported none. ## Review **No code-review agent ran** — this subagent context has no Task/subagent-spawn tool, so that gate is unmet. Assume one pair of eyes on this, not two. I self-reviewed the diff and found four things; three were fixed, one was skipped. Fixed: the missing 4b relay glyphs (acid ✓ on completed, magenta ✕ on error, live cyan mini-meter on running, with reduced motion collapsing the meter to one static half-height bar in `signal` via a pure branch of `relayMeterBars()` rather than a CSS media block, matching #10's `useReducedMotion` → motion-plan mechanism); the `.24` vs `.22` hairline mismatch; and a test gap. Also fixed: a relay row's data attribute defaulted an absent status to `running`, contradicting how the row actually drew — a row whose status never arrived now draws no glyph rather than a ✓ it cannot support. **Skipped — `isProactive` on `Message` and acid `#eaff3c` 自発 speaker labels in the rail.** Design 4a does specify an acid speaker label for a 自発-triggered agent message, but the design's own build-status table defers all of 自発送信 ("the adapter that carries a pushed turn does not exist yet"), and the governing rule is "leave it out entirely — no placeholder" / "Building UI that does nothing is not [acceptable]". `ProactiveSpeakContext` (`src/renderer/src/context/proactive-speak-context.tsx`) carries only `allowProactiveSpeak` / `idleSecondsToSpeak` / `allowButtonTrigger` — no per-turn trigger and no per-message attribution — so an `isProactive` field on `Message` would have no producer and the acid branch would be unreachable dead code. `faceplate-spec.ts` already records the identical decision for the 自発 faceplate row. The finding also asked for a different *body* colour; 4a gives both agent variants the same `#f4ecf6` body, so only the speaker label would ever change. The exact five-line change to make once the trigger exists is logged in `.denpa-work/QUESTIONS.md`.
Author
Owner

Shipped. Merged to main at d73f4ed (phase B2i — client chrome integration).

Closed as part of reconciling the board with main: the autonomous run's policy was not to auto-close, so shipped work stayed open and the tracker read as though nothing had landed. That policy is now reversed — issues close when they land.

Shipped. Merged to `main` at [`d73f4ed`](https://git.aiko.works/aiko/denpa/commit/d73f4ed) (phase B2i — client chrome integration). Closed as part of reconciling the board with `main`: the autonomous run's policy was not to auto-close, so shipped work stayed open and the tracker read as though nothing had landed. That policy is now reversed — issues close when they land.
aiko closed this issue 2026-07-30 13:32:53 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiko/denpa#16
No description provided.