mysociety / alaveteli

Provide a Freedom of Information request system for your jurisdiction
https://alaveteli.org
Other
387 stars 195 forks source link

Workflow for appeals to a regulator #2819

Open crowbot opened 8 years ago

crowbot commented 8 years ago

https://github.com/mysociety/whatdotheyknow-theme/issues/17 https://github.com/mysociety/alaveteli/issues/703 https://github.com/mysociety/ipvtheme/issues/7 https://github.com/mysociety/alaveteli/wiki/Complaining-to-ombudsman---feature-requirements

garethrees commented 8 years ago

https://www.whatdotheyknow.com/help/unhappy#complaining

garethrees commented 8 years ago

Feature 1 - letting the regulator know about overdue requests

  1. Currently, where a response is overdue the site sends a reminder email to the requester. The proposed new feature is that at this point the requester should be able to press a button to "Let the [name of the appropriate regulator] know that [name the public authority] has not responded to this request on time."

https://github.com/mysociety/alaveteli/wiki/Complaining-to-ombudsman---feature-requirements#feature-1---letting-the-regulator-know-about-overdue-requests

I think this feature would be best served by a manually sent email from the Alaveteli admin team. We could write a rake task that groups late requests by authority and prints them with their URL and number of days late. I think this batched-style would be more effective, as if the ICO spots a pattern emerging after several warnings they have more grounds to take substantial action.

$ rake stats:overdue_requests
Another Body
  https://alaveteli.example.org/request/abc, 60 days late
  https://alaveteli.example.org/request/cde, 20 days late

Some Body
  https://alaveteli.example.org/request/jhwe, 4 days late
  https://alaveteli.example.org/request/cwec, 1 day late
garethrees commented 8 years ago

Feature 2 - appealing to the regulator following an internal review

  1. The proposed feature is to allow complaints to the regulator to be made through the site in the same way as site currently handles internal review requests and related correspondence.

https://github.com/mysociety/alaveteli/wiki/Complaining-to-ombudsman---feature-requirements#feature-2---appealing-to-the-regulator-following-an-internal-review

Simplest UI workflow:

doc - 2 oct 2015 16-34

garethrees commented 8 years ago

I think this is going to be pretty tricky without dealing with public/private. I don't really see the advantage to private complaints – people may as well just fill in the ICO's form themselves. We should deal with this in #8.

garethrees commented 8 years ago

In terms of implementation, I think the answer is to extract the OutgoingMessage message_type logic in to STI or polymorphism. I don't know which yet – would need to dive deeper in to what the similarities and differences look like. Adding another message_type to OutgoingMessage would make things pretty complicated.

garethrees commented 8 years ago

Configuration parameters:

I'd be keen to not open these up for general usage until we've road tested the feature in WDTK (and maybe IPV, since they also want it).

garethrees commented 8 years ago

Actually, we'd have to have a more advanced data structure to support ICO / SIC.

ExternalArbitrator.add(:name => 'ICO', :contact_email => 'ico@example.com')
ExternalArbitrator.add(:name => 'SIC', :contact_email => 'sic@example.com', :tags => %w(scotland))
ExternalArbitrator.set_default('ICO')
garethrees commented 8 years ago

Since we're going to have to deal with differing rules depending on arbitrator, we could use the tag system to return some logic appropriate to whoever can handle the complaint:

DEFAULT_EXTERNAL_ARBITRATOR: InformationCommissionersOffice

# Match tags with an Arbitrator class
EXTERNAL_ARBITRATORS:
  - sic: ScottishInformationCommissioner
  - ico: InformationCommissionersOffice

The arbitrator classes would have to be able to return contact_email, human_name and complaint_template, and have some way of figuring out whether they can handle a complaint about a given InfoRequest (based on request status, last contact date, etc).

garethrees commented 8 years ago

Marking as awaiting review to start a discussion. I had a toy around with sketching some code ideas, but couldn't come up with anything that felt right yet.

