#. Build the read-only PrivateStorage / magic-folder Android app

   #. Build an Android app that can parse a Tahoe-LAFS capability

      The deliverable is a CI pipeline which produces an Android-installable package.
      The package provides an application that shows a structured representation of CHK and SDMF capability strings that are hard-coded into the application.

      #. Set up CI
      #. Implement a Tahoe-LAFS capability parser library in Haskell

   #. Extend Android app to download and display one hard-coded N=1,k=1 CHK using received "anonymous" (no ZKAPs) server configuration

      The deliverable is as above with the following additions.
      The package provides an application which has a CHK capability string hard-coded into it.
      The application can download the associated data from a Tahoe-LAFS server speaking the "anonymous" Great Black Swamp.
      The Tahoe-LAFS server is located via hard-coded Grid configuration.
      If the associated data is plain text then it can display it in some basic way.

      #. Implement Tahoe-LAFS Great Black Swamp (immutables, read-only) Haskell client library
      #. Implement CHK (read-only) Haskell library

   #. Extend Android app to support arbitrary N/k CHK capabilities

      The deliverable is as above with the following additions.
      The application can download the associated data from N Tahoe-LAFS servers speaking the "anonymous" Great Black Swamp.
      The Tahoe-LAFS servers is located via hard-coded Grid configuration.
      The same servers are selected as the Python Tahoe-LAFS implementation would select.
      If the associated data is plain text then it can display it in some basic way.

      #. Build Tahoe-LAFS server selection algorithm compatibility test suite
      #. Implement Tahoe-LAFS server selection algorithm in Haskell

   #. Extend Android app to download and display one hard-coded N=1,k=1 SDMF directory using received "anonymous" (no ZKAPs) server configuration

      The deliverable is as above with the following additions.
      The package provides an application which has an SDMF capability string hard-coded into it.
      The application can download the associated data from a Tahoe-LAFS server speaking the "anonymous" Great Black Swamp.
      The Tahoe-LAFS server is located via hard-coded configuration.
      If the associated data is plain text then it can display it in some basic way.

      #. Implement Tahoe-LAFS Great Black Swamp (mutables, read-only) Haskell client library
      #. Implement SDMF (read-only) Haskell library
      #. Implement directory (read-only) Haskell library

   #. Extend Android app to support arbitrary N/k SDMF capabilities

      The deliverable is as above with the following additions.
      The application can download the associated data from N Tahoe-LAFS servers speaking the "anonymous" Great Black Swamp.
      Servers are selected in a manner analogous to that of the arbitrary N/k CHK case.

   #. Extend Android app to support ZKAPAuthorizer-enabled servers

      The deliverable is as above with the following additions.
      The hard-coded Grid configuration may include storage servers which only speak the ZKAPAuthorizer variation of the storage protocol.
      The application can speak to these servers to accomplish all of the above download tasks.

      #. Implement ZKAPAuthorizer economic protocol (read-only) for Great Black Swamp Haskell client library
      #. Deploy Great Black Swamp-enabled Tahoe-LAFS storage servers

	 #. Add support for economic plugins to Tahoe-LAFS Great Black Swamp implementation
	 #. Port ZKAPAuthorizer economic plugin to Great Black Swamp
	 #. Release Tahoe-LAFS with the above
	 #. Update PrivateStorageio with new Tahoe-LAFS release

   #. Extend Android app to support browsing directories

      The deliverable is as above with the following additions.
      If a CHK or SDMF capability represents a directory object then the directory contents are interpreted and a structured representation of them is displayed in the GUI.
      If a child of the directory is a directory then the GUI UX can recurse into that child.

      #. Finalize GUI design
      #. Integrate Tahoe-LAFS Haskell client libraries with existing Kotlin GUI or new Obelisk-based GUI

   #. Extend Android app to support receiving a read-cap

      The deliverable is as above with the following additions:

      #. Integrate with the Haskell magic-wormhole client
      #. Use a user-typed code to access a shared magic-wormhole mailbox
      #. Receive a folder-invite, including a Collective read-only capability
      #. (optional) allow user to say Y/N to the invite (replying via mailbox as appropriate)
      #. Store the Collective read-only capability as a folder locally

   #. Extend Android app to support browsing magic-folders

      The deliverable is as above with the following additions.
      The magic-folders configured locally via the pairing protocol are enumerated in the GUI.
      The directory browsing GUI can be applied to the logical directory hierarchy represented by a magic-folder.

      #. Build a "magic-folder lite" Haskell client library

   #. Extend Android app to support QR Codes

      The deliverable is as above with the following additions.
      The magic-folder pairing protocol is extended to allow reading the wormhole code via QR code

      #. Incorporate a QR Code decoding library
      #. Set the application up to accept `ps-pair:` URLs
      #. Parse the code out of such an URL (instead of user typing it in)
      #. Hard-code all other parameters (AppID, wormhole mailbox address, version, ..)

   #. Extend the Android app to reject improper version negotiation

      The deliverable is after the "support receiving a read-cap" milestone.
      The magic-wormhole protocol understands the "app-versions" negotiation properly.

      #. Fix the Haskell magic-wormhole library to understand "app-versions" (currently it "parses" them but throws them away / ignores it).
      #. Fix the pairing protocol to ask for proper "app-versions" from ^
      #. Fix the pairing protocol to send proper "app-versions" to the peer
      #. Fail on incorrect or incompatible "app-versions"

      Note that this is "very nice to have" for proper interoperability, but not strictly necessary for a first release.
      Risk: before this is implemented, any subsequent release of anything in the stack that speaks a newer pairing protocol may break this application.