{"action":"created","comment":{"url":"https://api.github.com/repos/alphagov/smart-answers/pulls/comments/69882171","id":69882171,"diff_hunk":"@@ -1,11 +1,308 @@\n-# The flow definition\n+# Flow\n \n-The Ruby flow file defines a `Flow` class that contains all the questions, outcomes and rules to control flow between.\n+The Ruby flow file defines a subclass of `SmartAnswer::Flow` that specifies metadata, and defines all the question nodes, the outcome nodes, and the rules to control flow between the nodes.\n \n-The file should be named the same as the path that we want the Smart Answer to be accessible at on gov.uk. For example, if we want the Smart Answer to be accessible at www.gov.uk/example-smart-answer then:\n+## Naming\n \n-* The flow file should be 'example-smart-answer.rb'\n-* The flow class should be `ExampleSmartAnswerFlow`\n-* The flow name should be 'example-smart-answer'\n+The flow filename should be based on the path where the Smart Answer is to be found on gov.uk. For example, for a Smart Answer at https://www.gov.uk/example-smart-answer, the flow file should be named `lib/smart_answer_flows/example-smart-answer.rb`. Similarly the template directory should be named `lib/smart_answer_flows/example-smart-answer/`.\n \n-The `Flow` class contains a single `#define` method that defines the questions (see \"Question types\" below), rules (see \"Defining next node rules\" below) and outcomes (see \"Outcome templates\" below).\n+The flow class should be a camel-case version of the flow filename with the suffix, `Flow` e.g. in the case above it would be `ExampleSmartAnswerFlow`. The class should inherit from `SmartAnswer::Flow` and be in the `SmartAnswer` namespace.\n+\n+For example:\n+\n+```ruby\n+# lib/smart_answer_flows/example-smart-answer/example-smart-answer.rb\n+module SmartAnswer\n+  class ExampleSmartAnswerFlow < Flow\n+    def define\n+      # flow definition specified here\n+    end\n+  end\n+end\n+```\n+\n+> Note that much of the above does not follow standard Ruby or Rails conventions which isn't ideal. However, the plan is to move towards using such conventions as soon as possible.\n+\n+## Definition\n+\n+The flow is defined within the `define` instance method of the `Flow` subclass using a DSL to specify metadata, question nodes and outcome nodes.\n+\n+> Unfortunately this DSL is overly complex and makes it all too easy to create code which is very hard to follow. The DSL makes heavy use of Ruby's [`BasicObject#instance_eval`][instance-eval] & [`#instance_exec`][instance-exec]. This means that:\n+>\n+> * It's not obvious what variables are in scope within a given block of code.\n+> * It's all too easy to write arbitrary custom code which can make each flow a bit of a special case. This doesn't help on the maintainability front.\n+> * It's confusing that blocks of code are not necessarily executed in the order that they appear in the flow definition.\n+> * The code in the blocks is not easily unit-testable.\n+\n+Each flow is instantiated in the `FlowRegistry` via the `Flow.build` method which, in turn, instantiates the flow and invokes its `Flow#define` method.\n+\n+Currently in production a single instance of each flow class is instantiated at application start-up (or strictly speaking on the first request) and cached in the `FlowRegistry` i.e. the same instance of a particular flow class is used to service all the user requests involving that Smart Answer. Thus it's important that no request-specific state is stored on the flow instance, otherwise this could leak into other user requests.\n+\n+It's important to understand this distinction between \"flow definition time\" and \"request time\" when trying to understand a flow definition. A number of the sections below refer to this distinction.\n+\n+### Metadata\n+\n+There are a number of methods on `SmartAnswer::Flow` which allow \"metadata\" for the flow to be specified:\n+\n+```ruby\n+module SmartAnswer\n+  class ExampleSmartAnswerFlow < Flow\n+    def define\n+      name 'example-smart-answer' # this is the path where the Smart Answer will be registered on gov.uk (via Panopticon)\n+      content_id \"bfda3b4f-166b-48e7-9aaf-21bfbd606207\" # a UUID used by v2 of the Publishing API (?)\n+      status :published # this indicates whether or not the flow should appear on gov.uk (i.e. production); those with `:draft` status will not appear\n+      satisfies_need \"123456\" # may relate the Smart Answer to the original user need in the Need-o-tron app (?)\n+\n+      # question & outcome definitions specified here\n+    end\n+  end\n+end\n+```\n+\n+### Arbitrary Ruby code\n+\n+Since the flow definition is just the body of a standard Ruby method, it's possible to write arbitrary Ruby code at any point within it.\n+\n+> It should be possible to implement the majority of flows *without* writing such arbitrary Ruby code. Any decision to introduce such arbitrary code should be very carefully considered, particularly regarding it's maintainability.\n+\n+Since the flow definition is just the body of a `Flow` instance method (`#define`), the value of `self` at the \"top-level\" within the method is an instance of the flow.\n+\n+#### Local variables\n+\n+Some flows (e.g. [register-a-birth][local-variable-in-flow-definition]) define local variables towards the top of the flow definition. Standard Ruby scoping means that these are then available within question & outcome blocks, as well as within blocks nested inside these blocks. However, note that the value of the local variable is set at flow definition time and *not* at request time. Since a single flow instance is cached in the `FlowRegistry` at application start-up time, this means the local variable is _only assigned once_.\n+\n+### Start node\n+\n+Every flow has an implicit start node which represents the \"landing page\" i.e. the page which displays the \"Start\" button. There is no representation of this start node in the flow definition. Clicking the \"Start\" button on the \"landing page\" takes you to the page for the first question node (see below).\n+\n+Also see the documentation for [landing page templates](doc/landing-page-template.md).\n+\n+### Question nodes\n+\n+There is an implicit assumption that the question definition which appears first in the flow definition is the first question of the flow. All other \"routing\" between nodes is [done explicitly](doc/next-node-rules.md) in a single `next_node` block per question node.\n+\n+By convention, question nodes are usually listed roughly in the order that a user would visit them. Although this isn't always straightforward when there are multiple paths through the flow.\n+\n+Since all \"routing\" is done explicitly within `next_node` blocks, the order of the question definitions (other than the first one) is functionally unimportant.\n+\n+By convention, all question nodes are defined *before* any of the outcome nodes. However, again the order is functionally unimportant.\n+\n+Question nodes are defined by calls to one of the various [question-type methods](doc/question-types.md). Since the value of `self` at the \"top-level\" within the `#define` method is an instance of the flow, these question-type methods are defined on the `SmartAnswer::Flow` base class.\n+\n+For example:\n+\n+```ruby\n+module SmartAnswer\n+  class ExampleSmartAnswerFlow < Flow\n+    def define\n+      # metadata specified here\n+\n+      multiple_choice :question_key do\n+        option :option_key_1\n+        option :option_key_2\n+\n+        # optional blocks specified here\n+\n+        next_node do\n+          # routing logic specified here\n+        end\n+      end\n+    end\n+  end\n+end\n+```\n+\n+See [In-question blocks](#in-question-blocks) below for more information on the optional blocks mentioned in a comment in the example.\n+\n+#### Scope\n+\n+The value of `self` inside the question node definition block (but outside other blocks) is the instance of the relevant question node. Thus in the example above, the calls to `#option` and `#next_node` are made on the instance of the question node.\n+\n+In the same way that there is a single instance of each flow class, there is only ever a single instance of each question definition in the system at any one time i.e. a flow instance has an invariant set of question node definition instances.\n+\n+Since the same instance of a question definition is used across multiple requests, it's important that no request-specific state is stored on them.\n+\n+The value of `self` inside the `next_node` blocks (or the other optional blocks) is an instance of `SmartAnswer::State` ([see below](#state)), i.e. *not* an instance of a question node.\n+\n+```ruby\n+def define\n+  # self = instance of SmartAnswer::Flow\n+\n+  value_question :question_key do\n+    # self = instance of SmartAnswer::Question::Value\n+\n+    on_response do |response|\n+      # self = instance of SmartAnswer::State\n+    end\n+\n+    next_node do\n+      # self = instance of SmartAnswer::State\n+    end\n+  end\n+end\n+```\n+\n+#### Execution\n+\n+The code inside the question node definition block (but outside other blocks) is executed at _flow definition time_, not at request time. However, the code inside the `next_node` blocks (or the other optional blocks) is executed at _request time_, not at flow definition time.\n+\n+```ruby\n+def define\n+  # executed at flow definition time\n+\n+  value_question :question_key do\n+    # executed at flow definition time\n+\n+    on_response do |response|\n+      # executed at request time\n+    end\n+\n+    next_node do\n+      # executed at request time\n+    end\n+  end\n+end\n+```\n+\n+#### State\n+\n+The state object is intended to store all request-specific state, keeping that away from the instance of the flow which is reused across multiple requests. `SmartAnswer::State` inherits from `OpenStruct` and uses [`BasicObject#method_missing`][method-missing]\n+to allow arbitrary \"state variables\" to be written and read.\n+\n+Since the request path only includes the user's responses and *not* the question keys, and the app is stateless, *every* request has to be processed by walking through the question definition nodes starting at the first one. As a request is processed, the state is duplicated using [`Object#dup`][object-dup] in each \"transition\" to a new node.\n+\n+It's important to note that `Object#dup` does not do a \"deep\" copy. Thus any \"state variables\" set on the state which are references to other objects will continue to reference the same instances of those other object - those objects will *not* themselves be duplicated. The *only* exceptions to this are two built-in state variables, `responses` & `path` ([see below](#built-in-state-variables)) which are themselves duplicated using `Object#dup` in `State#initialize_copy`.\n+\n+> Since a new instance of the state is created for each request, it's not obvious why the state is duplicated in this way. I know that in the past there have been problems with state leaking between requests, so perhaps this was a mistaken attempt at preventing such leakage.\n+\n+It's possible to [view the state](doc/viewing-state.md) when you're running the app in the development environment.\n+\n+##### Built-in state variables\n+\n+* `current_node` - symbol key for the node being processed\n+* `path` - array of symbol keys for nodes previously processed\n+* `responses` - user responses parsed from request path; usually strings (?)\n+* `response` - always `nil` (?)\n+* `error` - key for validation error message to display; usually a string (?)\n+\n+> Note that some of the application code (e.g. illegal multiple choice response) erroneously sets the error key to the validation error message *string*. Since this string is not the *key* to an error message, the default error message is displayed.\n+\n+#### In-question blocks\n+\n+All question definition blocks, must include a single `next_node` block. A number of other in-question blocks can optionally be defined by passing a block to any of the following methods on `SmartAnswer::Node` & `SmartAnswer::Question::Base`. The value of `self` inside all these blocks is an instance of `SmartAnswer::State` ([see above](#state)). The code inside these blocks is executed at request time, not at flow definition time.\n+\n+All blocks of a particular type (within a single question) are executed at particular points in the request processing sequence i.e. all `on_response` blocks are executed before all `next_node_calculation` blocks. The order in which the blocks are defined only affects the order in which they are executed within the group of blocks of the same type i.e. when two `on_response` blocks are defined, the one defined first will be executed before the one defined second; however, even if a `next_node_calculation` block is defined before both of these `on_response` blocks, it will always be executed after both of them.","path":"doc/flow-definition.md","position":null,"original_position":201,"commit_id":"e15b858263866c733b199b81e708e89ace6ee4aa","original_commit_id":"bb3fc2965538c709446405ea115b210aa99eac93","user":{"login":"floehopper","id":3169,"avatar_url":"https://avatars.githubusercontent.com/u/3169?v=3","gravatar_id":"","url":"https://api.github.com/users/floehopper","html_url":"https://github.com/floehopper","followers_url":"https://api.github.com/users/floehopper/followers","following_url":"https://api.github.com/users/floehopper/following{/other_user}","gists_url":"https://api.github.com/users/floehopper/gists{/gist_id}","starred_url":"https://api.github.com/users/floehopper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floehopper/subscriptions","organizations_url":"https://api.github.com/users/floehopper/orgs","repos_url":"https://api.github.com/users/floehopper/repos","events_url":"https://api.github.com/users/floehopper/events{/privacy}","received_events_url":"https://api.github.com/users/floehopper/received_events","type":"User","site_admin":false},"body":"I've addressed this in a fix-up commit: e15b858263866c733b199b81e708e89ace6ee4aa.","created_at":"2016-07-07T10:06:49Z","updated_at":"2016-07-07T10:06:49Z","html_url":"https://github.com/alphagov/smart-answers/pull/2613#discussion_r69882171","pull_request_url":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613","_links":{"self":{"href":"https://api.github.com/repos/alphagov/smart-answers/pulls/comments/69882171"},"html":{"href":"https://github.com/alphagov/smart-answers/pull/2613#discussion_r69882171"},"pull_request":{"href":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613"}}},"pull_request":{"url":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613","id":76287366,"html_url":"https://github.com/alphagov/smart-answers/pull/2613","diff_url":"https://github.com/alphagov/smart-answers/pull/2613.diff","patch_url":"https://github.com/alphagov/smart-answers/pull/2613.patch","issue_url":"https://api.github.com/repos/alphagov/smart-answers/issues/2613","number":2613,"state":"open","locked":false,"title":"Documentation improvements","user":{"login":"floehopper","id":3169,"avatar_url":"https://avatars.githubusercontent.com/u/3169?v=3","gravatar_id":"","url":"https://api.github.com/users/floehopper","html_url":"https://github.com/floehopper","followers_url":"https://api.github.com/users/floehopper/followers","following_url":"https://api.github.com/users/floehopper/following{/other_user}","gists_url":"https://api.github.com/users/floehopper/gists{/gist_id}","starred_url":"https://api.github.com/users/floehopper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floehopper/subscriptions","organizations_url":"https://api.github.com/users/floehopper/orgs","repos_url":"https://api.github.com/users/floehopper/repos","events_url":"https://api.github.com/users/floehopper/events{/privacy}","received_events_url":"https://api.github.com/users/floehopper/received_events","type":"User","site_admin":false},"body":"## Description\r\n\r\nTrello card: https://trello.com/c/XMu0U6Qc\r\n\r\nThis is an attempt to improve the documentation, particularly around the flow definition e.g. the scope of variables within the various blocks, the execution order of those same blocks, and hence the availability of variables within templates.\r\n\r\nI've focussed on documenting the *current* behaviour of the app. However, where appropriate, I've also tried to highlight the following:\r\n\r\n* peculiarities of the current behaviour\r\n* things that are deprecated/encouraged (as we try to [move towards the new-style of flow][refactoring])\r\n\r\nNote that where I have ascribed an intention to the current behaviour of the app, this is essentially guesswork, because neither @chrisroos nor I were involved in building the app in the first place.\r\n\r\nI was slightly hesitant to write this documentation, because the flow definition DSL is a moving target as we [move towards the new-style of flow][refactoring]. The aim is for it to be much simpler/intuitive and not need as much documentation!\r\n\r\nIt's probably best to review this pull request by viewing the final versions of the affected pages, rather than the diffs:\r\n\r\n* [flow-definition](https://github.com/alphagov/smart-answers/blob/improve-flow-definition-documentation/doc/flow-definition.md)\r\n* [landing-page-template](https://github.com/alphagov/smart-answers/blob/improve-flow-definition-documentation/doc/landing-page-template.md)\r\n* [question-templates](https://github.com/alphagov/smart-answers/blob/improve-flow-definition-documentation/doc/question-templates.md)\r\n* [outcome-templates](https://github.com/alphagov/smart-answers/blob/improve-flow-definition-documentation/doc/outcome-templates.md)\r\n\r\n## External changes\r\n\r\nNone. This only includes changes to documentation.\r\n\r\n[refactoring]: https://github.com/alphagov/smart-answers/blob/improve-flow-definition-documentation/doc/refactoring.md\r\n","created_at":"2016-07-05T14:48:56Z","updated_at":"2016-07-07T10:06:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c3d5a9028c4d310998b72f35713c151243ceff52","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613/commits","review_comments_url":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613/comments","review_comment_url":"https://api.github.com/repos/alphagov/smart-answers/pulls/comments{/number}","comments_url":"https://api.github.com/repos/alphagov/smart-answers/issues/2613/comments","statuses_url":"https://api.github.com/repos/alphagov/smart-answers/statuses/e15b858263866c733b199b81e708e89ace6ee4aa","head":{"label":"alphagov:improve-flow-definition-documentation","ref":"improve-flow-definition-documentation","sha":"e15b858263866c733b199b81e708e89ace6ee4aa","user":{"login":"alphagov","id":596977,"avatar_url":"https://avatars.githubusercontent.com/u/596977?v=3","gravatar_id":"","url":"https://api.github.com/users/alphagov","html_url":"https://github.com/alphagov","followers_url":"https://api.github.com/users/alphagov/followers","following_url":"https://api.github.com/users/alphagov/following{/other_user}","gists_url":"https://api.github.com/users/alphagov/gists{/gist_id}","starred_url":"https://api.github.com/users/alphagov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alphagov/subscriptions","organizations_url":"https://api.github.com/users/alphagov/orgs","repos_url":"https://api.github.com/users/alphagov/repos","events_url":"https://api.github.com/users/alphagov/events{/privacy}","received_events_url":"https://api.github.com/users/alphagov/received_events","type":"Organization","site_admin":false},"repo":{"id":2651887,"name":"smart-answers","full_name":"alphagov/smart-answers","owner":{"login":"alphagov","id":596977,"avatar_url":"https://avatars.githubusercontent.com/u/596977?v=3","gravatar_id":"","url":"https://api.github.com/users/alphagov","html_url":"https://github.com/alphagov","followers_url":"https://api.github.com/users/alphagov/followers","following_url":"https://api.github.com/users/alphagov/following{/other_user}","gists_url":"https://api.github.com/users/alphagov/gists{/gist_id}","starred_url":"https://api.github.com/users/alphagov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alphagov/subscriptions","organizations_url":"https://api.github.com/users/alphagov/orgs","repos_url":"https://api.github.com/users/alphagov/repos","events_url":"https://api.github.com/users/alphagov/events{/privacy}","received_events_url":"https://api.github.com/users/alphagov/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/alphagov/smart-answers","description":"smart-answers","fork":false,"url":"https://api.github.com/repos/alphagov/smart-answers","forks_url":"https://api.github.com/repos/alphagov/smart-answers/forks","keys_url":"https://api.github.com/repos/alphagov/smart-answers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/alphagov/smart-answers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/alphagov/smart-answers/teams","hooks_url":"https://api.github.com/repos/alphagov/smart-answers/hooks","issue_events_url":"https://api.github.com/repos/alphagov/smart-answers/issues/events{/number}","events_url":"https://api.github.com/repos/alphagov/smart-answers/events","assignees_url":"https://api.github.com/repos/alphagov/smart-answers/assignees{/user}","branches_url":"https://api.github.com/repos/alphagov/smart-answers/branches{/branch}","tags_url":"https://api.github.com/repos/alphagov/smart-answers/tags","blobs_url":"https://api.github.com/repos/alphagov/smart-answers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/alphagov/smart-answers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/alphagov/smart-answers/git/refs{/sha}","trees_url":"https://api.github.com/repos/alphagov/smart-answers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/alphagov/smart-answers/statuses/{sha}","languages_url":"https://api.github.com/repos/alphagov/smart-answers/languages","stargazers_url":"https://api.github.com/repos/alphagov/smart-answers/stargazers","contributors_url":"https://api.github.com/repos/alphagov/smart-answers/contributors","subscribers_url":"https://api.github.com/repos/alphagov/smart-answers/subscribers","subscription_url":"https://api.github.com/repos/alphagov/smart-answers/subscription","commits_url":"https://api.github.com/repos/alphagov/smart-answers/commits{/sha}","git_commits_url":"https://api.github.com/repos/alphagov/smart-answers/git/commits{/sha}","comments_url":"https://api.github.com/repos/alphagov/smart-answers/comments{/number}","issue_comment_url":"https://api.github.com/repos/alphagov/smart-answers/issues/comments{/number}","contents_url":"https://api.github.com/repos/alphagov/smart-answers/contents/{+path}","compare_url":"https://api.github.com/repos/alphagov/smart-answers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/alphagov/smart-answers/merges","archive_url":"https://api.github.com/repos/alphagov/smart-answers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/alphagov/smart-answers/downloads","issues_url":"https://api.github.com/repos/alphagov/smart-answers/issues{/number}","pulls_url":"https://api.github.com/repos/alphagov/smart-answers/pulls{/number}","milestones_url":"https://api.github.com/repos/alphagov/smart-answers/milestones{/number}","notifications_url":"https://api.github.com/repos/alphagov/smart-answers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/alphagov/smart-answers/labels{/name}","releases_url":"https://api.github.com/repos/alphagov/smart-answers/releases{/id}","deployments_url":"https://api.github.com/repos/alphagov/smart-answers/deployments","created_at":"2011-10-26T15:39:01Z","updated_at":"2016-07-01T17:35:26Z","pushed_at":"2016-07-07T10:06:26Z","git_url":"git://github.com/alphagov/smart-answers.git","ssh_url":"git@github.com:alphagov/smart-answers.git","clone_url":"https://github.com/alphagov/smart-answers.git","svn_url":"https://github.com/alphagov/smart-answers","homepage":"","size":49641,"stargazers_count":79,"watchers_count":79,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":53,"mirror_url":null,"open_issues_count":21,"forks":53,"open_issues":21,"watchers":79,"default_branch":"master"}},"base":{"label":"alphagov:master","ref":"master","sha":"9c92748347346a0dc9261c4022a370261d1f4df3","user":{"login":"alphagov","id":596977,"avatar_url":"https://avatars.githubusercontent.com/u/596977?v=3","gravatar_id":"","url":"https://api.github.com/users/alphagov","html_url":"https://github.com/alphagov","followers_url":"https://api.github.com/users/alphagov/followers","following_url":"https://api.github.com/users/alphagov/following{/other_user}","gists_url":"https://api.github.com/users/alphagov/gists{/gist_id}","starred_url":"https://api.github.com/users/alphagov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alphagov/subscriptions","organizations_url":"https://api.github.com/users/alphagov/orgs","repos_url":"https://api.github.com/users/alphagov/repos","events_url":"https://api.github.com/users/alphagov/events{/privacy}","received_events_url":"https://api.github.com/users/alphagov/received_events","type":"Organization","site_admin":false},"repo":{"id":2651887,"name":"smart-answers","full_name":"alphagov/smart-answers","owner":{"login":"alphagov","id":596977,"avatar_url":"https://avatars.githubusercontent.com/u/596977?v=3","gravatar_id":"","url":"https://api.github.com/users/alphagov","html_url":"https://github.com/alphagov","followers_url":"https://api.github.com/users/alphagov/followers","following_url":"https://api.github.com/users/alphagov/following{/other_user}","gists_url":"https://api.github.com/users/alphagov/gists{/gist_id}","starred_url":"https://api.github.com/users/alphagov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alphagov/subscriptions","organizations_url":"https://api.github.com/users/alphagov/orgs","repos_url":"https://api.github.com/users/alphagov/repos","events_url":"https://api.github.com/users/alphagov/events{/privacy}","received_events_url":"https://api.github.com/users/alphagov/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/alphagov/smart-answers","description":"smart-answers","fork":false,"url":"https://api.github.com/repos/alphagov/smart-answers","forks_url":"https://api.github.com/repos/alphagov/smart-answers/forks","keys_url":"https://api.github.com/repos/alphagov/smart-answers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/alphagov/smart-answers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/alphagov/smart-answers/teams","hooks_url":"https://api.github.com/repos/alphagov/smart-answers/hooks","issue_events_url":"https://api.github.com/repos/alphagov/smart-answers/issues/events{/number}","events_url":"https://api.github.com/repos/alphagov/smart-answers/events","assignees_url":"https://api.github.com/repos/alphagov/smart-answers/assignees{/user}","branches_url":"https://api.github.com/repos/alphagov/smart-answers/branches{/branch}","tags_url":"https://api.github.com/repos/alphagov/smart-answers/tags","blobs_url":"https://api.github.com/repos/alphagov/smart-answers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/alphagov/smart-answers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/alphagov/smart-answers/git/refs{/sha}","trees_url":"https://api.github.com/repos/alphagov/smart-answers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/alphagov/smart-answers/statuses/{sha}","languages_url":"https://api.github.com/repos/alphagov/smart-answers/languages","stargazers_url":"https://api.github.com/repos/alphagov/smart-answers/stargazers","contributors_url":"https://api.github.com/repos/alphagov/smart-answers/contributors","subscribers_url":"https://api.github.com/repos/alphagov/smart-answers/subscribers","subscription_url":"https://api.github.com/repos/alphagov/smart-answers/subscription","commits_url":"https://api.github.com/repos/alphagov/smart-answers/commits{/sha}","git_commits_url":"https://api.github.com/repos/alphagov/smart-answers/git/commits{/sha}","comments_url":"https://api.github.com/repos/alphagov/smart-answers/comments{/number}","issue_comment_url":"https://api.github.com/repos/alphagov/smart-answers/issues/comments{/number}","contents_url":"https://api.github.com/repos/alphagov/smart-answers/contents/{+path}","compare_url":"https://api.github.com/repos/alphagov/smart-answers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/alphagov/smart-answers/merges","archive_url":"https://api.github.com/repos/alphagov/smart-answers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/alphagov/smart-answers/downloads","issues_url":"https://api.github.com/repos/alphagov/smart-answers/issues{/number}","pulls_url":"https://api.github.com/repos/alphagov/smart-answers/pulls{/number}","milestones_url":"https://api.github.com/repos/alphagov/smart-answers/milestones{/number}","notifications_url":"https://api.github.com/repos/alphagov/smart-answers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/alphagov/smart-answers/labels{/name}","releases_url":"https://api.github.com/repos/alphagov/smart-answers/releases{/id}","deployments_url":"https://api.github.com/repos/alphagov/smart-answers/deployments","created_at":"2011-10-26T15:39:01Z","updated_at":"2016-07-01T17:35:26Z","pushed_at":"2016-07-07T10:06:26Z","git_url":"git://github.com/alphagov/smart-answers.git","ssh_url":"git@github.com:alphagov/smart-answers.git","clone_url":"https://github.com/alphagov/smart-answers.git","svn_url":"https://github.com/alphagov/smart-answers","homepage":"","size":49641,"stargazers_count":79,"watchers_count":79,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":53,"mirror_url":null,"open_issues_count":21,"forks":53,"open_issues":21,"watchers":79,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613"},"html":{"href":"https://github.com/alphagov/smart-answers/pull/2613"},"issue":{"href":"https://api.github.com/repos/alphagov/smart-answers/issues/2613"},"comments":{"href":"https://api.github.com/repos/alphagov/smart-answers/issues/2613/comments"},"review_comments":{"href":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613/comments"},"review_comment":{"href":"https://api.github.com/repos/alphagov/smart-answers/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/alphagov/smart-answers/pulls/2613/commits"},"statuses":{"href":"https://api.github.com/repos/alphagov/smart-answers/statuses/e15b858263866c733b199b81e708e89ace6ee4aa"}}}}
{"actor":{"display_login":"floehopper"}}