crowbot commented 8 years ago

So having read the discussions so far, I have a few thoughts about this feature.

If the theme is responsible for determining these questions, can we supply some nice defaults? At the moment it seems like the default options for when the ombudsman feature is available that we might want to make available in core without requiring custom theme code are 'after an internal review' and 'when overdue'. The default for which ombudsman is chosen could just be the primary one if the theme doesn't implement any custom override.

garethrees commented 8 years ago

Couldn't resist having a go at this:

class InfoRequest # < ActiveRecord::Base
  attr_accessor :title, :tags

  def initialize(opts = {})
    @title = opts[:title]
    @tags = opts[:tags]
  end

  def overdue?
    true
  end

  def had_internal_review?
    false
  end
end

class RegulatorTagMapping # < ActiveRecord::Base
  attr_accessor :name, :email, :tag

  def self.all
    @all ||= []
  end

  def self.first
    all.first
  end

  def self.exists?(opts)
    where(opts).any?
  end

  def self.where(opts)
    all.map { |reg| reg if reg.tag == opts[:tag] }.compact
  end

  def initialize(opts = {})
    self.name = opts[:name]
    self.email = opts[:email]
    self.tag = opts[:tag]
    self.class.all << self
    self
  end
end

require 'forwardable'
module Regulator

  class Base
    extend Forwardable

    attr_reader :info_request
    def_delegators :@regulator_mapping, :name, :email

    def initialize(info_request, regulator_mapping)
      @info_request = info_request
      @regulator_mapping = regulator_mapping
    end

    def will_accept_request?
      false
    end
  end

  class InformationCommissionersOffice < Base
    def will_accept_request?
      info_request.overdue?
    end
  end

  class ScottishInformationCommissioner < Base
    def will_accept_request?
      info_request.overdue? && info_request.had_internal_review?
    end
  end

  MAPPINGS = {
    :ico => InformationCommissionersOffice,
    :sic => ScottishInformationCommissioner
  }

  def self.for(info_request)
    regulator, mapping = find_regulator_and_mapping(info_request.tags)
    if regulator && mapping
      regulator.new(info_request, mapping)
    else
      nil
    end
  end

  def self.find_regulator_and_mapping(tags)
    regulator_and_mappings = tags.map do |tag|
      regulator             = find_regulator(tag)
      regulator_tag_mapping = find_regulator_tag_mapping(tag)

      result = [regulator, regulator_tag_mapping]

      if result.compact.size == 2
        result
      else
        nil
      end
    end

    regulator_and_mappings.compact.first
  end

  def self.find_regulator(tag)
    MAPPINGS[tag.to_sym]
  end

  def self.find_regulator_tag_mapping(tag)
    RegulatorTagMapping.where(:tag => tag).first
  end

end

RegulatorTagMapping.new(:name => "ICO", :email => "ico@localhost", :tag => 'ico')
RegulatorTagMapping.new(:name => "SIC", :email => "sic@localhost", :tag => 'sic')

info_request1 = InfoRequest.new(:title => 'School performance in England', :tags => %w(school ico bristol))
regulator = Regulator.for(info_request1)
regulator.will_accept_request?
# => true

info_request2 = InfoRequest.new(:title => 'School performance in Scotland', :tags => %w(school sic glasgow))
regulator = Regulator.for(info_request2)
regulator.will_accept_request?
# => false

regulator.email
# => "sic@localhost"
garethrees commented 8 years ago

So, to add your own rules:

# Add the class
#
# ALAVETELI_THEME/lib/regulator/my_regulator.rb
module Regulator
  class MyRegulator < Base
    def will_accept_request?
      # My custom behaviour
    end
  end
end

# Configure it against a tag
#
# ALAVETELI_THEME/config/initializers/regulator.rb
# TODO: Make the MAPPINGS constant an instance var with accessors
Regulators.add :my_tag_target => Regulator::MyRegulator

