# MANIFEST: ReadingList
updated: 2026-08-15T17:17:11+00:00
state: approved
blocks: 10
planning_feedback: |
  analyze-display_name applied ARCHITECTURE.md
  analyze-short_description applied ARCHITECTURE.md
applied: ARCHITECTURE.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,ARCHITECTURE_compact.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,DATABASE.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,DATABASE_compact.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,FEATURE-Book-Creation.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,FEATURE-Book-Removal.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,FEATURE-Incomplete-Submission.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,FEATURE-Ordered-List.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,FEATURE-Test-Suite.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,SCREEN-Reading-List.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,UI-GENERAL.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,changes/TICKET-001-Mark-Book-Read.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,changes/TICKET-002-Mark-Book-Read.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,flask.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,persistence.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,python.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4,sqlite.md=4d3bb927bfd3a4c7bc31b51fa27713be9ae48cd4
applied_specs: |
  ARCHITECTURE.md sha256=c42125d1c9a4d632e46f7b88523442ceb51348a2893aa1bb01dcd7b11bbd892b commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-1 applied_at=2026-08-15T17:21:14+00:00 build_sha256=224e24fd544c5535815aa7e2ba8674b0b7572543ece9730dcc8e5545c37616e5
  ARCHITECTURE_compact.md sha256=c2f8604d6ead6b4043cf1560e2365be0c2cea0a441650051f06dc87e46267f9f commit=- applied_by=block-9 applied_at=2026-08-15T17:35:50+00:00 build_sha256=c2f8604d6ead6b4043cf1560e2365be0c2cea0a441650051f06dc87e46267f9f
  DATABASE.md sha256=78e782f3b44cbf8f06bf8af3062dfbc659139e71f0edda468bbe62514cb03467 commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-2 applied_at=2026-08-15T17:23:36+00:00 build_sha256=c0de90e008dcbd98092ec02a29a0ecf4a8b10d22ee92bce38d3f3be76cfaa9fc
  DATABASE_compact.md sha256=90b6fbe98b22f968b82c16866294b215f4dde921aa5fb592edce96692d2d4fb2 commit=c35d4315ac552d6edf20fc01b168daa120b79d8c applied_by=block-10 applied_at=2026-08-15T17:38:45+00:00 build_sha256=90b6fbe98b22f968b82c16866294b215f4dde921aa5fb592edce96692d2d4fb2
  FEATURE-Book-Creation.md sha256=2bdc2bd440ce66e5d39b75577beca1e647556e065db5085f0abf49d6182760e3 commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-4 applied_at=2026-08-15T17:27:25+00:00 build_sha256=284f68392c8bc02ae14a050d7e2605886ce99b102b83a0bd7b077ed6ea16ee69
  FEATURE-Book-Removal.md sha256=6f98c32605ce108d1e29e99d39bae49eb6823e5825b2d2f90319a3c8321a2939 commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-6 applied_at=2026-08-15T17:31:08+00:00 build_sha256=b7671c5828111a2b75e116d694ba48d786592aeccb57c0b72abad3fcbad33e6c
  FEATURE-Incomplete-Submission.md sha256=96d0d4fc945551d701d21669a4cf50e63b66697040e56b431746661def9e0485 commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-7 applied_at=2026-08-15T17:32:38+00:00 build_sha256=3e2e77f56af611208bf7541b4a1224215ae16e980347133df342dd7b65683ab4
  FEATURE-Ordered-List.md sha256=364fa94d12e14acdc5a279ea32806a4f54999fa6a9f0edb769d7446c61e88fd3 commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-5 applied_at=2026-08-15T17:28:43+00:00 build_sha256=483854475539e4376fd2c0a669e9c72f880f5ada477e1efe3229d579b614cdc9
  FEATURE-Test-Suite.md sha256=8f200d65385c2e99573f6d51b74106337b22852b042bcaea23c5d9a6504bddae commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-9 applied_at=2026-08-15T17:35:50+00:00 build_sha256=b45ea869268d990e85c68cddf6efd4d2f1f7a2938645af2db9211b453fe37588
  SCREEN-Reading-List.md sha256=0003c6471f57751fb4bf2c8a3a359f5d20a6d6cfa66c38e6c57201c4328ae337 commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-10 applied_at=2026-08-15T17:38:45+00:00 build_sha256=bcf41704467eb3bd0af4b1de78474c9f8751db6507679191e5849fedaad21bd8
  UI-GENERAL.md sha256=0b6f592e79f56bbddb07352ad5ce0b07084a40a38ed7969e14ac933aa8d25272 commit=3d6897b00aee7d5f91f22f6c1f4ad809e83e4307 applied_by=block-3 applied_at=2026-08-15T17:26:15+00:00 build_sha256=062a3dabf23bcea23680430b002c4f2bd45fb41e34b6592b852458f87106c807
  UI-GENERAL_compact.md sha256=686b3f9cd5d7f5bacebc84f6dc4d1049a09d61ae79a304a93419d2c97d7df380 commit=- applied_by=block-8 applied_at=2026-08-15T17:34:05+00:00 build_sha256=686b3f9cd5d7f5bacebc84f6dc4d1049a09d61ae79a304a93419d2c97d7df380
  changes/TICKET-001-Mark-Book-Read.md sha256=2fe293f759c99bb313751c3a35a5286bb5fe658f443a465fe81b4dd56a3bea0a commit=9cbe248150df2f68847aa51e42be4d4707d8d56d applied_by=block-10 applied_at=2026-08-15T17:38:45+00:00 build_sha256=47d88ff4d6b3381ff3a94cca9b5846a0aa07eb7898681293e8f959f3113ae473
  changes/TICKET-002-Mark-Book-Read.md sha256=ce4183a9b0445df669546c679afa919090801425624eeb62a5814e4f8513ce9b commit=9cbe248150df2f68847aa51e42be4d4707d8d56d applied_by=block-10 applied_at=2026-08-15T17:38:45+00:00 build_sha256=3dace2410c0749c441e2dd9b88b6e641fcb43f578f999ef7a37980ddc9f9847b
