# How this documentation is generated

Every page on this site is a Markdown file in git, and every one of them was
written by a person. This page describes the pipeline we propose building next:
one that watches releases in the repositories that have public documentation,
works out what customers can observe, drafts the update, and opens a pull request
here for a human to approve.

{% callout type="warning" title="This is a design, not a description" %}
The pipeline does not exist yet. Nothing below has run. The worked example is
written in the present tense because that is the clearest way to describe a
mechanism, not because it is reporting something that happened — see
[Why this site exists](why-this-site-exists.md) for what is actually built.
{% /callout %}

## The release we will follow

`id-verification-service` cuts a release. Its notes cover eleven changes. Three
of them matter for this story:

| Change in the release | Customer-visible? |
|---|---|
| New optional `livenessCheck` field on the workflow steps endpoint | **Yes** |
| Document recognition upgraded to a newer vendor SDK | Yes — but the vendor must not be named |
| `WorkflowRepo` split into three classes | **No** |

The pipeline's job is to document the first two, name nobody in the second, and
stay silent about the third.

## Step by step

{% step n=1 title="A release goes out" %}
The trigger is a release, not a merge. By the time a team cuts one they have
already decided the work ships, and several teams here already mark which of
their releases are external — so the signal exists before the pipeline does.

A GitHub Action in the service repository fires on release and collects the
release notes, the diff since the previous release, and the two files below.
{% /step %}

{% step n=2 title="The repository says how its own domain is documented" %}
Each repository with public documentation carries a file describing its own
conventions: which pages in the docs site correspond to it, the vocabulary it
uses, and what may never be exposed.

```yaml
# .continuous-docs.yml — id-verification-service
owns:
  - knowledge-base/idv/**
  - api-reference/workflow-api.md
never_expose:
  - the identity of document, biometric and eID vendors
  - internal queue names and service topology
prefer:
  "vendor SDK upgrade": "expanded document recognition coverage"
```

Putting this beside the code matters. A central policy is one that nobody
outside the docs team ever reads, and the people who know that a vendor name is
commercially sensitive are the people working in that repository.

{% callout type="important" title="Every repository draws the line somewhere else" %}
This is not a hypothetical need. `id-verification-service` already generates two
OpenAPI specs from the same annotated source — one internal, one external — and
the vendors behind its document and biometric checks appear 59 times in the
internal spec and never in the external one. That rule already exists in code.
The pipeline's job is to inherit it, not to invent a new one.
{% /callout %}
{% /step %}

{% step n=3 title="The OpenAPI spec is regenerated in the same release" %}
The API reference is downstream of the service's source: controllers and DTOs
are annotated in place, and those annotations generate the spec that renders the
reference.

Regenerating it as part of the release means the machine-readable surface never
lags the release that changed it. CI already enforces the other half of this —
a pull request whose committed spec no longer matches what the code produces
fails the build.

```diff
 "paths": {
   "/v1/workflows/{id}/steps": {
     "post": {
       "requestBody": { "schema": { "properties": {
         "type":          { "type": "string", "enum": ["document", "selfie", "aml"] },
+        "livenessCheck": { "type": "boolean", "default": false,
+                           "description": "Require an active liveness check on the selfie step." },
```

One property added, nothing removed or renamed: an additive, non-breaking
change.
{% /step %}

{% step n=4 title="Customer impact is extracted, and an agent drafts the change" %}
The release notes are the input, because they are already written for an
audience rather than for a commit log. An agent reads them together with the
diff and the repository's conventions file, and returns a structured verdict
before it writes any prose:

```json
{
  "customerVisible": true,
  "changes": [
    "New optional request field `livenessCheck` on workflow steps",
    "Document recognition coverage expanded (vendor SDK upgrade)"
  ],
  "ignored": [
    "WorkflowRepo split into three classes — no behavioural change, no public surface"
  ],
  "pages": ["knowledge-base/idv/session-management-and-configuration.md"],
  "confidence": 0.86
}
```

{% callout type="tip" title="What it ignored is part of the output" %}
The `ignored` list appears on the pull request. A reviewer can see that the
refactor was considered and correctly dropped. A filter that only reports what it
found cannot be trusted; a correct silence is what proves it is working.
{% /callout %}

The disclosure rules are applied **before** the prose is written, not scrubbed
out afterwards:

{% callout type="generated" title="Generated: changelog entry" %}
**ID Verification**

- Workflow selfie steps can now require an **active liveness check**. Set
  `livenessCheck: true` when creating a step.
- **Expanded document recognition coverage** for identity documents across
  additional countries and formats.
{% /callout %}

The second bullet is the test. The release upgraded a named vendor SDK; the
entry says what the customer gains and names nobody.
{% /step %}

{% step n=5 title="A pull request is opened here, not there" %}
The change lands in the documentation repository rather than in the service, so
the reviewer reads prose rather than a diff of somebody else's implementation.

{% callout type="generated" title="Generated: proposed edit" %}
```diff
 ## Selfie step

 The selfie step captures a live photo and compares it against the document
 portrait. It runs after the document step by default.
+
+### Requiring an active liveness check
+
+Set `livenessCheck: true` on the step to require the user to complete an
+active liveness challenge before the selfie is accepted. This raises assurance
+against presentation attacks at the cost of a slightly longer session. It is
+off by default.
```
{% /callout %}

The pull request body is generated too, and written for the reviewer rather than
the customer — what was detected, what was ignored, which pages changed, and how
confident the filter was about each.
{% /step %}

{% step n=6 title="The branch builds a preview" %}
The rendered page is read before anyone outside sees it.

This is the smallest gap in the whole design: the site build already runs on
every push, it is simply not wired to pull requests yet.
{% /step %}

{% step n=7 title="Merge, and it is live" %}
A GitHub Action builds the site and publishes it. The page is live within about
a minute.

**This step already works.** It is how the page you are reading reached you.
{% /step %}

## The release that produces nothing

The week before, the same repository cut a release containing only the
`WorkflowRepo` refactor and some dependency bumps. The pipeline ran and produced:

```json
{
  "customerVisible": false,
  "changes": [],
  "ignored": ["WorkflowRepo split into three classes", "dependency bumps"],
  "pages": [],
  "confidence": 0.97
}
```

No pull request. No notification. That silence is the feature: a pipeline that
raises something on every release gets muted inside a month, and muted pipelines
do not come back.

{% callout type="human" title="Where review actually matters" %}
A confidently worded wrong sentence on a public page is worse than a stale one,
and some of these pages are effectively contractual for regulated customers.
Nothing here is merged without a named reviewer, and the pipeline opens a pull
request — it never publishes.
{% /callout %}

## What would carry over from a page like this

Pages drafted this way would record where they came from — the repository, the
release, and the commit — so a reader or an auditor can always trace a sentence
back to the change that caused it.
