Open crowbot opened 8 years ago
Feature 1 - letting the regulator know about overdue requests
- 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."
- …
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
Feature 2 - appealing to the regulator following an internal review
- 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.
- …
Simplest UI workflow:
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.
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.
Configuration parameters:
EXTERNAL_ARBITRATOR_NAME
EXTERNAL_ARBITRATOR_EMAIL
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).
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')
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).
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.
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.
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"
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')
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
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)?
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:
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
We want to be able to show that its been sent to the regulator. How?
Two options:
regulator_informed
, regulator_responded
InfoRequestEvent
to enrich information (iterate over to see if we've ever created an external_review_sent
event)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:
We think they can send a "Decision Notice" which broadly answers:
In terms of actual results they could:
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.
@lizconlan +1 on your suggestion of a hook method. Great examples under "Never Require Inheritance" here: https://practicingruby.com/articles/unobtrusive-ruby-in-practice
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.
Additional conversation in email to dev@
with subject "Automated appeals to the ombudsman".
Renamed this ticket to reflect the feature title after closing #703.
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)
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.
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'
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).
p.s. I use TurboScan for iPhone scanning of sketches. Works reasonably well.
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 2. Hidden behind JS.
Option 2.2 JS hidden area open
Option 3. Show the ICO part of the thread as a new request
+1 for Option 2
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.
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?
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:
We at WhatDoTheyKnow have been told:
The ICO requires that individuals referring a complaint to us explain and provide sufficient details of their complaint. Where we do not receive this information it is our practice to contact the individual to request this and also to explain that we will not be able to begin investigating their case until they have done so.
The ICO may seek to informally resolve a case, without issuing a formal decision notice, in these circumstances it will ask the requestor if they're happy with eg. additional reasoning / material provided by a public body and if they are willing to withdraw the referral. eg. I've received:
Please can you advise whether or not you are now happy to withdraw your complaint? If not, please let me know on what grounds you remain dissatisfied. I am unable to progress any investigation without your input. If I do not hear from you by the end of the week I will have no option other than to close the case.
Thank you @RichardTaylor, this is excellent!
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.
InfoRequest#receive
needs to be able to accept an external review responseIncomingMessage#from_public_body?
needs to know an external review response is not from a PublicBody
(at the moment, it appears to assume everything is)OutgoingMessage
needs an OutgoingMessage::Template::ExternalReview
templateOutgoingMessage#to
and OutgoingMessage#subject
need to handle the correct values when in an external_review
stateInfoRequest
needs to know who to send external reviews to, if it can at allInfoRequest
at all.OutgoingMailer
class methods may no longer be used, so deprecate/remove themScottish Information Commissioner's new online appeals tool http://www.itspublicknowledge.info/YourRights/Unhappywiththeresponse/AppealingtoCommissioner.aspx
A request for this via the mysociety-community list.
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
Thread from a Pro user requesting this https://groups.google.com/u/1/a/mysociety.org/g/alaveteli-pro/c/f5kOGvT6EfA
"Don’t use the ICO’s ‘Report a Concern’ Form" http://www.confirmordeny.org.uk/?p=712
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.
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.
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.
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.
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.
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