A lab for Q&A systems like Mosaic/Patchwork/HCH/etc.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Alpha. Likely to change dramatically.


Install stack, and then stack build should be all that's required to build the code. stack run or stack exec affable will then run the executable.

Command Line Options

  • gen-api - Generate the client-side code for the web API into static/command-api.js.
  • serve [<dbfile>] - Start a web server optionally storing state in the Sqlite database dbfile.
  • noauto [<dbfile>] - Create an interaction with no automation optionally storing state in the Sqlite database dbfile.
  • export <dbfile> <id> - Print the automation as Haskell code for the function with ID id stored in the Sqlite database dbfile.
  • concurrent [<dbfile>] - Same as next option but schedule questions concurrently.
  • [<dbfile>] - Create an interaction with automation optionally storing state in the Sqlite database dbfile.

For example, stack run foo.db (or stack exec affable foo.db) will start a session supporting automation and storing the results into the Sqlite database foo.db. This does not reuse the automation from prior runs.

Once you've completed (whether by answering the top-level question, or using Ctrl-D/Ctrl-Z/Ctrl-C to terminate early), you can export the code via stack run export foo.db 1 > t.hs. 1 should be replaced by the ID of the top-level function you want to export which you'd need to get by looking in the database, though it will likely be 1 if you started with an empty database. Querying the database with SELECT id FROM Functions WHERE isAnswer = 1 should given you appropiate IDs. t.hs is now a self-contained Haskell program which is can be compiled and executed, e.g. via runhaskell t.hs.


These are the commands that are accepted in the interactive mode:

  • ask <message> - This schedules a new question to be asked.
  • view <pointer> - This expands a pointer revealing what it points at.
  • reply <message> - This answers the current question.
  • wait - This waits for the answers to unanswered questions.
  • exit - Exits the program.

Tab completion should work for these commands except for exit.

Currently, you need to ask a question as the first thing otherwise the program will crash.

A pointer looks like $n where n is a number, e.g. $37.

A message is an arbitrary string that may contain pointers except that it must have balanced square brackets, [, ]. A square bracketed part of the string becomes a sub-message that will be hidden behind a pointer.

When you ask a question like What is $1 minus $1? the question that will be presented is the more general question, What is $1 minus $2?

Here is an animation illustrating the command-line interface in action: Demonstration of command-line interface

See the scripts in https://github.com/oughtinc/affable/tree/master/tests/scripts for more example input sequences.


Topics to explore:

  • Framework that allows automation based on actions or whatever is appropriate.

  • Framework that allows continuous distillation

  • Probably support reflection a la the Taxonomy

  • Intercession on scheduling

    • Ideally some support for automation/distillation of scheduling.
  • Internal dialog via message passing

    • Persistent processes
    • Or, auto-replicating processes
      • Only access to the causally "latest" (from the current process' perspective) node
      • or acess to earlier "versions" as well
  • Or, editing versus internal dialog

    • How to handle staleness?
    • Should editing be non-local? If no, what does that mean exactly?
  • Intercession on other aspects? (Rendering, Distillation, Automation)