# Hook it up in the admin interface
RegulatorTagMapping.new(:name => "My Regulator", :email => "reg@localhost", :tag => 'my_tag_target')
lizconlan commented 8 years ago

Devil's advocate, we could provide something more like a hook method with something like...

module Regulator
  class Base

    ...

    def will_accept_request?
      false || acceptance_rules
    end

    def acceptance_rules
      false
    end
  end

  class InformationCommissionersOffice < Base
    def acceptance_rules
      info_request.overdue?
    end
  end

  class ScottishInformationCommissioner < Base
    def acceptance_rules
      info_request.overdue? && info_request.had_internal_review?
    end
  end
end

Or...

module Regulator
  class Base

    ...

    def will_accept_request?
      !info_request.public_body.defunkt? && acceptance_rules
    end

    def acceptance_rules
      false
    end
  end
end 

...if you want to lay down some ground rules

garethrees commented 8 years ago

Yep, that looks good. I wonder if there's a nice way to avoid endless &&, &&, &&, &&, etc in acceptance_rules (or will_accept_request?, or whatever)?

garethrees commented 8 years ago

We spoke about whether the additional correspondence would make the requests threads hard to navigate. We decided that at some point you're going to want the option to "just show everything".

We thought of a few mitigation strategies:

doc - 20-10-2015 10-17

garethrees commented 8 years ago

When does the ICO appeal link appear?

def can_refer_to_ico?
  # true if its ever been in internal review
  # true if overdue
  # true if very overdue
  # false if not_foi?
  # false if vexatious?
  # false if user_withdrawn?
  # false if public_body.tagged('foi_no')
  # false if hidden?
end

if @regulator && @regulator.can_accept?(@info_request)
  link_to new_regulator_message_path(@info_request)
end

We've received a response from the regulator. How can we figure out its from them?

@incoming_message.who_from
# => 'ico'

# Might be nice to have message formatters for incoming messages in general:
MessageFormatter.for, 'ico', @incoming_message
garethrees commented 8 years ago

We want to be able to show that its been sent to the regulator. How?

Two options:

We were going to ask whether there was a specific reason the volunteers wanted a new state, or whether they just wanted to be able to show it's happened.

Out of the two options, I prefer using InfoRequestEvent as it avoids piling more work on the user. The benefit to the user of adding a new state is that it's a good prompt of what next steps they can take. I think we can still do a good job of this using the event data.

A sketch of the phrasing we could use if we added more states:

doc - 20-10-2015 12-00

garethrees commented 8 years ago

We think they can send a "Decision Notice" which broadly answers:

In terms of actual results they could:

garethrees commented 8 years ago

Via Richard:

Attached is the letter from the ICO to WhatDoTheyKnow.com saying

We would appreciate it if the website could be updated to reflect the fact that the Commissioner accepts complaints about delays in responding to a request for information without the requester exhausting the public authority’s internal review procedure.

garethrees commented 8 years ago

@lizconlan +1 on your suggestion of a hook method. Great examples under "Never Require Inheritance" here: https://practicingruby.com/articles/unobtrusive-ruby-in-practice

RichardTaylor commented 8 years ago

On overdue request referral

I share Louise's concerns. I think overdue request referral should be an option presented to requesters and not something entirely automated or needing to involve administrators.

Something the ICO does is put bodies into a status of "Monitoring compliance". A banner/notice for a authority saying the ICO are monitoring it might be an option (Is this approach by the regulator UK specific?). Perhaps the ICO could request automatic notifications of overdue requests in respect of bodies they're formally monitoring and we could enable them to ask for such notifications in respect of other requests too?

Perhaps the ICO could be a special user on the system and they could track certain requests and we'd make it public (and perhaps notify the public body) when they decide to track a request. Perhaps an ideal proactive regulator would pro-actively jump into some correspondence with public bodies!

Why do you want a new state?

