The four values of a participatory decision-making process

  1. The importance of a participatory decision-making process
  2. The four values of a participatory decision-making process

In the first post of the series, we talked about why have a participatory decision-making process is so important, and the value that it can bring. However, it can be quick difficult to define what that is. Fortunately, there is a set of four values that must present in each discussion or meeting or whatever the decision-making is. They are:

The four values of a participatory decision-making process are

  1. Full participation
  2. Mutual understanding
  3. Inclusive solution
  4. Shared responsibility

An in-depth analysis of the four values:

First value: Full participation

  • Participants are comfortable in sharing uncomfortable ideas and their first draft ideas
  • Participants are encouraging each other to think like that

The facilitators role in achieving full participation

  • Protect against injunctions against thinking in public (e.g. Can we go back to the topic, we are diverging, didn’t we already discuss this)
  • Build a respectful and supportive atmosphere
  • Protect against self-censorship

Second value: Mutual understanding

  • The participants understand and accept the legitimacy of the others needs and goals
  • The participants think from each other’s point’s of view
  • Dialogue is more important than persuasion
  • The participants take time to understand everyone’s perspectives

The facilitators role in achieving mutual understanding

  • Prevent the “I really can’t focus on what you are saying until I feel you understand what is my points of view” mentality
  • Help everyone realize the value of thinking from each others point of view
  • Always be impartial and honor the points of view of everyone involved. This ways, every member has the feeling that someone understands them

Third value: Inclusive solutions

  • Solutions emerge from the integrations of everyone’s perspectives, needs and goals
  • Everyone has a piece of truth
  • The solutions are not compromises, as they work for everyone involved
  • They might require the discovery of a new option
  • Innovation and sustainability of a solution are more important than the decision being expedient

The facilitators role in achieving inclusive solutions

  • Help the group find innovative ideas that result from using everyone’s point of view
  • Help the group engage in divergent thinking
  • And then build a shared framework of understanding in the groan zone
  • To, at last, converge with sound decisions

Fourth: Shared responsibility

  • Everyone is an owner of the outcome
  • Everyone is responsible for running the meeting: settings the goals, the agenda, the priorities and arriving at conclusions
  • Members must be able to implement the proposals that they endorse
  • The problem: the group relies on authority. This makes the leaders to “get on with it” and to the work themselves

The facilitators role in achieving shared responsibility

The facilitator helps the group build assertiveness, collaboration and the ownership of the decision process and outcomes.

  1. The importance of a participatory decision-making process
  2. The four values of a participatory decision-making process

The importance of a participatory decision-making process

I have been reading “The Facilitator’s Guide to Participatory Decision-Making” by Sam Kaner. The objective of this series is to write down some notes for me, and provide content that can be found by others, to assert if the book should be bought (so for, the answer is a resounding yes!).

  1. The importance of a participatory decision-making process
  2. The four values of a participatory decision-making process

Facilitator’s Guide to Participatory Decision-Making

Sam Kaner

Well, what is this book about?

Decision making is everywhere, from small things like how to divide tasks for an afternoon project to large multi-month enterprises with several stakeholders involved and many workers. Therefore making sound decisions is super important: it will lead to better products, less time wasted. Specially, it wil lead to better morale, as everyone feels that their needs are being heard.

Participatory decision-making

A participatory decision-making process means that every one that is touched by a decision is heard and participates in it. They suggest root causes, share their concerns, suggest solutions and implement the solution. Not only that, but they participate in the decision process itself: run meetings, prepare the agenda, etc.

Why is this so important? Well,

If people do not participate in the decision-making process, that decision will fail with misunderstood ideas and a half-hearted implementation

The diamond of participatory decision-making

Diamond of Participatory Decision-Making. Developed by Sam Kaner
Diamond of Participatory Decision-Making. It was developed by Sam Kaner with Lenny Lind, Catherine Toldi, Sarah Fisk and Duane Berger

This diagram summarizes the dynamics of group thinking. First, the group discusses a new topic as “Business as usual”. The participants stay in their comfort zone and make safe suggestions. Some times this is enough for a simple problem, and the meeting ends there. Many times it is not.


Then, the group moves into divergent thinking. It starts generating alternatives and exploring different points of view. It is important that its members feel safe to share novel ideas, without fear of judgement.

This will lead to the groan zone, where the most discomfort and heated moments exist. The group processes all the ideas created in the divergent zone to start building a shared framework of understanding. What is the shared framework of understanding? It is a “state” where the group is aware of the individual’s concerns, points of view and suggestions. Everyone shares the same level of understanding of the problem.


When this happens the group can start to converge. It summarizes key points, judges the ideas and evaluates alternatives. Hopefully, this leads to a decision without any compromise, where each affected party has its problems addressed.

Divergent thinking

  • Generating alternatives
  • Free flowing open discussion
  • Gathering different points of view
  • No judgement

Groan zone

  • Understanding foreign and complex ideas
  • Build a shared framework of understanding
  • The confusion moment

