Commit Graph
7 Commits
Author SHA1 Message Date
rzen cdc91d669d The embedded guide catches up on its own — creation-time parity for both apps, an open-time refresh for the phone
The card's frozen spec recommended Option C (install the agent guide at
board creation); the owner's follow-up comment extended that ruling to a
second axis — embedded guidelines should update whenever a board opens if
the on-disk version is older than Lanework's, which the Mac app already
does via BoardStore.refreshAgentGuide()/runScheduledHeals(). This card
implements both halves.

- BoardWriter.createBoard now calls AgentGuide.install(atBoardRoot:)
  right after seedGitignoreIfAbsent, so every board — Mac- or
  phone-created, since KanbanMobile.BoardIndexStore.createBoard calls
  this same method — is born with a current-version CLAUDE.md, with no
  dependency on a later open. Routed through AgentGuide.install itself
  rather than a hand-rolled write, so never-downgrade, the
  CLAUDE.user.md rescue, squatter displacement, and the EchoLedger
  heal-attribution exclusion all carry over unchanged.

- BoardSession (KanbanMobile) gains a private refreshAgentGuideOnce(),
  fired once from open() (already idempotent on the .idle phase),
  fire-and-forget through the same CoordinatedFileAccess.write bracket
  every phone write uses. Deliberately not a heal scheduler — a
  one-shot courtesy check at session open, silent on failure (logged,
  never surfaced to lastError or a banner), matching AgentGuide's own
  "nothing here is a user-facing event" posture. The type's doc comment
  now names this one exception while keeping "no heal scheduler" true.

- project.yml: lifted the KanbanMobile target's AgentGuide.swift build
  exclusion (dating to the original mobile MVP, "agents work where the
  Mac app runs") — both changes above fail to compile on the phone
  without it, since the type simply wasn't in that module. Verified
  safe: AgentGuide.swift imports only Foundation, and its one upward
  dependency touches only EchoLedger's unconditional recording API,
  never the #if os(macOS)-gated consumer surfaces.

Tests: KanbanTests/BoardWriterTests.swift gains
createBoardInstallsTheCurrentAgentGuide, calling createBoard directly
and asserting the guide lands at AgentGuide.version immediately — the
card's own Done-when, and also the phone's creation-time coverage since
it's the same call site. KanbanMobileUITests/AgentGuideUITests.swift
covers the open-time refresh itself, the one piece only reachable
end-to-end from a running KanbanMobile process (no mobile unit-test
target exists): the bundle's fixture board already carries no
CLAUDE.md, so tapping into it and polling disk proves the wiring with
no fixture changes needed.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-08 22:22:02 -04:00
rzen 78c32776d4 The phone reads the thread — comments arrive on the card's read view, posting and editing behind transactional sheets
The comment thread renders read-only under the card's body (author line, Markdown body through CardBodyView, read-only paperclip rows), read outside the snapshot and re-read on every walk landing via BoardSession.snapshotGeneration. Add Comment posts through the Mac composer's own draft-then-rename bracket — seeding from the card's single synced draft so a thought started on the Mac finishes here — and each row's context menu opens the same sheet in edit mode. Both commit on their trailing button or not at all: the phone's transactional model, dirty-Cancel confirmation and swipe-dismiss disabled while dirty included. UI-tested end to end with disk assertions.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-08-08 18:18:56 -04:00
rzen c4591ead2c Cards open to be read — the mobile detail screen turns read-only, editing moves behind a transactional Save
CardDetailScreen renders title, inline-Markdown body, and a quiet dates
footer; all writing moves to the new CardEditScreen, a full-screen cover
with segmented Details/Body panes. Drafts commit in one perform bracket
on Save only — Cancel guards dirty drafts with a discard confirmation,
and a failed write keeps the sheet and its drafts and raises an alert
instead of dismissing. CardAttributesSection becomes a pure
binding-driven editor with no write path of its own. The UI test walk
crosses the new split, with body-pane and discard coverage, and a
deterministic replaceAllText helper retires the flaky ⌘A select-all.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-08-08 14:47:50 -04:00
rzen 871083e5ca The tab bar retires — boards are the app, settings behind the gear, recency the default order
The boards stack becomes the root screen: Settings moves from its own
tab to a sheet behind a leading gearshape button, the sort pickers trade
their text segments for symbols (hand.draw, textformat.abc, clock) with
the words kept for accessibility, and every list now opens sorted by
most recent change. UI tests re-aimed at the gear button and Done-button
scoping fixed for the sheet-over-sheet nav bars — 4/4 green in the
simulator.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-08-08 13:07:44 -04:00
rzen adbc5ddd89 Backup bows out of the phone — the zipped-share future replaces it, later
IndieBackup comes out whole: the package, the Backup directory, the Settings section, the .kanbanbackup document type and its onOpenURL restore path. Settings is now the About section alone. The Files-app keys stay — they serve local-board visibility, not backups. Board sharing as a zipped archive is the planned replacement and is deliberately not started here.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-08-08 11:25:53 -04:00
rzen 1c16bb4c38 The board chooses where it lives — swipe-open settings move it between iCloud and this iPhone
A trailing swipe on a board row opens Board Settings, whose first setting is location: iCloud or Local, with a confirmed move to the other side — destructive-styled only outbound, because leaving iCloud is the direction that sheds protection. The move is setUbiquitous against the real container and a coordinated move under the DEBUG stand-in; evacuation sweeps materialization first and refuses honestly while content is still downloading. The local home is the sandbox Documents folder, published to the Files app, so a local board is still a folder the user owns.

With a second home the iCloud wall softens (user-ruled 2026-08-08): the index always reaches ready, cloud unavailability becomes an inline notice with a retry, creates land locally when there is no account, and LANEWORK_FORCE_NO_ICLOUD makes that state reproducible in tests regardless of the machine's sign-in. Known gap, now user-reachable: backup remains iCloud-only, so local boards sit outside it.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-08-08 10:56:39 -04:00
rzen ce8a446658 The phone gets its first witnesses — KanbanMobileUITests drive the MVP against a fixture board
The mobile app's first runtime coverage, and its first runtime, full stop: the suite launches the real app over a scratch directory seeded from rich-board.kanban via LANEWORK_LOCAL_ROOT, walks boards to lanes to cards to the card editor, retitles a card and polls the frontmatter on disk until the write lands, then taps through the Settings About section to see the changelog and license actually render. No iCloud account, no metadata query — the DEBUG override is the whole harness.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-08-08 10:22:11 -04:00