I think that's question for developers; it's a question of how something's to be implemented not what users see isn't it? What's the impact on the ability to search for / display requests which have been referred to the ICO, been successful after an ICO referral etc.

The next step will probably be organising a meeting with the ICO.

I think working with the ICO (+ the Scottish ICO) is desirable and in the interests of our users; but building this feature shouldn't be dependant on their co-operation; and they shouldn't have undue influence over how it works.

I wonder what the ICO would think about the option of chasing a public body for a response publicly on our site? (I don't know if they copy complainants on chasing messages now - it's something they could do).

Ask volunteers and ICO what can the ICO do about a complaint?

I think a key point here is that responses after an ICO intervention can come many months after correspondence has ceased on a thread. If we've got correspondence involving the ICO on the thread the gap may reduce but we might want to act to stop requests referred to the ICO from being closed to new correspondence too soon.

how we might work the process in to the app from a requestor’s point of view.

Showing correspondence from the ICO on the threads in a distinct manner should be a fun job for mySociety's design team.

garethrees commented 8 years ago

Additional conversation in email to dev@ with subject "Automated appeals to the ombudsman".

garethrees commented 8 years ago

Renamed this ticket to reflect the feature title after closing #703.

wrightmartin commented 8 years ago

Here's some sketches on what I think are three different approaches

