From a12d059fd487ee0241a5155e8d3d830591e5b7db Mon Sep 17 00:00:00 2001
From: Martyn Welch <martyn.welch@collabora.com>
Date: Tue, 30 Jun 2020 12:00:38 +0100
Subject: [PATCH] Move guides to guides

These documents can be moved to guides more or less as they are.

Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
---
 content/guidelines/api_documentation.md       |   2 +-
 content/guidelines/d-bus_services.md          | 380 ------------------
 content/guidelines/json_parsing.md            | 167 --------
 content/guidelines/processes.md               |   2 +-
 content/{guidelines => guides}/api_design.md  | 173 ++++----
 content/guides/d-bus_services.md              | 352 ++++++++++++++++
 content/{guidelines => guides}/gsettings.md   |   2 +-
 content/guides/json_parsing.md                | 161 ++++++++
 content/{guidelines => guides}/sqlite.md      |  16 +-
 content/{guidelines => guides}/xml_parsing.md |  20 +-
 content/release/15.09/releasenotes.md         |   2 +-
 11 files changed, 622 insertions(+), 655 deletions(-)
 delete mode 100644 content/guidelines/d-bus_services.md
 delete mode 100644 content/guidelines/json_parsing.md
 rename content/{guidelines => guides}/api_design.md (72%)
 create mode 100644 content/guides/d-bus_services.md
 rename content/{guidelines => guides}/gsettings.md (98%)
 create mode 100644 content/guides/json_parsing.md
 rename content/{guidelines => guides}/sqlite.md (86%)
 rename content/{guidelines => guides}/xml_parsing.md (81%)

diff --git a/content/guidelines/api_documentation.md b/content/guidelines/api_documentation.md
index 0f13a77f7..61aad140e 100644
--- a/content/guidelines/api_documentation.md
+++ b/content/guidelines/api_documentation.md
@@ -162,7 +162,7 @@ D-Bus interface descriptions contain documentation comments, and these
 can be extracted from the XML using `gdbus-codegen`, and turned into
 DocBook files to be included by gtk-doc. Generate the documentation
 using the rules described in the [D-Bus services
-guidelines]( {{< ref "/guidelines/d-bus_services.md" >}} ).
+guidelines]( {{< ref "d-bus_services.md" >}} ).
 
 The DocBook files can be included in the main `*-docs.xml` file using:
 