## story 1: Establish the Flask application architecture and module boundaries.
id:           architecture
evidence: evidence/block-1.md
summary:      Establish the Flask application architecture and module boundaries.
type:         foundational
kind:         capability
phase:        1
block:        1
implements:   ARCHITECTURE.md
feedback:     analyze-display_name, analyze-short_description
instructions: |
  Establish the Flask application structure, application factory, route registration boundary,
  configuration boundary, and ownership rules for persistence and web concerns. Keep the design
  suitable for a small runnable web application and preserve insertion order for books.
stack:        python.md, flask.md, sqlite.md
stack_mode:   builder
size:         11455
provides:     application_factory, web_entrypoint
acceptance:   yes
state: closed/verified

## story 2: Establish SQLite persistence for ordered books.
id:           database
evidence: evidence/block-2.md
summary:      Establish SQLite persistence for ordered books.
type:         foundational
kind:         migration
phase:        1
block:        2
implements:   DATABASE.md
instructions: |
  Implement the SQLite persistence boundary for books. Define the books table and the typed store
  interface for adding, ordered listing, and removal. Ensure application code reaches SQLite only
  through the persistence interface and that insertion order is preserved.
stack:        persistence.md, sqlite.md, python.md
stack_mode:   builder
size:         9734
provides:     book_store.add, book_store.list_ordered, book_store.remove, books_table
consumes:     application_factory
depends:      architecture
acceptance:   yes
state: closed/verified

## story 3: Define shared presentation patterns for the reading-list interface.
id:           ui-general
evidence: evidence/block-3.md
summary:      Define shared presentation patterns for the reading-list interface.
type:         foundational
kind:         capability
phase:        1
block:        3
implements:   UI-GENERAL.md
instructions: |
  Define the shared HTML and CSS presentation patterns for the reading-list page, including the
  book form, ordered list, removal controls, empty state, and clear validation error treatment.
  Keep the patterns small and accessible for the single-screen application.
stack:        python.md, flask.md
stack_mode:   consumer
size:         3973
provides:     reading_list_ui_patterns
consumes:     application_factory
depends:      architecture
acceptance:   yes
state: closed/verified

## story 4: Add and persist a book submitted with a title and author.
id: book-creation
evidence: evidence/block-4.md
summary: Add and persist a book submitted with a title and author.
type: service
kind: capability
phase: 1
block: 4
implements: FEATURE-Book-Creation.md
covers: BOOKS-001
accepts: st-002
context: ARCHITECTURE_compact.md, DATABASE_compact.md
stack: python.md, flask.md, sqlite.md
stack_mode: consumer
size: 4873
provides: POST /books, book_creation
consumes: book_store.add, books_table
instructions: |
  Implement the book-creation workflow and POST /books route. Accept a title and author from the
  web form, persist the submitted book through the store, and return the reader to the list where
  the new book is visible. Preserve the submitted values without reordering existing books.
acceptance: yes
depends: database
state: closed/verified

## story 5: Render books in their insertion order with an empty-list state.
id: ordered-list
evidence: evidence/block-5.md
summary: Render books in their insertion order with an empty-list state.
type: service
kind: capability
phase: 1
block: 5
implements: FEATURE-Ordered-List.md
covers: BOOKS-002
accepts: st-003
context: ARCHITECTURE_compact.md, DATABASE_compact.md
stack: python.md, flask.md, sqlite.md
stack_mode: consumer
size: 4757
provides: GET /, ordered_book_listing
consumes: book_store.list_ordered, books_table
instructions: |
  Implement the ordered book-list read workflow and GET / route. Read books through the persistence
  interface in insertion order, render every book in that order, and present an understandable
  empty-list state when no books exist.
