The wave-3 loss was caused by sprite auto-suspend, not nohup process-group semantics. /.sprite/llm.txt: 'When idle, sprites pause automatically. Services and sessions keep sprites alive.' Detached processes are on neither list, so setsid is necessary but not sufficient. tasks/wave-guard.sh holds a /v1/tasks lease (max 3600s, renewal is DELETE+POST since re-POST returns 409), renews every 15 min while workers run, writes logs/WAVE<N>-DONE, then releases the lease so the sprite can suspend rather than idle hot. Also documents hazard #6 (pgrep -f / pkill -f matching the orchestrator's own shell) and adds the wave-3 worker prompts and shared screen contract. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
110 lines
5.4 KiB
Plaintext
110 lines
5.4 KiB
Plaintext
You are Worker E1 on the Bookshelf project (~/bookshelf). Wave 3, part 1:
|
|
APP SHELL + SETUP + LOCATIONS + SETTINGS screens.
|
|
|
|
FIRST, READ THESE — the contract. Follow exactly; do not invent alternative names,
|
|
do not restate them back to me:
|
|
~/bookshelf/docs/SPEC.md (authoritative — see "Screens", "Design language")
|
|
~/bookshelf/docs/HANDOFF.md (operational state, gotchas already paid for)
|
|
|
|
Waves 1-2 are DONE and verified green: theme + shared components (ui.theme,
|
|
ui.components), the whole data layer (data.local/remote/repo/prefs, AppContainer),
|
|
and metadata/scanning plumbing. REUSE them. Read `AppContainer.kt` and the repository
|
|
classes to learn the real API before you write anything against them.
|
|
|
|
## Your scope
|
|
ui.nav Routes.kt + BookshelfNavHost — the whole navigation graph, including
|
|
routes to E2's screens (see the contract block below)
|
|
ui.setup SetupScreen: server URL (https validation, trailing-slash strip,
|
|
reachability probe), email, password. MUST distinguish "bad/unreachable
|
|
URL" from "bad credentials" in its error text — SPEC calls this out.
|
|
ui.locations LocationsScreen: bookcases -> shelves tree, CRUD + reorder, book counts
|
|
per shelf, tap-a-shelf -> library filtered to it, "Move books" bulk action.
|
|
ui.settings SettingsScreen: server, account, sign out, manual sync + last-sync time,
|
|
book/cover counts.
|
|
MainActivity: host BookshelfNavHost, pick the start route (setup vs library) based
|
|
on whether a server URL + auth token already exist.
|
|
|
|
## HARD BOUNDARIES — Worker E2 is running RIGHT NOW in this same repo
|
|
- DO NOT create or edit anything under ui.library, ui.detail, ui.scan. E2 owns those.
|
|
You WILL reference E2's screen composables from BookshelfNavHost — that is expected;
|
|
use exactly the signatures in the contract block and do not open those files.
|
|
- DO NOT edit ui.theme or ui.components (wave 1B, verified green). Reuse, don't modify.
|
|
- DO NOT edit `app/build.gradle.kts` or `gradle/libs.versions.toml`. Everything needed
|
|
is already declared and wired. If you think something is missing, report it, do not add it.
|
|
- Data layer: you MAY extend LocationRepository / ShelfDao / BookcaseDao (e.g. reorder,
|
|
bulk-move helpers) if a screen genuinely needs it. You may NOT touch BookRepository or
|
|
BookDao — E2 owns those. If you need a book-side query, report it instead.
|
|
|
|
## SHARED SCREEN CONTRACT — fixed by the orchestrator, IDENTICAL in both wave-3
|
|
## prompts. Do NOT change these signatures. E1 writes BookshelfNavHost against them;
|
|
## E2 writes the screens to match. If you deviate, the other worker's code stops
|
|
## compiling and the wave fails.
|
|
|
|
Routes (string constants live in ui/nav/Routes.kt, owned by E1):
|
|
"setup" | "library" | "library?shelfId={shelfId}" | "detail/{bookId}" |
|
|
"scan" | "locations" | "settings"
|
|
|
|
Screen composable signatures:
|
|
|
|
// E2 owns
|
|
@Composable fun LibraryScreen(
|
|
shelfIdFilter: String?,
|
|
onBookClick: (String) -> Unit,
|
|
onScanClick: () -> Unit,
|
|
onLocationsClick: () -> Unit,
|
|
onSettingsClick: () -> Unit,
|
|
container: AppContainer,
|
|
)
|
|
@Composable fun DetailScreen(
|
|
bookId: String,
|
|
onBack: () -> Unit,
|
|
container: AppContainer,
|
|
)
|
|
@Composable fun ScanScreen(
|
|
onBack: () -> Unit,
|
|
container: AppContainer,
|
|
)
|
|
|
|
// E1 owns
|
|
@Composable fun SetupScreen(onSetupComplete: () -> Unit, container: AppContainer)
|
|
@Composable fun LocationsScreen(
|
|
onBack: () -> Unit,
|
|
onShelfClick: (String) -> Unit, // navigates to library?shelfId=...
|
|
container: AppContainer,
|
|
)
|
|
@Composable fun SettingsScreen(
|
|
onBack: () -> Unit,
|
|
onSignedOut: () -> Unit, // navigates back to "setup"
|
|
container: AppContainer,
|
|
)
|
|
|
|
All screens take `container: AppContainer` and construct their own ViewModel from it
|
|
(manual DI per SPEC — NO Hilt). Package = ui.<screen>, e.g. ui.library.LibraryScreen.
|
|
|
|
## Build/verify — CRITICAL
|
|
Never run `./gradlew`; E2 builds concurrently and you will corrupt each other's build.
|
|
ALWAYS use the serialized wrapper (it takes a lock and may block — wait for it):
|
|
~/bookshelf/tasks/gw assembleDebug
|
|
~/bookshelf/tasks/gw testDebugUnitTest
|
|
|
|
## Definition of done — verified by YOU, actually run, not assumed
|
|
1. `~/bookshelf/tasks/gw assembleDebug` exits 0.
|
|
2. `~/bookshelf/tasks/gw testDebugUnitTest` exits 0 with ZERO failures. There are 68
|
|
existing passing tests — you must not break any of them.
|
|
3. The app must behave per SPEC with NO server configured (lands on setup) and must not
|
|
crash when the server is unreachable. Sync failure = a quiet status line, never a
|
|
crash or a blocking dialog.
|
|
4. Every screen uses the wave-1B theme and components. Warm paper / mahogany / gold,
|
|
Literata for titles. Do not introduce new colors or a second type scale.
|
|
|
|
## IMPORTANT — do not repeat Worker D's mistake
|
|
A previous worker ended its turn saying "tests are running in the background, I'll
|
|
report when done." That is a FAILURE. Run the commands, WAIT for them, and report real
|
|
exit codes you actually observed. A truthfully reported gap is worth more than a false
|
|
green; an unverified claim is worth less than nothing.
|
|
|
|
## Report back (short — read by a token-constrained orchestrator)
|
|
- real exit codes of the two gradle commands, and the test failure count
|
|
- files created, one line each
|
|
- anything in SPEC.md you could NOT satisfy, and why
|