diff --git a/content/guidelines/d-bus_services.md b/content/guidelines/d-bus_services.md
deleted file mode 100644
index 672ef5489..000000000
--- a/content/guidelines/d-bus_services.md
+++ /dev/null
@@ -1,380 +0,0 @@
-+++
-date = "2015-09-08"
-weight = 100
-
-title = "D-Bus Services"
-
-aliases = [
-    "/old-wiki/Guidelines/D-Bus_services"
-]
-+++
-
-# D-Bus services
-
-Most Apertis components communicate with various daemons via D-Bus. The
-D-Bus interfaces exposed by those daemons are public API, and hence must
-be designed as carefully as any C API — changing them is not easy once
-other projects depend on them. D-Bus interfaces are described using an
-[XML
-format](http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format)
-which gives the parameters and types of every method.
-
-## Summary
-
-  - Use GDBus rather than libdbus or libdbus-glib.
-    ([Dependencies](#dependencies))
-  - Install D-Bus interface XML files. ([Interface
-    files](#interface-files))
-  - Version D-Bus interfaces to allow old and new versions to be used in
-    parallel. ([API versioning](#api-versioning))
-  - Use standard D-Bus interfaces (`Properties` and `ObjectManager`)
-    where possible for consistency. ([API
-    design](#api-design))
-  - Design D-Bus APIs to reduce round trips, as they are expensive.
-    ([API design](#api-design))
-  - Use `gdbus-codegen` to generate the low-level C code for
-    implementing a D-Bus API on the server and client side. ([Code
-    generation](#code-generation))
-  - Use `gdbus-codegen` to generate documentation for a D-Bus API and
-    include that in the project’s API documentation.
-    ([Documentation](#documentation))
-  - Never use synchronous calls in the C implementation of a D-Bus
-    service. ([Service
-    implementation](#service-implementation))
-  - Install D-Bus service files. ([Service
-    files](#service-files))
-
-## Dependencies
-
-Use
-[GDBus](https://developer.gnome.org/gio/stable/gdbus-convenience.html),
-which is part of GLib’s GIO. Do *not* use libdbus or libdbus-glib, both
-of which are deprecated, do not integrate well with GLib, and are no
-longer maintained.
-
-To depend on GDBus, add a pkg-config dependency on `gio-2.0` to
-`configure.ac`. There should be no dependency on `dbus-1` or
-`dbus-glib-1`, both of which are for the deprecated libraries.
-
-## Interface files
-
-Interface files should be installed to `$PREFIX/share/dbus-1/interfaces`
-so that other services can introspect them. This can be done with the
-following `Makefile.am` snippet:
-
-    xmldir = $(datadir)/dbus-1/interfaces
-    xml_DATA = org.foo.MyApp.Interface1.xml org.foo.MyApp.Interface2.xml
-
-If an interface defined by project A needs to be used by project B,
-project B should declare a build time dependency on project A, and use
-the installed copy of the interface file for any code generation it has
-to do. It should *not* have a local copy of the interface, as that could
-then go out of sync with the canonical copy in project A’s git
-repository.
-
-### API versioning
-
-[Just like C
-APIs]( {{< ref "/guidelines/module_setup.md#parallel-installability" >}} ),
-D-Bus interfaces should be designed to be parallel-usable with
-API-incompatible versions. This is typically achieved by including a
-version number in each interface name. A full article describing the
-approach is
-[here](http://0pointer.de/blog/projects/versioning-dbus.html).
-
-### API design
-
-D-Bus API design is broadly the same as C API design, but there are a
-few additional points to bear in mind which arise both from D-Bus’
-features (explicit errors, signals and properties), and from its
-implementation as an IPC system — D-Bus method calls are much more
-expensive than C function calls, typically taking on the order of
-milliseconds to complete a round trip. Therefore, the number of method
-calls needed to perform an operation should be minimised by design.
-
-  - Use enumerated values rather than booleans or undocumented ‘magic’
-    integers. This improves documentation, usability of the API, and
-    also allows more values to be added to the enums in future without
-    breaking API as would be needed for a boolean. See also: [Use Enums
-    Not Booleans](http://c2.com/cgi/wiki?UseEnumsNotBooleans).
-  - Use standard, existing D-Bus interfaces where possible. For example,
-    the D-Bus specification defines the
-    [`org.freedesktop.DBus.Properties`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties)
-    and
-    [`org.freedesktop.DBus.ObjectManager`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
-    interfaces, which should be implemented by any object in preference
-    to home-grown solutions.
-      - Specifically, emit the `PropertiesChanged` signal whenever the
-        value of a property changes. This avoids the need for custom
-        ‘\[PropertyName\]Changed’ signals for every property in an
-        interface, and also allows change notifications to be bundled
-        together to reduce IPC round trips. For this reason, properties
-        should be used instead of
-        ‘\[PropertyName\]Get’/‘\[PropertyName\]Set’ getter/setter
-        methods wherever possible.
-      - Note that D-Bus properties can be read-only as well as
-        read-write, so can also replace single getter methods to allow
-        change notification of the property.
-  - Use enumerated values instead of human readable strings. Two D-Bus
-    peers could be running in different locales, which would complicate
-    translation of the value — converting an enumerated value to a human
-    readable string on the client side is much simpler.
-  - Reduce D-Bus round trips by supporting multiple related operations
-    in a single call where possible. For example, a D-Bus method to add
-    an object on the server could be expanded to take an array of
-    parameters, and create multiple objects in a single call, rather
-    than a single one. The logical conclusion of this is the pattern of
-    replacing (e.g.) `InsertEntry(params)` and `RemoveEntry(id)` methods
-    with a `ChangeEntries(a(params_to_insert), a(ids_to_remove))` method
-    and a `EntriesChanged(a(ids_added), a(ids_removed))` signal. In the
-    base case, the arrays in these D-Bus APIs would contain a single
-    element, but could contain more if needed.
-  - Long-running operations should communicate return values via normal
-    D-Bus method returns, rather than via a signal. D-Bus supports
-    asynchronous methods: the server implementation merely needs to
-    delay calling the `g_dbus_method_invocation_return_value()` call for
-    the invocation.
-  - Use D-Bus error returns rather than custom error messages or success
-    codes. This re-uses the D-Bus error infrastructure, bypasses the
-    issue of which values to return in outbound parameters from the
-    method invocation, and allows errors to be highlighted in D-Bus
-    [debugging tools](#debugging).
-  - Follow standard naming conventions for objects, methods and
-    parameters.
-      - Type information should not be included in parameter names (e.g.
-        Hungarian notation).
-      - The convention for D-Bus argument naming is to use
-        `lowercase_with_underscores`
-        [1](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties).
-  - If sending sensitive data over D-Bus (such as passwords),
-    double-check the system D-Bus eavesdropping settings. Eavesdropping
-    should never be enabled on production systems, and should only be
-    enabled on development systems for debugging purposes. Broadcast
-    signals must *not* contain sensitive data, but unicast messages
-    (including method calls, method replies and unicast signals) may.
-  - Ensure integers are signed (signature ‘i’) or unsigned (signature
-    ‘u’) as appropriate.
-  - If specifying multiple parameters as identically-indexed arrays,
-    consider combining the arrays to a single one with tuple elements
-    containing the individual values. e.g. Signature ‘aiauas’ would
-    become ‘a(ius)’, but only if all three arrays were indexed
-    identically.
-  - More generally, expose as much structure in D-Bus types as possible,
-    avoiding structured strings, as they require building on the server
-    side and parsing on the client side, which is extra code, and extra
-    potential for bugs or vulnerabilities.
-  - D-Bus arrays are automatically transmitted with their length, so it
-    does not need to be encoded as a separate parameter.
-
-### Code generation
-
-Rather than manually implementing both the server and client sides of a
-D-Bus interface, automatically generate
-[`GDBusProxy`](https://developer.gnome.org/gio/stable/GDBusProxy.html)
-and
-[`GDBusInterfaceSkeleton`](https://developer.gnome.org/gio/stable/GDBusInterfaceSkeleton.html)
-implementations for all APIs in a D-Bus interface using
-[`gdbus-codegen`](https://developer.gnome.org/gio/stable/gdbus-codegen.html).
-These can then be called from the client and server code to ease
-implementation.
-
-Here’s some standard `Makefile.am` rules to generate the C and H files
-for an interface, then compile them as a library. GLIB_CFLAGS and
-GLIB_LIBS must contain the flags returned by a pkg-config query for
-glib-2.0 gio-2.0.
-
-    # Default values
-    lib_LTLIBRARIES =
-    dbus_sources_xml =
-    dbus_built_docs =
-
-    # Shared values
-    #
-    # Note that as this is all generated code, we disable various warnings.
-    service_cppflags = \
-        $(AM_CPPFLAGS)
-    service_cflags = \
-        -Wno-error \
-        -Wno-strict-aliasing \
-        -fno-strict-aliasing \
-        -Wno-redundant-decls \
-        $(GLIB_CFLAGS) \
-        $(CODE_COVERAGE_CFLAGS) \
-        $(AM_CFLAGS)
-    service_libadd = \
-        $(GLIB_LIBS) \
-        $(CODE_COVERAGE_LIBS) \
-        $(AM_LIBADD)
-    service_ldflags = \
-        $(ERROR_LDFLAGS) \
-        $(AM_LDFLAGS)
-    service_codegen_flags = \
-        --interface-prefix Namespace. \
-        --c-namespace Nspc \
-        --generate-docbook docs \
-        $(NULL)
-
-    # Generic rules
-    %.c %.h: %.xml
-        $(AM_V_GEN)$(GDBUS_CODEGEN) \
-            $(service_codegen_flags) --generate-c-code $* $<
-
-    dbus_sources_h = $(dbus_sources_xml:.xml=.h)
-    dbus_sources_c = $(dbus_sources_xml:.xml=.c)
-
-    EXTRA_DIST = $(dbus_sources_xml)
-    CLEANFILES = $(dbus_sources_h) $(dbus_sources_c) $(dbus_built_docs)
-
-    # Example library containing the interface code
-    example_sources_xml = org.foo.MyApp1.ExampleInterface.xml
-    example_docs_xml = docs-org.foo.MyApp1.ExampleInterface.xml
-
-    dbus_sources_xml += $(example_sources_xml)
-    dbus_built_docs += $(example_docs_xml)
-    $(example_docs_xml): $(example_sources_xml)
-
-    lib_LTLIBRARIES += libexample.la
-    nodist_libexample_la_SOURCES = \
-        $(example_sources_xml:.xml=.c) \
-        $(example_sources_xml:.xml=.h) \
-        $(NULL)
-    libexample_la_CPPFLAGS = $(service_cppflags)
-    libexample_la_CFLAGS = $(service_cflags)
-    libexample_la_LIBADD = $(service_libadd)
-    libexample_la_LDFLAGS = $(service_ldflags)
-
-### Documentation
-
-Also just like C APIs, D-Bus APIs must be documented. The D-Bus
-interface XML format supports inline documentation for each method,
-property and signal, which can then be converted to DocBook format and
-included in the project’s API manual using gdbus-codegen and gtk-doc.
-
-The standard interface rules in [Code
-generation](#code-generation) also generate a DocBook
-documentation file for each D-Bus API. Include these DocBook files in
-the API documentation using the approach described in the [API
-documentation
-guidelines]( {{< ref "/guidelines/api_documentation.md#d-bus-apis" >}} ).
-
-## Service implementation
-
-When implementing a D-Bus service in C using GDBus, a few rules need to
-be followed:
-
-1.  Never use synchronous calls: always use the `*_async()` APIs. D-Bus
-    IPC has no guaranteed latency, so a call may take several seconds,
-    during which time a sync call would be blocking the program’s main
-    loop, preventing it from doing any other work.
-2.  Always respond exactly once to an incoming D-Bus method invocation,
-    either by calling
-    [`g_dbus_method_invocation_return_error()`](https://developer.gnome.org/gio/stable/GDBusMethodInvocation.html#g-dbus-method-invocation-return-error)
-    or
-    [`g_dbus_method_invocation_return_value()`](https://developer.gnome.org/gio/stable/GDBusMethodInvocation.html#g-dbus-method-invocation-return-value).
-    The latter is automatically wrapped as the
-    `[namespace]_[object]_[method]_complete_*()` functions by
-    `gdbus-codegen`.
-
-The second point is important: each D-Bus method invocation should have
-exactly one response, which should either be an error, or a success
-return with zero or more outbound parameters. It is an error for a D-Bus
-method to, e.g., return both an error and then a return value; or for it
-to never return. Doing so would cause a timeout for the caller, and
-potentially memory leaks or use-after-frees.
-
-## Service files
-
-Each D-Bus service must install a `.service` file describing its service
-name and which binary to run to make that service appear. This allows
-for service activation (see ‘Message Bus Starting Services’ in
-[2](http://dbus.freedesktop.org/doc/dbus-specification.html)).
-
-To install a service file for the session bus, use the following
-`Makefile.am`:
-
-    # DBus Activation file
-    servicedir = $(datadir)/dbus-1/services
-    service_in_files = org.foo.MyApp1.service.in
-
-    service_DATA = $(services_in_files:.in=)
-    edit = $(AM_V_GEN)sed \
-           -e 's|@sbindir[@]|$(sbindir)|g' \
-           -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
-           -e 's|@localstatedir[@]|$(localstatedir)|g' \
-           -e 's|@libexecdir[@]|$(libexecdir)|g'
-
-    %.service: %.service.in
-        $(edit) $< >$@
-
-    DISTCLEANFILES = $(service_DATA)
-    EXTRA_DIST = $(service_in_files)
-
-Service files for the system bus have to be installed elsewhere, but
-also typically require an accompanying D-Bus configuration file to set
-their security policy, which is beyond the scope of this document.
-
-## Debugging
-
-Debugging D-Bus can be tricky, as it is a core system service. Three
-main tools are available: dbus-monitor, Bustle and D-Feet.
-
-### dbus-monitor
-
-[dbus-monitor](http://dbus.freedesktop.org/doc/dbus-monitor.1.html)
-allows monitoring of D-Bus messages as they are sent, outputting them to
-the console. It supports [filtering the messages according to D-Bus
-match
-rules](https://wiki.ubuntu.com/DebuggingDBus#Filtering_all_the_noise).
-The session bus can be monitored using:
-
-    dbus-monitor --session
-
-and match rules applied as:
-
-    dbus-monitor "type=error" "sender=org.freedesktop.SystemToolsBackends"
-
-(which will print messages matching either of the two rules: so all
-errors, and all messages originating from the
-org.freedesktop.SystemToolsBackends peer).
-
-Because we have dbus-daemon newer than 1.9.10,
-
-    sudo dbus-monitor --system
-
-can be used to monitor the system bus; reconfiguring it is not necessary
-(but you do have to be root, e.g. using sudo).
-
-### D-Feet
-
-[D-Feet](https://wiki.gnome.org/Apps/DFeet) is an explorer for a D-Bus
-bus. It connects to the bus, and displays all clients and objects
-currently available on the bus. The objects can be inspected, and their
-methods called directly. It is valuable for verifying that a service is
-exporting the expected objects to the bus, and that the objects’ methods
-can be called as expected.
-
-### Bustle
-
-[Bustle](http://willthompson.co.uk/bustle/) is a more advanced version
-of [dbus-monitor](#dbus-monitor) which displays D-Bus
-calls graphically, including timing data. It is intended for profiling
-IPC performance by highlighting D-Bus calls which happen frequently or
-take a long time. It can be used as a general replacement for
-dbus-monitor, though.
-
-There is a presentation available on [profiling D-Bus APIs using
-Bustle](http://willthompson.co.uk/talks/profiling-and-optimizing-d-bus-apis.pdf).
-
-## External links
-
-  - [D-Bus
-    specification](http://dbus.freedesktop.org/doc/dbus-specification.html)
-  - [GDBus API
-    documentation](https://developer.gnome.org/gio/stable/gdbus-convenience.html)
-  - [Article on versioning D-Bus
-    APIs](http://0pointer.de/blog/projects/versioning-dbus.html)
-  - [dbus-monitor](http://dbus.freedesktop.org/doc/dbus-monitor.1.html)
-  - [D-Feet](https://wiki.gnome.org/Apps/DFeet)
-  - [Bustle](http://willthompson.co.uk/bustle/)
-  - [Profiling APIs with
-    Bustle](http://willthompson.co.uk/talks/profiling-and-optimizing-d-bus-apis.pdf)
diff --git a/content/guidelines/json_parsing.md b/content/guidelines/json_parsing.md
deleted file mode 100644
index 8c448c7cd..000000000
--- a/content/guidelines/json_parsing.md
+++ /dev/null
@@ -1,167 +0,0 @@
-+++
-date = "2015-09-08"
-weight = 100
-
-title = "JSON parsing"
-
-aliases = [
-    "/old-wiki/Guidelines/JSON_parsing"
-]
-+++
-
-# JSON parsing
-
-JSON is used for various formats within Apertis, and potentially also
-for various web APIs. It is a well defined format, and several mature
-libraries exist for parsing it. However, the JSON being parsed typically
-comes from untrusted sources (user input or untrusted web APIs), so must
-be validated extremely carefully to prevent exploits.
-
-## Summary
-
-  - Use a standard library to parse JSON, such as json-glib. ([Parsing
-    JSON](#parsing-json))
-  - Be careful to pair up JSON reader functions on all code paths.
-    ([Parsing JSON](#parsing-json))
-  - Write a JSON schema for each JSON format in use. ([Schema
-    validation](#schema-validation))
-  - Use Walbottle to validate JSON schemas and documents. ([Schema
-    validation](#schema-validation))
-  - Use Walbottle to generate test vectors for unit testing JSON reader
-    code. ([Unit testing](#unit-testing))
-
-## Parsing JSON
-
-JSON should be parsed using a standard library, such as
-[json-glib](https://developer.gnome.org/json-glib/stable/). That will
-take care of checking the JSON for well-formedness and safely parsing
-the values it contains. The output from json-glib is a hierarchy of
-parsed JSON nodes which may be values, arrays or objects. The Apertis
-code must then extract the data it requires from this hierarchy. This
-navigation of the hierarchy is still security critical, as the parsed
-JSON document may not conform to the expected format (the *schema* for
-that document). See [Schema
-validation](#schema-validation) for more information on
-this.
-
-When using json-glib, the
-[`JsonReader`](https://developer.gnome.org/json-glib/stable/JsonReader.html)
-object is typically used to navigate a parsed JSON document and extract
-the required data. A common pitfall is to not pair calls to
-[`json_reader_read_member()`](https://developer.gnome.org/json-glib/stable/JsonReader.html#json-reader-read-member)
-and
-[`json_reader_end_member()`](https://developer.gnome.org/json-glib/stable/JsonReader.html#json-reader-end-member).
-
-For example:
-
-    gint
-    read_some_member (JsonReader *reader)
-    {
-      gint retval;
-
-      /* This code is incorrect. */
-      if (!json_reader_read_member (reader, "member-name"))
-        {
-          return -1;
-        }
-
-      retval = json_reader_read_int (reader);
-      json_reader_end_member (reader);
-
-      return retval;
-    }
-
-This code is incorrect because `json_reader_end_member()` is not called
-on the code path where the `member-name` member doesn’t exist. That
-leaves the `JsonReader` in an error state, and any remaining read
-operations will silently fail.
-
-Instead, the following should be done:
-
-    gint
-    read_some_member (JsonReader *reader)
-    {
-      gint retval = -1;
-
-      if (json_reader_read_member (reader, "member-name"))
-        {
-          retval = json_reader_read_int (reader);
-        }
-
-      json_reader_end_member (reader);
-
-      return retval;
-    }
-
-The same is true of other APIs, such as
-[`json_reader_read_element()`](https://developer.gnome.org/json-glib/stable/JsonReader.html#json-reader-read-element).
-Read the API documentation for json-glib functions carefully to check
-whether the function will put the `JsonReader` into an error state on
-failure and, if so, how to get it out of that error state.
-
-## Schema validation
-
-Ideally, all JSON formats will have an accompanying [JSON
-schema](http://json-schema.org/) which describes the expected structure
-of the JSON files. A JSON schema is analogous to an XML schema for XML
-documents. If a schema exists for a JSON document which is stored in git
-(such as a UI definition), that document can be validated at compile
-time, which can help catch problems without the need for runtime
-testing.
-
-One tool for this is
-[Walbottle](http://people.collabora.com/~pwith/walbottle/), which allows
-validation of JSON documents against schemas. Given a schema called
-`schema.json` and two JSON documents called `example1.json` and
-`example2.json`, the following `Makefile.am` snippets will validate them
-at compile time:
-
-    json_schema_files = schema.json
-    json_files = example1.json example2.json
-
-    check-local: check-json-schemas check-json
-
-    check-json-schemas: $(json_schema_files)
-        json-schema-validate --ignore-errors $^
-    check-json: $(json_schema_files) $(json_files)
-        json-validate --ignore-errors $(addprefix --schema=,$(json_schema_files)) $(json_files)
-
-    .PHONY: check-json-schemas check-json
-
-## Unit testing
-
-Due to the susceptibility of JSON handling code to break on invalid
-input (as it assumes the input follows the correct schema, which it may
-not, as it’s untrusted), it is important to unit test such code. See the
-[Unit testing guidelines]( {{< ref "/guidelines/unit_testing.md" >}} ) for
-suggestions on writing code for testing. The ideal is for the JSON
-parsing code to be separated from whatever code calls it, so that it can
-be linked into unit tests by itself, and passed JSON snippets to check
-what it retrieves from them.
-
-Thinking of JSON snippets which thoroughly test parsing and validation
-code is hard, and is impossible to do without also using code coverage
-metrics (see the [Tooling
-guidelines]( {{< ref "/guidelines/tooling.md#code-coverage" >}} )). However,
-given a JSON schema for the document, it is possible to automatically
-and exhaustively generate [unit test
-vectors](http://en.wikipedia.org/wiki/Test_vector) which can be easily
-copied into the unit tests to give good coverage.
-
-This can be done using Walbottle:
-
-    json-schema-generate --valid-only schema.json
-    json-schema-generate --invalid-only schema.json
-
-That command will generate sets of valid and invalid test vectors, each
-of which is a JSON instance which may or may not conform to the given
-schema.
-
-## External links
-
-  - [JSON website](http://www.json.org/)
-  - [JSON Schema website](http://json-schema.org/)
-  - [json-glib website](https://wiki.gnome.org/Projects/JsonGlib)
-  - [json-glib
-    documentation](https://developer.gnome.org/json-glib/stable/)
-  - [Walbottle website](http://people.collabora.com/~pwith/walbottle/)
diff --git a/content/guidelines/processes.md b/content/guidelines/processes.md
index ddf605cb3..d036a6306 100644
--- a/content/guidelines/processes.md
+++ b/content/guidelines/processes.md
@@ -41,7 +41,7 @@ allows for greater interaction between the parent process and the task.
 
 Subprocesses should not be used to implement functionality which could
 be implemented by [D-Bus service
-daemons]( {{< ref "/guidelines/d-bus_services.md" >}} ).
+daemons]( {{< ref "d-bus_services.md" >}} ).
 
 When using subprocesses, closed-loop management should be used, by
 monitoring the child process’ PID after sending it kill signals, and
diff --git a/content/guidelines/api_design.md b/content/guides/api_design.md
similarity index 72%
rename from content/guidelines/api_design.md
rename to content/guides/api_design.md
index 086349d3f..505f303a5 100644
--- a/content/guidelines/api_design.md
+++ b/content/guides/api_design.md
@@ -13,28 +13,29 @@ This page describes some general API design principles which are useful
 to bear in mind when designing APIs (whether those APIs are for C, C++,
 JavaScript, D-Bus, or something else).
 
-## Summary
-
-  - API designs must make sense from the point of view of a third-party
-    app developer ([start by designing high-level
-    APIs](#high-level-api), [only add daemons if it is
-    necessary](#fewer-daemons))
-  - Interfaces that don't have to be API should not be API ([minimize
-    surface area](#surface-area))
-  - [Follow GNOME/GObject conventions](#gnome-conventions),
-    so that we get JavaScript bindings automatically
-  - [Use existing frameworks](#reuse) where we can; if we
-    can't use them directly, learn from their design
-  - [Identify privilege boundaries](#privilege-boundary), do
-    not trust less-privileged components, and [consider whether some
-    features should be restricted](#restricted-features)
-
-## <span id="surface-area">Minimize "surface area"</span>
-
-The "SDK API" is intended to remain stable/compatible over time, which
-means that we are committing to interfaces in the "SDK API" continuing
-to work in future: third-party code that uses stable Apertis APIs must
-continue to work in future, without needing changes.
+# Summary
+
+- API designs must make sense from the point of view of a third-party app
+  developer
+  ([start by designing high-level APIs]( {{< ref "#start-from-the-api-that-the-app-developer-will-use" >}} ),
+  [only add daemons if it is necessary]( {{< ref "#have-as-few-daemons-as-possible-but-no-fewer" >}} ))
+- Interfaces that don't have to be API should not be API
+  ([minimize surface area]( {{< ref "#minimize-surface-area" >}} ))
+- [Follow GNOME/GObject conventions]( {{< ref "#follow-gnome-conventions" >}} ), so
+  that we get JavaScript bindings automatically
+- [Use existing frameworks]( {{< ref "#use-existing-software-or-if-we-cant-learn-from-it" >}} ) where we can; if we can't
+  use them directly, learn from their design
+- [Identify privilege boundaries]( {{< ref "#be-aware-of-where-the-privilege-boundaries-are" >}} ), do not
+  trust less-privileged components, and
+ [consider whether some features should be restricted]( {{< ref "#think-about-how-much-we-want-the-app-to-be-allowed-to-do" >}} )
+
+# Minimize "surface area"
+
+The "SDK API" is intended to remain stable/compatible over time, which means
+that we are
+[committing to interfaces](https://designs.apertis.org/latest/supported-api.html#api-support-levels)
+in the "SDK API" continuing to work in future: third-party code that uses
+stable Apertis APIs should continue to work in future, without needing changes.
 
 As a result, one of the most important questions to ask about new public
 interfaces is: does this *need* to be public API right now? If it
@@ -50,33 +51,34 @@ regret it in future.
 
 Some examples of applying that principle:
 
-  - hiding struct contents by using a MyObjectPrivate struct instead of
-    putting members in the MyObject struct (in GObject, use
-    [G_ADD_PRIVATE()](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#G-ADD-PRIVATE:CAPS)
-    or
-    [G_DEFINE_TYPE_WITH_PRIVATE()](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#G-DEFINE-TYPE-WITH-PRIVATE:CAPS))
-  - considering the D-Bus API between a built-in or otherwise special
-    app, and the system components it uses, to be private
-  - if in doubt, making things private initially, and making them public
-    if it later proves to be necessary
+- hiding struct contents by using a `MyObjectPrivate` struct instead of putting
+  members in the `MyObject` struct (in GObject, use
+  [G_ADD_PRIVATE()](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#G-ADD-PRIVATE:CAPS)
+  or
+  [G_DEFINE_TYPE_WITH_PRIVATE()](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#G-DEFINE-TYPE-WITH-PRIVATE:CAPS))
+- considering the D-Bus API between a built-in or otherwise special app, and
+  the system components it uses, to be private
 
-## <span id="fewer-daemons">Have as few daemons as possible, but no fewer</span>
+If in doubt, making things private initially, and making them public if it
+later proves to be necessary
+
+# Have as few daemons as possible, but no fewer
 
 Sometimes it's necessary to have more than one process (app code talking
 to a daemon/service/agent, typically a [D-Bus
-service]( {{< ref "/guidelines/d-bus_services.md" >}} )). There are lots of good
+service]( {{< ref "d-bus_services.md" >}} )). There are lots of good
 reasons to do that:
 
-  - having a [privilege boundary](#privilege-boundary)
-  - mediating between multiple processes that all want to manipulate the
-    state of the same object (for instance,
-    [Barkway](https://git.apertis.org/cgit/barkway.git/) decides the
-    order of the popup stack, which is global shared state)
-  - having something persist in the background when switching between
-    apps or closing/reopening apps (for instance,
-    [Telepathy](http://telepathy.freedesktop.org/wiki/) puts telephony,
-    instant messaging and other real-time communications in the
-    background)
+- having a [privilege boundary]({{< ref "#be-aware-of-where-the-privilege-boundaries-are" >}})
+- mediating between multiple processes that all want to manipulate the
+  state of the same object (for instance,
+  [Barkway](https://git.apertis.org/cgit/barkway.git/) decides the
+  order of the popup stack, which is global shared state)
+- having something persist in the background when switching between
+  apps or closing/reopening apps (for instance,
+  [Telepathy](http://telepathy.freedesktop.org/wiki/) puts telephony,
+  instant messaging and other real-time communications in the
+  background)
 
 However, every time we introduce inter-process communication between two
 components, we increase the complexity of the system, which increases
@@ -98,7 +100,7 @@ Shell](https://wiki.gnome.org/Projects/GnomeShell) puts notifications
 and the window manager (among other things) in the same process. If the
 requirements allow it, we should do the same.
 
-## <span id="privilege-boundary">Be aware of where the privilege boundaries are</span>
+# Be aware of where the privilege boundaries are
 
 Not all of the code in Apertis is equally-privileged: components that
 run as root are more privileged than components that run as the user,
@@ -138,13 +140,13 @@ dbus-daemon, and can be trusted. If we can derive the app name from the
 AppArmor profile, then that cannot be faked either, so we can reliably
 identify an app by its profile.
 
-## <span id="high-level-api">Start from the API that the app developer will use</span>
+# Start from the API that the app developer will use
 
-This is related to the [surface area](#surface-area) and
-[fewer daemons](#fewer-daemons) reasoning above. The
-requirements for our SDK APIs take the form "third-party apps should be
-able to do X, Y and Z". In many cases, it is tempting to address this by
-providing a D-Bus API that the third-party app can use, with
+This is related to the [surface area]( {{< ref "#minimize-surface-area" >}} )
+and [fewer daemons]( {{< ref "#have-as-few-daemons-as-possible-but-no-fewer" >}} )
+reasoning above. The requirements for our SDK APIs take the form "third-party
+apps should be able to do X, Y and Z". In many cases, it is tempting to address
+this by providing a D-Bus API that the third-party app can use, with
 auto-generated GDBus C "bindings".
 
 In Collabora's experience, auto-generated code has limits: it's often
@@ -171,24 +173,23 @@ indication that the result is going to be something that apps can use.
 
 Because we intend to use
 [GObject-Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection)
-to provide JavaScript versions of the SDK APIs, the C API translates
-directly into a JavaScript API, so making a high-quality C API that
-follows GObject conventions translates directly into improving the
-JavaScript API. If we do not [follow GNOME API
-conventions](#gnome-conventions) then GObject-Introspection
-will not give us a usable JavaScript API.
+to provide JavaScript versions of the SDK APIs, the C API translates directly
+into a JavaScript API, so making a high-quality C API that follows GObject
+conventions translates directly into improving the JavaScript API. If we do not
+[follow GNOME API conventions]( {{< ref "#follow-gnome-conventions" >}} ) then
+GObject-Introspection will not give us a usable JavaScript API.
 
-## <span id="restricted-features">Think about how much we want the app to be allowed to do</span>
+# Think about how much we want the app to be allowed to do
 
 This is not normally a concern, but in Apertis it is, because there's a
 privilege boundary between apps (whether our apps or third-party apps).
 We need to consider (and document) which of these categories each
 feature is in:
 
-  - all apps (including third-party ones) should be able to do this
-  - apps should be able to do this if they have some special flag in
-    their manifest
-  - only trusted components within Apertis should be able to do this
+- all apps (including third-party ones) should be able to do this
+- apps should be able to do this if they have some special flag in
+  their manifest
+- only trusted components within Apertis should be able to do this
 
 For instance, in Android, all apps can write to /sdcard; only apps that
 have asked for the "permission" can record audio; and only trusted
@@ -206,7 +207,7 @@ volume, whereas the worst case for recording is sending private
 conversations to the Internet. So recording and playback should have a
 clear division between them.
 
-## <span id="gnome-conventions">Follow GNOME conventions</span>
+# Follow GNOME conventions
 
 Our platform includes a lot of GNOME-related libraries such as GLib and
 Clutter, and our API guidelines follow GObject/GNOME style quite
@@ -229,29 +230,29 @@ See [the Coding
 Conventions](https://designs.apertis.org/latest/coding_conventions.html)
 for more on this topic, but here is a brief summary:
 
-  - namespace objects with the library's appropriate prefix
-  - use GLib naming conventions: CapitalizedWords for types;
-    CAPITALS_AND_UNDERSCORES for constants;
-    lowercase_and_underscores for parameters, struct members and
-    variables
-  - avoid Hungarian notation (pSomePointer, v_func_returning_void(),
-    etc.)
-  - use
-    [GError](https://developer.gnome.org/glib/stable/glib-Error-Reporting.html)
-    to report recoverable runtime errors
-  - use
-    [`g_return_[val_]if_fail()`](https://designs.apertis.org/latest/coding_conventions.html#pre-and-postcondition-assertions)
-    to report failed precondition checks and other library-user errors
-  - use GObject features where appropriate: signals, properties,
-    construct-time properties, virtual methods (vfuncs)
-  - use GIO features where appropriate: GAsyncResult, GCancellable,
-    GTask
-  - prefer to use GAsyncResult instead of your own function typedef for
-    asynchronous operations
-  - prefer to use signals instead of your own function typedef for
-    events
-
-## <span id="reuse">Use existing software, or if we can't, learn from it</span>
+- namespace objects with the library's appropriate prefix
+- use GLib naming conventions: CapitalizedWords for types;
+  CAPITALS_AND_UNDERSCORES for constants;
+  lowercase_and_underscores for parameters, struct members and
+  variables
+- avoid Hungarian notation (pSomePointer, v_func_returning_void(),
+  etc.)
+- use
+  [GError](https://developer.gnome.org/glib/stable/glib-Error-Reporting.html)
+  to report recoverable runtime errors
+- use
+  [`g_return_[val_]if_fail()`](https://designs.apertis.org/latest/coding_conventions.html#pre-and-postcondition-assertions)
+  to report failed precondition checks and other library-user errors
+- use GObject features where appropriate: signals, properties,
+  construct-time properties, virtual methods (vfuncs)
+- use GIO features where appropriate: GAsyncResult, GCancellable,
+  GTask
+- prefer to use GAsyncResult instead of your own function typedef for
+  asynchronous operations
+- prefer to use signals instead of your own function typedef for
+  events
+
+# Use existing software, or if we can't, learn from it
 
 Several components in Apertis overlap with existing open-source
 projects, in which people have already spent a lot of time understanding
@@ -288,7 +289,7 @@ perhaps the difference points to a design issue in our API, which would
 mean we can improve it by correcting that design issue, and get a better
 outcome.
 
-## API review process
+# API review process
 
 Before a public API may be marked as stable and suitable for use by third-party
 apps, it must be reviewed. The process for this is:
diff --git a/content/guides/d-bus_services.md b/content/guides/d-bus_services.md
new file mode 100644
index 000000000..82ce503db
--- /dev/null
+++ b/content/guides/d-bus_services.md
@@ -0,0 +1,352 @@
++++
+date = "2015-09-08"
+weight = 100
+
+title = "D-Bus Services"
+
+aliases = [
+    "/old-wiki/Guidelines/D-Bus_services"
+]
++++
+
+# D-Bus services
+
+Most Apertis components communicate with various daemons via D-Bus. The D-Bus
+interfaces exposed by those daemons are public API, and hence must be designed
+as carefully as any C API — changing them is not easy once other projects
+depend on them. D-Bus interfaces are described using an
+[XML format](http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format)
+which gives the parameters and types of every method.
+
+## Summary
+
+- Use GDBus rather than libdbus or libdbus-glib.
+  ([Dependencies]( {{< ref "d-bus_services.md#dependencies" >}} ))
+- Install D-Bus interface XML files. ([Interface files]( {{< ref "d-bus_services.md#interface-files" >}} ))
+- Version D-Bus interfaces to allow old and new versions to be used in
+  parallel. ([API versioning]( {{< ref "d-bus_services.md#api-versioning" >}} ))
+- Use standard D-Bus interfaces (`Properties` and `ObjectManager`) where
+  possible for consistency. ([API design]( {{< ref "d-bus_services.md#api-design" >}} ))
+- Design D-Bus APIs to reduce round trips, as they are expensive.
+  ([API design]( {{< ref "d-bus_services.md#api-design" >}} ))
+- Use `gdbus-codegen` to generate the low-level C code for implementing a D-Bus
+  API on the server and client side. ([Code generation]( {{< ref "d-bus_services.md#code-generation" >}} ))
+- Use `gdbus-codegen` to generate documentation for a D-Bus API and include
+  that in the project’s API documentation.  ([Documentation]( {{< ref "d-bus_services.md#documentation" >}} ))
+- Never use synchronous calls in the C implementation of a D-Bus service.
+  ([Service implementation]( {{< ref "d-bus_services.md#service-implementation" >}} ))
+- Install D-Bus service files. ([Service files]( {{< ref "d-bus_services.md#service-files" >}} ))
+
+## Dependencies
+
+Use [GDBus](https://developer.gnome.org/gio/stable/gdbus-convenience.html),
+which is part of GLib’s GIO. Do *not* use libdbus or libdbus-glib, both of
+which are deprecated, do not integrate well with GLib, and are no longer
+maintained.
+
+To depend on GDBus, add a pkg-config dependency on `gio-2.0` to `configure.ac`.
+There should be no dependency on `dbus-1` or `dbus-glib-1`, both of which are
+for the deprecated libraries.
+
+## Interface files
+
+Interface files should be installed to `$PREFIX/share/dbus-1/interfaces` so
+that other services can introspect them. This can be done with the following
+`Makefile.am` snippet:
+
+    xmldir = $(datadir)/dbus-1/interfaces
+    xml_DATA = org.foo.MyApp.Interface1.xml org.foo.MyApp.Interface2.xml
+
+If an interface defined by project A needs to be used by project B, project B
+should declare a build time dependency on project A, and use the installed copy
+of the interface file for any code generation it has to do. It should *not*
+have a local copy of the interface, as that could then go out of sync with the
+canonical copy in project A’s git repository.
+
+### API versioning
+
+[Just like C APIs]( {{< ref "/guidelines/module_setup.md#parallel-installability" >}} ),
+D-Bus interfaces should be designed to be parallel-usable with
+API-incompatible versions. This is typically achieved by including a version
+number in each interface name. A full article describing the approach is
+[here](http://0pointer.de/blog/projects/versioning-dbus.html).
+
+### API design
+
+D-Bus API design is broadly the same as C API design, but there are a few
+additional points to bear in mind which arise both from D-Bus’ features
+(explicit errors, signals and properties), and from its implementation as an
+IPC system — D-Bus method calls are much more expensive than C function calls,
+typically taking on the order of milliseconds to complete a round trip.
+Therefore, the number of method calls needed to perform an operation should be
+minimised by design.
+
+- Use enumerated values rather than booleans or undocumented ‘magic’ integers.
+  This improves documentation, usability of the API, and also allows more
+  values to be added to the enums in future without breaking API as would be
+  needed for a boolean. See also:
+  [Use Enums Not Booleans](http://c2.com/cgi/wiki?UseEnumsNotBooleans).
+- Use standard, existing D-Bus interfaces where possible. For example, the
+  D-Bus specification defines the
+  [`org.freedesktop.DBus.Properties`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties)
+  and
+  [`org.freedesktop.DBus.ObjectManager`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
+  interfaces, which should be implemented by any object in preference to
+  home-grown solutions.
+  - Specifically, emit the `PropertiesChanged` signal whenever the value of a
+    property changes. This avoids the need for custom ‘\[PropertyName\]Changed’
+    signals for every property in an interface, and also allows change
+    notifications to be bundled together to reduce IPC round trips. For this
+    reason, properties should be used instead of
+    ‘\[PropertyName\]Get’/‘\[PropertyName\]Set’ getter/setter methods wherever
+    possible.
+  - Note that D-Bus properties can be read-only as well as read-write, so can
+    also replace single getter methods to allow change notification of the
+    property.
+- Use enumerated values instead of human readable strings. Two D-Bus peers
+  could be running in different locales, which would complicate translation of
+  the value — converting an enumerated value to a human readable string on the
+  client side is much simpler.
+- Reduce D-Bus round trips by supporting multiple related operations in a
+  single call where possible. For example, a D-Bus method to add an object on
+  the server could be expanded to take an array of parameters, and create
+  multiple objects in a single call, rather than a single one. The logical
+  conclusion of this is the pattern of replacing (e.g.) `InsertEntry(params)` and
+  `RemoveEntry(id)` methods with a `ChangeEntries(a(params_to_insert),
+  a(ids_to_remove))` method and a `EntriesChanged(a(ids_added),
+  a(ids_removed))` signal. In the base case, the arrays in these D-Bus APIs
+  would contain a single element, but could contain more if needed.
+- Long-running operations should communicate return values via normal D-Bus
+  method returns, rather than via a signal. D-Bus supports asynchronous
+  methods: the server implementation merely needs to delay calling the
+  `g_dbus_method_invocation_return_value()` call for the invocation.
+- Use D-Bus error returns rather than custom error messages or success codes.
+  This re-uses the D-Bus error infrastructure, bypasses the issue of which
+  values to return in outbound parameters from the method invocation, and
+  allows errors to be highlighted in D-Bus
+  [debugging tools]( {{< ref "d-bus_services.md#debugging" >}} ).
+- Follow standard naming conventions for objects, methods and parameters.
+  - Type information should not be included in parameter names (e.g.  Hungarian
+    notation).
+  - The convention for D-Bus argument naming is to use
+    `lowercase_with_underscores`
+    [1](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties).
+- If sending sensitive data over D-Bus (such as passwords), double-check the
+  system D-Bus eavesdropping settings. Eavesdropping should never be enabled on
+  production systems, and should only be enabled on development systems for
+  debugging purposes. Broadcast signals must *not* contain sensitive data, but
+  unicast messages (including method calls, method replies and unicast signals)
+  may.
+- Ensure integers are signed (signature ‘i’) or unsigned (signature ‘u’) as
+  appropriate.
+- If specifying multiple parameters as identically-indexed arrays, consider
+  combining the arrays to a single one with tuple elements containing the
+  individual values. e.g. Signature ‘aiauas’ would become ‘a(ius)’, but only if
+  all three arrays were indexed identically.
+- More generally, expose as much structure in D-Bus types as possible, avoiding
+  structured strings, as they require building on the server side and parsing
+  on the client side, which is extra code, and extra potential for bugs or
+  vulnerabilities.
+- D-Bus arrays are automatically transmitted with their length, so it does not
+  need to be encoded as a separate parameter.
+
+### Code generation
+
+Rather than manually implementing both the server and client sides of a D-Bus
+interface, automatically generate
+[`GDBusProxy`](https://developer.gnome.org/gio/stable/GDBusProxy.html) and
+[`GDBusInterfaceSkeleton`](https://developer.gnome.org/gio/stable/GDBusInterfaceSkeleton.html)
+implementations for all APIs in a D-Bus interface using
+[`gdbus-codegen`](https://developer.gnome.org/gio/stable/gdbus-codegen.html).
+These can then be called from the client and server code to ease
+implementation.
+
+Here’s some standard `Makefile.am` rules to generate the C and H files for an
+interface, then compile them as a library. GLIB_CFLAGS and GLIB_LIBS must
+contain the flags returned by a pkg-config query for glib-2.0 gio-2.0.
+
+    # Default values
+    lib_LTLIBRARIES =
+    dbus_sources_xml =
+    dbus_built_docs =
+
+    # Shared values
+    #
+    # Note that as this is all generated code, we disable various warnings.
+    service_cppflags = \
+        $(AM_CPPFLAGS)
+    service_cflags = \
+        -Wno-error \
+        -Wno-strict-aliasing \
+        -fno-strict-aliasing \
+        -Wno-redundant-decls \
+        $(GLIB_CFLAGS) \
+        $(CODE_COVERAGE_CFLAGS) \
+        $(AM_CFLAGS)
+    service_libadd = \
+        $(GLIB_LIBS) \
+        $(CODE_COVERAGE_LIBS) \
+        $(AM_LIBADD)
+    service_ldflags = \
+        $(ERROR_LDFLAGS) \
+        $(AM_LDFLAGS)
+    service_codegen_flags = \
+        --interface-prefix Namespace. \
+        --c-namespace Nspc \
+        --generate-docbook docs \
+        $(NULL)
+
+    # Generic rules
+    %.c %.h: %.xml
+        $(AM_V_GEN)$(GDBUS_CODEGEN) \
+            $(service_codegen_flags) --generate-c-code $* $<
+
+    dbus_sources_h = $(dbus_sources_xml:.xml=.h)
+    dbus_sources_c = $(dbus_sources_xml:.xml=.c)
+
+    EXTRA_DIST = $(dbus_sources_xml)
+    CLEANFILES = $(dbus_sources_h) $(dbus_sources_c) $(dbus_built_docs)
+
+    # Example library containing the interface code
+    example_sources_xml = org.foo.MyApp1.ExampleInterface.xml
+    example_docs_xml = docs-org.foo.MyApp1.ExampleInterface.xml
+
+    dbus_sources_xml += $(example_sources_xml)
+    dbus_built_docs += $(example_docs_xml)
+    $(example_docs_xml): $(example_sources_xml)
+
+    lib_LTLIBRARIES += libexample.la
+    nodist_libexample_la_SOURCES = \
+        $(example_sources_xml:.xml=.c) \
+        $(example_sources_xml:.xml=.h) \
+        $(NULL)
+    libexample_la_CPPFLAGS = $(service_cppflags)
+    libexample_la_CFLAGS = $(service_cflags)
+    libexample_la_LIBADD = $(service_libadd)
+    libexample_la_LDFLAGS = $(service_ldflags)
+
+### Documentation
+
+Also just like C APIs, D-Bus APIs must be documented. The D-Bus interface XML
+format supports inline documentation for each method, property and signal,
+which can then be converted to DocBook format and included in the project’s API
+manual using gdbus-codegen and gtk-doc.
+
+The standard interface rules in
+[Code generation]( {{< ref "d-bus_services.md#code-generation" >}} ) also
+generate a DocBook documentation file for each D-Bus API. Include these DocBook
+files in the API documentation using the approach described in the
+[API documentation guidelines]( {{< ref "/guidelines/api_documentation.md#d-bus-apis" >}} ).
+
+## Service implementation
+
+When implementing a D-Bus service in C using GDBus, a few rules need to be
+followed:
+
+1. Never use synchronous calls: always use the `*_async()` APIs. D-Bus
+   IPC has no guaranteed latency, so a call may take several seconds,
+   during which time a sync call would be blocking the program’s main
+   loop, preventing it from doing any other work.
+2. Always respond exactly once to an incoming D-Bus method invocation,
+   either by calling
+   [`g_dbus_method_invocation_return_error()`](https://developer.gnome.org/gio/stable/GDBusMethodInvocation.html#g-dbus-method-invocation-return-error)
+   or
+   [`g_dbus_method_invocation_return_value()`](https://developer.gnome.org/gio/stable/GDBusMethodInvocation.html#g-dbus-method-invocation-return-value).
+   The latter is automatically wrapped as the
+   `[namespace]_[object]_[method]_complete_*()` functions by
+   `gdbus-codegen`.
+
+The second point is important: each D-Bus method invocation should have exactly
+one response, which should either be an error, or a success return with zero or
+more outbound parameters. It is an error for a D-Bus method to, e.g., return
+both an error and then a return value; or for it to never return. Doing so
+would cause a timeout for the caller, and potentially memory leaks or
+use-after-frees.
+
+## Service files
+
+Each D-Bus service must install a `.service` file describing its service name
+and which binary to run to make that service appear. This allows for service
+activation (see ‘Message Bus Starting Services’ in
+[2](http://dbus.freedesktop.org/doc/dbus-specification.html)).
+
+To install a service file for the session bus, use the following `Makefile.am`:
+
+    # DBus Activation file
+    servicedir = $(datadir)/dbus-1/services
+    service_in_files = org.foo.MyApp1.service.in
+
+    service_DATA = $(services_in_files:.in=)
+    edit = $(AM_V_GEN)sed \
+           -e 's|@sbindir[@]|$(sbindir)|g' \
+           -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
+           -e 's|@localstatedir[@]|$(localstatedir)|g' \
+           -e 's|@libexecdir[@]|$(libexecdir)|g'
+
+    %.service: %.service.in
+        $(edit) $< >$@
+
+    DISTCLEANFILES = $(service_DATA)
+    EXTRA_DIST = $(service_in_files)
+
+Service files for the system bus have to be installed elsewhere, but also
+typically require an accompanying D-Bus configuration file to set their
+security policy, which is beyond the scope of this document.
+
+## Debugging
+
+Debugging D-Bus can be tricky, as it is a core system service. Three main tools
+are available: dbus-monitor, Bustle and D-Feet.
+
+### dbus-monitor
+
+[dbus-monitor](http://dbus.freedesktop.org/doc/dbus-monitor.1.html) allows
+monitoring of D-Bus messages as they are sent, outputting them to the console.
+It supports
+[filtering the messages according to D-Bus match rules](https://wiki.ubuntu.com/DebuggingDBus#Filtering_all_the_noise).
+The session bus can be monitored using:
+
+    dbus-monitor --session
+
+and match rules applied as:
+
+    dbus-monitor "type=error" "sender=org.freedesktop.SystemToolsBackends"
+
+(which will print messages matching either of the two rules: so all errors, and
+all messages originating from the org.freedesktop.SystemToolsBackends peer).
+
+Because we have dbus-daemon newer than 1.9.10,
+
+    sudo dbus-monitor --system
+
+can be used to monitor the system bus; reconfiguring it is not necessary (but
+you do have to be root, e.g. using sudo).
+
+### D-Feet
+
+[D-Feet](https://wiki.gnome.org/Apps/DFeet) is an explorer for a D-Bus bus. It
+connects to the bus, and displays all clients and objects currently available
+on the bus. The objects can be inspected, and their methods called directly. It
+is valuable for verifying that a service is exporting the expected objects to
+the bus, and that the objects’ methods can be called as expected.
+
+### Bustle
+
+[Bustle](https://gitlab.freedesktop.org/bustle/bustle) is a more advanced version of
+[dbus-monitor]( {{< ref "d-bus_services.md#dbus-monitor" >}}) which displays
+D-Bus calls graphically, including timing data. It is intended for profiling
+IPC performance by highlighting D-Bus calls which happen frequently or take a
+long time. It can be used as a general replacement for dbus-monitor, though.
+
+There is a presentation available on
+[profiling D-Bus APIs using Bustle](http://willthompson.co.uk/talks/profiling-and-optimizing-d-bus-apis.pdf).
+
+## External links
+
+- [D-Bus specification](http://dbus.freedesktop.org/doc/dbus-specification.html)
+- [GDBus API documentation](https://developer.gnome.org/gio/stable/gdbus-convenience.html)
+- [Article on versioning D-Bus APIs](http://0pointer.de/blog/projects/versioning-dbus.html)
+- [dbus-monitor](http://dbus.freedesktop.org/doc/dbus-monitor.1.html)
+- [D-Feet](https://wiki.gnome.org/Apps/DFeet)
+- [Bustle](https://gitlab.freedesktop.org/bustle/bustle)
+- [Profiling APIs with Bustle](http://willthompson.co.uk/talks/profiling-and-optimizing-d-bus-apis.pdf)
diff --git a/content/guidelines/gsettings.md b/content/guides/gsettings.md
similarity index 98%
rename from content/guidelines/gsettings.md
rename to content/guides/gsettings.md
index 4ff716d7f..0156d812b 100644
--- a/content/guidelines/gsettings.md
+++ b/content/guides/gsettings.md
@@ -23,7 +23,7 @@ with
 [`g_settings_bind()`](https://developer.gnome.org/gio/stable/GSettings.html#g-settings-bind).
 
 Due to its tight integration with other GLib utilities, it should be
-used in preference to (e.g.) [SQLite]( {{< ref "/guidelines/sqlite.md" >}} ) for
+used in preference to (e.g.) [SQLite]( {{< ref "sqlite.md" >}} ) for
 configuration data (but not for user data or documents, or high volumes
 of data).
 
diff --git a/content/guides/json_parsing.md b/content/guides/json_parsing.md
new file mode 100644
index 000000000..a388049f4
--- /dev/null
+++ b/content/guides/json_parsing.md
@@ -0,0 +1,161 @@
++++
+date = "2015-09-08"
+weight = 100
+
+title = "JSON parsing"
+
+aliases = [
+    "/old-wiki/Guidelines/JSON_parsing"
+]
++++
+
+# JSON parsing
+
+JSON is used for various formats within Apertis, and potentially also for
+various web APIs. It is a well defined format, and several mature libraries
+exist for parsing it. However, the JSON being parsed typically comes from
+untrusted sources (user input or untrusted web APIs), so must be validated
+extremely carefully to prevent exploits.
+
+## Summary
+
+- Use a standard library to parse JSON, such as json-glib.
+  ([Parsing JSON]( {{< ref "json_parsing.md#parsing-json" >}} ))
+- Be careful to pair up JSON reader functions on all code paths.
+  ([Parsing JSON]( {{< ref "json_parsing.md#parsing-json" >}} ))
+- Write a JSON schema for each JSON format in use.
+  ([Schema validation]( {{< ref "json_parsing.md#schema-validation" >}} ))
+- Use Walbottle to validate JSON schemas and documents.
+  ([Schema validation]( {{< ref "json_parsing.md#schema-validation" >}} ))
+- Use Walbottle to generate test vectors for unit testing JSON reader
+  code. ([Unit testing]( {{< ref "json_parsing.md#unit-testing" >}} ))
+
+## Parsing JSON
+
+JSON should be parsed using a standard library, such as
+[json-glib](https://developer.gnome.org/json-glib/stable/). That will take care
+of checking the JSON for well-formedness and safely parsing the values it
+contains. The output from json-glib is a hierarchy of parsed JSON nodes which
+may be values, arrays or objects. The Apertis code must then extract the data
+it requires from this hierarchy. This navigation of the hierarchy is still
+security critical, as the parsed JSON document may not conform to the expected
+format (the *schema* for that document). See
+[Schema validation]( {{< ref "json_parsing.md#schema-validation" >}} ) for more
+information on this.
+
+When using json-glib, the
+[`JsonReader`](https://developer.gnome.org/json-glib/stable/JsonReader.html)
+object is typically used to navigate a parsed JSON document and extract the
+required data. A common pitfall is to not pair calls to
+[`json_reader_read_member()`](https://developer.gnome.org/json-glib/stable/JsonReader.html#json-reader-read-member)
+and
+[`json_reader_end_member()`](https://developer.gnome.org/json-glib/stable/JsonReader.html#json-reader-end-member).
+
+For example:
+
+    gint
+    read_some_member (JsonReader *reader)
+    {
+      gint retval;
+
+      /* This code is incorrect. */
+      if (!json_reader_read_member (reader, "member-name"))
+        {
+          return -1;
+        }
+
+      retval = json_reader_read_int (reader);
+      json_reader_end_member (reader);
+
+      return retval;
+    }
+
+This code is incorrect because `json_reader_end_member()` is not called on the
+code path where the `member-name` member doesn’t exist. That leaves the
+`JsonReader` in an error state, and any remaining read operations will silently
+fail.
+
+Instead, the following should be done:
+
+    gint
+    read_some_member (JsonReader *reader)
+    {
+      gint retval = -1;
+
+      if (json_reader_read_member (reader, "member-name"))
+        {
+          retval = json_reader_read_int (reader);
+        }
+
+      json_reader_end_member (reader);
+
+      return retval;
+    }
+
+The same is true of other APIs, such as
+[`json_reader_read_element()`](https://developer.gnome.org/json-glib/stable/JsonReader.html#json-reader-read-element).
+Read the API documentation for json-glib functions carefully to check whether
+the function will put the `JsonReader` into an error state on failure and, if
+so, how to get it out of that error state.
+
+## Schema validation
+
+Ideally, all JSON formats will have an accompanying [JSON
+schema](http://json-schema.org/) which describes the expected structure of the
+JSON files. A JSON schema is analogous to an XML schema for XML documents. If a
+schema exists for a JSON document which is stored in git (such as a UI
+definition), that document can be validated at compile time, which can help
+catch problems without the need for runtime testing.
+
+One tool for this is [Walbottle](https://github.com/pwithnall/walbottle), which
+allows validation of JSON documents against schemas. Given a schema called
+`schema.json` and two JSON documents called `example1.json` and
+`example2.json`, the following `Makefile.am` snippets will validate them at
+compile time:
+
+    json_schema_files = schema.json
+    json_files = example1.json example2.json
+
+    check-local: check-json-schemas check-json
+
+    check-json-schemas: $(json_schema_files)
+        json-schema-validate --ignore-errors $^
+    check-json: $(json_schema_files) $(json_files)
+        json-validate --ignore-errors $(addprefix --schema=,$(json_schema_files)) $(json_files)
+
+    .PHONY: check-json-schemas check-json
+
+## Unit testing
+
+Due to the susceptibility of JSON handling code to break on invalid input (as
+it assumes the input follows the correct schema, which it may not, as it’s
+untrusted), it is important to unit test such code. See the [Unit testing
+guidelines]( {{< ref "/guidelines/unit_testing.md" >}} ) for suggestions on
+writing code for testing. The ideal is for the JSON parsing code to be
+separated from whatever code calls it, so that it can be linked into unit tests
+by itself, and passed JSON snippets to check what it retrieves from them.
+
+Thinking of JSON snippets which thoroughly test parsing and validation code is
+hard, and is impossible to do without also using code coverage metrics (see the
+[Tooling guidelines]( {{< ref "/guidelines/tooling.md#code-coverage" >}} )).
+However, given a JSON schema for the document, it is possible to automatically
+and exhaustively generate [unit test
+vectors](http://en.wikipedia.org/wiki/Test_vector) which can be easily copied
+into the unit tests to give good coverage.
+
+This can be done using Walbottle:
+
+    json-schema-generate --valid-only schema.json
+    json-schema-generate --invalid-only schema.json
+
+That command will generate sets of valid and invalid test vectors, each of
+which is a JSON instance which may or may not conform to the given schema.
+
+## External links
+
+  - [JSON website](http://www.json.org/)
+  - [JSON Schema website](http://json-schema.org/)
+  - [json-glib website](https://wiki.gnome.org/Projects/JsonGlib)
+  - [json-glib
+    documentation](https://developer.gnome.org/json-glib/stable/)
+  - [Walbottle website](http://people.collabora.com/~pwith/walbottle/)
diff --git a/content/guidelines/sqlite.md b/content/guides/sqlite.md
similarity index 86%
rename from content/guidelines/sqlite.md
rename to content/guides/sqlite.md
index f70f1ca9b..7ce68496b 100644
--- a/content/guidelines/sqlite.md
+++ b/content/guides/sqlite.md
@@ -16,19 +16,19 @@ throughput databases. It is used for storing some user data in Apertis.
 
 ## Summary
 
-  - Use SQLite for appropriate use cases: not configuration data (use
-    [GSettings]( {{< ref "/guidelines/gsettings.md" >}} )). ([When to use
-    SQLite](#when-to-use-sqlite))
-  - Consider your vacuuming policy before committing to using SQLite.
-    ([When to use SQLite](#when-to-use-sqlite))
-  - Avoid SQL injection vulnerabilities by using prepared statements.
-    ([SQL injection](#sql-injection))
+- Use SQLite for appropriate use cases: not configuration data (use
+  [GSettings]( {{< ref "gsettings.md" >}} )). ([When to use
+  SQLite]( {{< ref "gsettings.md#when-to-use-sqlite" >}} ))
+- Consider your vacuuming policy before committing to using SQLite.
+  ([When to use SQLite]( {{< ref "gsettings.md#when-to-use-sqlite" >}}))
+- Avoid SQL injection vulnerabilities by using prepared statements.
+  ([SQL injection]( {{< ref "gsettings.md#sql-injection" >}} ))
 
 ## When to use SQLite
 
 Even though it is lightweight for a database, SQLite is a fairly
 heavyweight solution to some problems. It should *not* be used for
-configuration data: [GSettings]( {{< ref "/guidelines/gsettings.md" >}} ) should
+configuration data: [GSettings]( {{< ref "gsettings.md" >}} ) should
 be used for that. Similarly, it is not suitable for more fully featured
 database systems which require support for concurrent access or advanced
 SQL support. It fills the middle space, and is best suited to situations
diff --git a/content/guidelines/xml_parsing.md b/content/guides/xml_parsing.md
similarity index 81%
rename from content/guidelines/xml_parsing.md
rename to content/guides/xml_parsing.md
index ffc2d0b19..621168800 100644
--- a/content/guidelines/xml_parsing.md
+++ b/content/guides/xml_parsing.md
@@ -12,22 +12,22 @@ aliases = [
 # XML parsing
 
 XML is used for a few formats within Apertis, although not as many as
-[JSON]( {{< ref "/guidelines/json_parsing.md" >}} ). It is more commonly used
+[JSON]( {{< ref "json_parsing.md" >}} ). It is more commonly used
 internally by various GLib systems and tools, such as
-[GSettings]( {{< ref "/guidelines/gsettings.md" >}} ) and
-[D-Bus]( {{< ref "/guidelines/d-bus_services.md" >}} ). In situations where it
+[GSettings]( {{< ref "gsettings.md" >}} ) and
+[D-Bus]( {{< ref "d-bus_services.md" >}} ). In situations where it
 is parsed by Apertis code, the XML being parsed typically comes from
 untrusted sources (untrusted web APIs or user input), so must be
 validated extremely carefully to prevent exploits.
 
 ## Summary
 
-  - Use a standard library to parse XML, such as libxml2. ([Parsing
-    XML](#parsing-xml))
-  - Write an XML schema for each XML format in use. ([Schema
-    validation](#schema-validation))
-  - Use xmllint to validate XML documents. ([Schema
-    validation](#schema-validation))
+- Use a standard library to parse XML, such as libxml2. ([Parsing
+  XML]( {{< ref "xml_parsing.md#parsing-xml" >}} ))
+- Write an XML schema for each XML format in use. ([Schema
+  validation]( {{< ref "xml_parsing.md#schema-validation" >}} ))
+- Use xmllint to validate XML documents. ([Schema
+  validation]( {{< ref "xml_parsing.md#schema-validation" >}} ))
 
 ## Parsing XML
 
@@ -71,7 +71,7 @@ following `Makefile.am` snippet will validate them at compile time:
     .PHONY: check-xml
 
 Various existing autotools macros for systems which use XML, such as
-[GSettings]( {{< ref "/guidelines/gsettings.md" >}} ), already automatically
+[GSettings]( {{< ref "gsettings.md" >}} ), already automatically
 validate the relevant XML files.
 
 ## External links
diff --git a/content/release/15.09/releasenotes.md b/content/release/15.09/releasenotes.md
index 7189ba52c..c1e0b1f15 100644
--- a/content/release/15.09/releasenotes.md
+++ b/content/release/15.09/releasenotes.md
@@ -215,7 +215,7 @@ of actuators (for example, seat adjustment) in a safe manner.
 
 Improvements have been made to the core of
 [Walbottle](https://github.com/pwithnall/walbottle), a unit test
-generator for [JSON data formats]( {{< ref "/guidelines/json_parsing.md" >}} ),
+generator for [JSON data formats]( {{< ref "json_parsing.md" >}} ),
 to allow it to be used more for testing Apertis SDK libraries. Walbottle
 has been integrated with libthornbury, a UI utility library. Further
 improvements will be made to it after the 15.09 release, and it will be
-- 
GitLab