Convergent thinking

  • Evaluating alternatives
  • Summarizing key points
  • Sorting ideas into categories
  • Exercising judgement

Last but not least, there four values adjacent to all this process. They are fundamental in ensuring that the participatory part of the decision-making process happens. They are:

  • Full participation
  • Mutual understanding
  • Inclusive solution
  • Shared responsibility

There is an entire post on this series dedicated to dissecting them.

The facilitator role in participatory decision-making

Well, that explains the second part of “The Facilitator’s Guide to Participatory Decision-Making“, what about the facilitator? Who is that guy?

In short:

The facilitator supports everyone at doing their best thinking

The facilitator is a servant leader that ensures everyone is heard and feels safe to share their opinions. Lastly, the facilitator guides the group through the diamond of participatory decision making.

There are some “smells” that prevent traditional groups from reaching perfect solutions:

  • Fixed positions
  • Win/lose mentality
  • Self-censorship
  • Reliance on authority

It is the facilitator’s role to prevent them from creeping up and undermining the meetings. These smells are explained in a post dedicated to the values of participatory decision making.

To do its best job, the facilitator must have:

  • Content neutrality – he does not have a position in one of the discussion sides.
  • Does not have a position in the outcome – he does not benefit if a certain decision is made.
  • Does not advocate for certain processes – the group is responsible to choose how they decide things.

In short, the facilitator must be independent and act from outside any of the group’s individual interests.

During the discussion, the facilitator:

  • Builds and sustains a supportive atmosphere
  • Stays out of the content and respects the process
  • Teaches the group new thinking skills
  1. The importance of a participatory decision-making process
  2. The four values of a participatory decision-making process

Create a custom django prometheus metric

Today I’ll show you how to create your custom prometheus metric for your django application. Prometheus is an awesome tool to monitor our stack, specially with its integration with grafana and its cool dashboards.

The example metric is for a recent use case. I wanted to measure my website visitors favourite pages, and where they came from.

I wanted to achieve this without tracking, cookies, paid services or having to use Google Analytics. Since I was already using a Prometheus/ Grafana suite to have visibility of my platform health, I decided to use it for this goal as well.

This was the end result, on grafana:

A custom django prometheus metric on grafana

First step: having django-prometheus up and running!

Just follow the instructions on the project readme, they should be just:

pip install django-prometheus

Then, on settings.py

INSTALLED_APPS = [
   ...
   'django_prometheus',
   ...
]

MIDDLEWARE = [
    'django_prometheus.middleware.PrometheusBeforeMiddleware',
    # All your other middlewares go here, including the default
    # middlewares like SessionMiddleware, CommonMiddleware,
    # CsrfViewmiddleware, SecurityMiddleware, etc.
    'django_prometheus.middleware.PrometheusAfterMiddleware',
]

And lastly, on your urls.py:

urlpatterns = [
    ...
    url('', include('django_prometheus.urls')),
]

Also, if you are deploying your code using gunicorn or similar(and you should if you are deploying to a production environment!), pay attention. You need to declare multiple ports since the workers could block each other while trying to service the Prometheus scrape request. This is also very well explained in the django-Prometheus documentation.

PROMETHEUS_METRICS_EXPORT_PORT_RANGE = range(8001, 8050)

Second step: adding our custom django Prometheus metric

This is the actual first step in creating our custom prometheus metric on our django app. register the new metric.

Now it might be a good time to refer to the official Prometheus documentation about metrics. After a good read, we can register it:

Our custom metric will count the number of requests by view, path and referer.

The general idea is to first create a new Metrics class, that inherits from django_prometheus.Metrics. On that we will register own actual metric:

  1. we want it to be a Counter, because it will be increasing over time.
  2. we will unoriginally name it django_http_requests_total_by_view_path_referer,
  3. and add a description that will be useful for documentation purposes.
  4. lastly, our metric will have three labels: view, path and referer so that we can group and filter by them.

Last but not least, do not forget to call the parent method so that we register the remaining metrics.

from django_prometheus.conf import NAMESPACE
from django_prometheus.middleware import Metrics
from prometheus_client import Counter

class CustomMetrics(Metrics):
    def register(self):
        self.requests_total_by_view_path_referer = self.register_metric(
            Counter,
            "django_http_requests_total_by_view_path_referer",
            "Count of requests by view, path, referer.",
            ["view", "path", "referer"],
            namespace=NAMESPACE,
        )
        return super().register()

Third step: creating our custom PrometheusMiddleware

Now that we have our shiny metric, we need to measure it. To do so, we will create two classes that inherit from PrometheusBeforeMiddleware and PrometheusBeforeMiddleware – they will contain our actual metric collection logic.

PrometheusAfterMiddleWare has a bunch of methods where we can add our logic. These methods are called on different moments of the request/response lifecycle, and so receive different parameters:

  • For example, process_exception() receives the request and exception objects,
  • process_response receives() request and response object,
  • the process_view method() receives the request and view related objects.