acceptance: yes
depends: book-creation
state: closed/verified

## story 6: Remove a selected book from the reading list.
id: book-removal
evidence: evidence/block-6.md
summary: Remove a selected book from the reading list.
type: service
kind: capability
phase: 1
block: 6
implements: FEATURE-Book-Removal.md
covers: BOOKS-003
accepts: st-004
context: ARCHITECTURE_compact.md, DATABASE_compact.md
stack: python.md, flask.md, sqlite.md
stack_mode: consumer
size: 4950
provides: POST /books/{id}/remove, book_removal
consumes: book_store.remove, ordered_book_listing
instructions: |
  Implement the removal action for a selected book. Route the removal request through the
  persistence boundary, then return the reader to the list so the removed book is absent on the
  next read while all remaining books retain their relative order.
acceptance: yes
depends: ordered-list
state: closed/verified

## story 7: Reject submissions missing a title or author with a clear error.
id: incomplete-submission
evidence: evidence/block-7.md
summary: Reject submissions missing a title or author with a clear error.
type: service
kind: capability
phase: 1
block: 7
implements: FEATURE-Incomplete-Submission.md
covers: BOOKS-004
accepts: st-005
context: ARCHITECTURE_compact.md, DATABASE_compact.md
stack: python.md, flask.md
stack_mode: consumer
size: 3948
provides: validate_book_submission
consumes: POST /books, book_creation
instructions: |
  Add validation at the book-submission boundary. Reject an empty title, an empty author, or both,
  do not persist rejected submissions, and return a clear user-facing indication that the required
  field is missing. Preserve valid submissions through the existing creation workflow.
acceptance: yes
depends: book-creation
state: closed/verified

## story 8: Assemble the reader-facing form, ordered list, empty state, and removal controls.
id: reading-list-screen
evidence: evidence/block-8.md
summary: Assemble the reader-facing form, ordered list, empty state, and removal controls.
type: service
kind: capability
phase: 1
block: 8
implements: SCREEN-Reading-List.md
context: UI-GENERAL.md, ARCHITECTURE_compact.md, DATABASE_compact.md
stack: python.md, flask.md
stack_mode: consumer
size: 4780
provides: reading_list_screen
consumes: GET /, POST /books, POST /books/{id}/remove, reading_list_ui_patterns
instructions: |
  Assemble the single reading-list screen using the completed workflows and shared UI patterns.
  Provide a direct path to submit a title and author, show books in insertion order, show the
  empty-list state, expose removal controls, and display validation failures clearly.
acceptance: yes
depends: ui-general, book-creation, ordered-list, book-removal, incomplete-submission
state: closed/verified

## story 9: Run and verify the complete automated test suite through bin/test.sh.
id: verification-suite
evidence: evidence/block-9.md
summary: Run and verify the complete automated test suite through bin/test.sh.
type: service
kind: test harness
phase: 1
block: 9
implements: FEATURE-Test-Suite.md
covers: VERIFY-001, VERIFY-002
accepts: st-001, st-006
context: ARCHITECTURE_compact.md, DATABASE_compact.md
stack: python.md
stack_mode: consumer
size: 2757
provides: sh bin/test.sh
consumes: reading_list_screen, book_creation, ordered_book_listing, book_removal, validate_book_submission
instructions: |
  Provide the automated tests covering adding, ordered listing, removal, and rejection of empty
  title or author. Provide a POSIX-compatible bin/test.sh runnable from the application root.
  The terminal verification must execute the complete suite and preserve its command, exit code,
  standard output, and standard error as evidence.
acceptance: yes
depends: reading-list-screen
state: closed/verified

## story 10: Add persisted read state per book and migrate existing rows.
id: mark-read-schema
evidence: evidence/block-10.md
summary: Add persisted read state per book and migrate existing rows.
origin: reading-list.md@02f4924
created: 2026-08-15
type: feature
phase: 1
block: 10
implements: changes/TICKET-001-Mark-Book-Read.md
context: DATABASE.md
state: closed/verified

## story 11: Add the mark-read action and route for a listed book.
id: mark-read-route
evidence: evidence/block-10.md
summary: Add the mark-read action and route for a listed book.
origin: reading-list.md@02f4924
created: 2026-08-15
type: feature
phase: 1
block: 10
implements: changes/TICKET-002-Mark-Book-Read.md
context: SCREEN-Reading-List.md
depends: mark-read-schema
state: closed/verified

## story 12: Render each book's read or unread state and provide the mark-read control.
id: mark-read-view
evidence: evidence/block-10.md
summary: Render each book's read or unread state and provide the mark-read control.
origin: reading-list.md@02f4924
created: 2026-08-15
type: feature
phase: 1
block: 10
implements: changes/TICKET-002-Mark-Book-Read.md
context: SCREEN-Reading-List.md
depends: mark-read-route
state: closed/verified