(Sorry for the bad photos, I just cannot get my scanner working and didn't want to burn any more time on hardware troubleshooting)

  1. We just insert the referral and the contents into the request page thread. The ICO just becomes a third party in the thread
  2. We insert the referral and contents as in 1, but we hide the contents behind a javascript 'click to reveal' thingy. This prevents the request page from becoming too cluttered, but keeps the thread intact

one-and-two

3 We deal with the ICO referral as a new request, with some sort of signposting back and forth. This keeps request pages almost as they are now, but maybe it requires too much understanding of the concepts to comprehend what we're showing here.

three

Regardless of the approach we need to make it clear that the ICO are involved with clear signposting and design nudges, such as showing the ICO logo (in the UK) or an equivalent for international sites as an 'avatar'

garethrees commented 8 years ago

All look good. 1 is likely to be the least amount of work, so probably start there. I'm keen to avoid international partners needing to find an ICO logo (if their ICO even has one).

garethrees commented 8 years ago

p.s. I use TurboScan for iPhone scanning of sketches. Works reasonably well.

wrightmartin commented 8 years ago

I'm keen to avoid international partners needing to find an ICO logo (if their ICO even has one).

Yeah sure, we could devise a default icon that is optionally replaced

Here's option one.

option 1 - ico in main thread

wrightmartin commented 8 years ago

Option 2. Hidden behind JS.

option 2 - ico in same thread but hidden

Option 2.2 JS hidden area open option 2a - ico in same thread but hidden revealed state

wrightmartin commented 8 years ago

Option 3. Show the ICO part of the thread as a new request

option 3 - ico thread in a new window

option 3 - ico thread in a new window ico request

schlos commented 8 years ago

+1 for Option 2

RichardTaylor commented 8 years ago

Maybe the ICO correspondence could be shown when the correspondence with the ICO is active and then collapsed when has concluded?

Also I wasn't expecting the ICO to correspond with the public body openly via Alaveteli. I expected the requestor - ICO correspondence only to be shown. It would be great if the regulator did operate so openly - currently those escalating a request to the ICO don't get copied on exchanges between the ICO and the public body.

wrightmartin commented 8 years ago

Also I wasn't expecting the ICO to correspond with the public body openly via Alaveteli. I expected the requestor - ICO correspondence only to be shown. It would be great if the regulator did operate so openly - currently those escalating a request to the ICO don't get copied on exchanges between the ICO and the public body.

@RichardTaylor we talked about that, I assume 99% of the time it will happen outside of Alaveteli, but I thought I better allow for it here. Do you know any other details about the lifecycle of escalated requests that might be useful?

RichardTaylor commented 8 years ago

Do you know any other details about the lifecycle of escalated requests that might be useful?

Some notes based on largely on looking through some of my own correspondence following asking the ICO for a decision:

wrightmartin commented 8 years ago

Thank you @RichardTaylor, this is excellent!

wrightmartin commented 8 years ago

Here's an exploration of how we show threaded conversations in context, rather than based purely on the timestamp of the reply.

Something else I've added is the new 'to' field to the message. Hopefully it helps to explain what's going on here.

option1 - threaded conversation

garethrees commented 8 years ago
garethrees commented 7 years ago

Scottish Information Commissioner's new online appeals tool http://www.itspublicknowledge.info/YourRights/Unhappywiththeresponse/AppealingtoCommissioner.aspx

garethrees commented 6 years ago

A request for this via the mysociety-community list.

MattK1234 commented 5 years ago

Just to note a user requested this feature recently, as they were not happy at having to provide their private email address to the ICO. Linked to #5320

garethrees commented 4 years ago

Thread from a Pro user requesting this https://groups.google.com/u/1/a/mysociety.org/g/alaveteli-pro/c/f5kOGvT6EfA

garethrees commented 4 years ago

"Don’t use the ICO’s ‘Report a Concern’ Form" http://www.confirmordeny.org.uk/?p=712

garethrees commented 3 years ago

Noting that there's a desire to enable multiple external reviewers rather than a single one https://github.com/openaustralia/righttoknow/issues/752.

We've now at least extracted a Legislation class, which might be the first step in making it a little easier to pair a legislation with a given reviewer, though, we should be careful not to introduce too much complexity in modelling the law as-is, vs our principle of modelling a world that we think should exist.

RichardTaylor commented 3 years ago

A correspondent has noted that a search on Google using site:ico.org.uk obtains results from within decision notices, and reviewing previous decisions can help when referring cases for a decision.

RichardTaylor commented 2 years ago

I made a change to the title:

Automated appeals to ICO >> Workflow for appeals to a regulator

Automated appeals suggests eg. automatically alerting a regulator (in the UK the ICO) if a response is long overdue.

As I understand it the feature proposed here is not that, but a system for enabling people to make referrals to a regulator via an Alaveteli site.

We could separately ticket the possibility of automated referrals to regulators - referrals might be on the basis of poor performance by a body rather than related to specific cases/requests.

RichardTaylor commented 2 years ago

How many people/requests might this feature serve?

We have stats showing 9,255 internal review messages were sent via WhatDoTheyKnow in 2021

https://github.com/mysociety/wdtk_analysis_notebooks/blob/master/notebooks/appeals-jan.ipynb

An internal review is a prerequisite to referral to the ICO (other than in cases of non-response where referral can be made straight away). We also know that around 35-40% of internal reviews result in an improved status - we don't know if these requesters are entirely happy, and not in need of a referral to the ICO, but we could assume for this estimate that they are.

That gives 9,225 * (1-0.375) = 5,765 request threads per year which might benefit from an "appeal to the regulator" feature.

There's an inconsistency I can't explain, but may be a difference between counting messages vs requests, with
https://2021.mysociety.org/#transparency

We have 2021 stats saying "1,991 [requests] went on to request an internal review" and there were "100,000+ requests made via WhatDoTheyKnow."

The quality, importance and potential impact of requests matters as well as absolute numbers - but the number of requests which might be aided by the feature is a factor in assessing the value of providing it.

laurentS commented 2 years ago

We at madada.fr would be interested in something like this. I'm exploring a customisation on our end, as I suspect the details of the workflow will be different between French laws and others (Belgium is probably very similar to France). We have just added a custom version of the PDF download with extra information that the CADA (the French appeal body) requested, and we will add a custom state for the request. A fully automated workflow around these elements would be ideal, but definitely more work. As a side note, France recently changed the rules so that the CADA can now provide an opinion on an entire batch instead of having to decide on each request individually.