Take a look at the django-prometheus existing code to figure out the best place to put your metric, putting it closer to similar metrics. For this case process_response() seemed like a good candidate because the view name has been resolved by then.

from django_prometheus.middleware import Metrics, PrometheusBeforeMiddleware, PrometheusAfterMiddleware

...

class AppMetricsBeforeMiddleware(PrometheusBeforeMiddleware):
    metrics_cls = CustomMetrics


class AppMetricsAfterMiddleware(PrometheusAfterMiddleware):
    metrics_cls = CustomMetrics

    def _get_referer_name(self, request):
        referer_name = "<unnamed referer>"
        if hasattr(request, "META"):
            if request.META is not None:
                if request.META.get("HTTP_REFERER") is not None:
                    referer_name = request.META.get("HTTP_REFERER")
        return referer_name

    def process_response(self, request, response):

      self.label_metric(self.metrics.requests_total_by_view_path_referer,
                        request,
                        view=self._get_view_name(request),
                        path=request.path,
                        referer=self._get_referer_name(request)).inc()

        return super().process_response(request, response)

The actual implementation is very simple:

  1. Label the metric with the view name, the path, and referer values:
    1. To get the view we use the django-prometheus built-in _get_view_name function,
    2. To get the referer we adapt the aforementioned function’s logic to get the referer field from the HTTP request header dict, and lastly,
    3. We get the path from the django request object.
  2. We finally increment the resulting metric
  3. Call the parent method to get all the other metrics.

Last step: plugging everything together

This is the easiest step! We just need to replace django-prometheus middleware with our custom middleware in django settings!

Assuming your custom Middleware is in DjangoSite/MyApp/custom_metrics.py:

MIDDLEWARE = [
    'MyApp.custom_metrics.AppMetricsBeforeMiddleware',
    # .. all other middleware
    'MyApp.custom_metrics.AppMetricsAfterMiddleware'
]

If you go to your /metrics endpoint you should see it:

Custom prometheus metric exported from django

Then is can be exported to prometheus so we can do all the cool things with grafana:

A custom django prometheus metric on grafana

Wrapping up

Although it has some tricks, creating your custom Prometheus metric for your Django application is not very difficult.

For my web analytics use-case, it would be trivial to get the user-agent field to know how my visitors are reading my site, if they are registered users or not, etc.

You might like

A list of the top 5 dokuwiki plugins for 2021

Dokuwiki is a very simple wiki platform that you can self-host. It provides just the right balance between features and complexity. With an ecosystem of plugins, it allows you to customize your wiki to your taste. I’ve searched this ecosystem to personalize mine to the extent where I can use it without battling its rigid “wiki nature”.

Today I want to share some of the plugins that I have used on my personal wiki.


This was the first plugin that I installed— it enables the formatting of the text using markdown rather than the wiki syntax – which makes for a much more enjoying writing experience in general. Note that you can use the two interchangeably, so no dokuwiki formatting feature is lost.

Add new page

https://www.dokuwiki.org/plugin:addnewpage

The default way of creating a new page in DokuWiki is to create a new link from an already existing page — while this ensures that there are no orphans pages, this is cumbersome and not ergonomic. This plugin adds a form that enables you to quickly create a new page.

The risk of creating an orphan page is mitigated with the IndexMenu.

The end result
The dowuki code in the document

IndexMenu

https://www.dokuwiki.org/plugin:indexmenu

The third plugin on this collection creates a list of all the pages under a namespace — with many options for you to customize the filtering and display.

I use it on my main page to have a listing of all the namespaces and pages on my wiki. This makes it super easy to find what I am looking for, and ensures no page goes missing. I also list my most used namespaces (my work notes and programming snippets) there, so I can quickly jump to the info I’m looking for.

There is a interactive option that is useful for large listing, list this one of the entire site
It is simple to dynamically list all the pages under a namespace

Code used to generate the previous lists:

## Tech
// index everything under the tech namespace
{{indexmenu>:tech}}


## Site tree
// index everything on the root namespace using the javascript version
{{indexmenu>:|js}}

* note that I have using markdown for the heading, and not wiki syntax

Move plugin

https://www.dokuwiki.org/plugin:move

You should not be moving your pages manually, it is super tedious and this plugin does it automatically. To fix this, the move plugin painlessly moves and renames pages and namespaces — it then updates all the needed backlinks.
A last note: I’ve had some problems with using this plugin my phone with responsive templates,it only works with the wiki in desktop mode.

Tag

https://www.dokuwiki.org/plugin:tag

The last plugin I want to share breaks the traditional hierarchy of parent and child pages. This plugin lets you assign category tags to wiki pages — which can then be listed and you can find all related pages.

A very interesting use I found was to create a “pinned” tag that I then filter by on my start page. This way I have my most used pages in one place.

A list of all the posts with the tag pinne`
Pinned pages
// shortcut
{{topic>pinned}}
Adding the tag pinned relates this post to the others with the same tag

That was it! Thank you for reading, I hope you enjoying this list!