From 26a4ecbe9d7d2cf5c9d86077ad96bc70dfe42ee9 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 19:52:02 +0000
Subject: [PATCH 01/11] docs: restore getting-started guidance for stable
LibreSign
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
versioned/base/user_manual/start.rst | 39 ++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 versioned/base/user_manual/start.rst
diff --git a/versioned/base/user_manual/start.rst b/versioned/base/user_manual/start.rst
new file mode 100644
index 00000000..40f58281
--- /dev/null
+++ b/versioned/base/user_manual/start.rst
@@ -0,0 +1,39 @@
+Getting started
+===============
+
+Choose the path that matches your role. An administrator must install and
+configure LibreSign before users can request signatures.
+
+I want to request signatures
+----------------------------
+
+#. Sign in to the Nextcloud instance where LibreSign is enabled.
+#. Open **LibreSign** and find **Request Signatures** or the request action
+ in the **Files** screen.
+#. Select a PDF using **Upload**, **Choose from Files**, or **Upload from URL**
+ when those options are available to your account.
+#. Follow :ref:`add_signature` to add recipients and send the request.
+
+If the request controls are missing, ask your administrator whether your
+account is permitted to create requests.
+
+I received a signing invitation
+-------------------------------
+
+#. Open the invitation link from the requester and check the document and
+ requested identity details before proceeding.
+#. Follow the on-screen signing steps. Depending on the configured signing
+ method, LibreSign may ask you to define a signature, provide a password,
+ upload a certificate, or complete identity verification.
+#. Review the confirmation before submitting. See :ref:`sign_invitation`.
+
+External email signers can use the invitation workflow without a Nextcloud
+account when that identification method is enabled by the administrator.
+Do not forward a personal invitation link to another person.
+
+I want to verify a signed document
+----------------------------------
+
+Use :ref:`validate_document` to check a signed PDF or a document UUID. The
+validation result must be reviewed; an image of a handwritten signature is not
+by itself evidence of a valid digital signature.
From 99c6ab010efc8861d98b5ff4641c9b6fb71e7d0e Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 19:52:30 +0000
Subject: [PATCH 02/11] docs: restore stable user signing, validation, and help
guides
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
versioned/base/user_manual/faq.rst | 39 ++++++++++
versioned/base/user_manual/functionality.rst | 77 ++++++++++++++++++++
versioned/base/user_manual/index.rst | 32 +++++---
versioned/base/user_manual/support.rst | 19 +++++
4 files changed, 158 insertions(+), 9 deletions(-)
create mode 100644 versioned/base/user_manual/faq.rst
create mode 100644 versioned/base/user_manual/functionality.rst
create mode 100644 versioned/base/user_manual/support.rst
diff --git a/versioned/base/user_manual/faq.rst b/versioned/base/user_manual/faq.rst
new file mode 100644
index 00000000..07803c4f
--- /dev/null
+++ b/versioned/base/user_manual/faq.rst
@@ -0,0 +1,39 @@
+Frequently asked questions
+==========================
+
+Do I need a Nextcloud account to sign?
+------------------------------------
+
+Not always. A requester can invite an external email signer without creating
+an account when the administrator enables that identification method. Creating
+signature requests from the Nextcloud interface does require appropriate
+permissions. See :doc:`start`.
+
+Must I upload my own digital certificate?
+-----------------------------------------
+
+That depends on the signing method required for the request and the server's
+certificate configuration. If a personal certificate is required, LibreSign
+will prompt for it. A drawn or typed appearance is not the same thing as the
+cryptographic signature embedded in a signed PDF.
+
+How do I know whether everyone has signed?
+-----------------------------------------
+
+Check the request details and each signer's progress in :ref:`see_signed_file`.
+One completed signer does not prove a multi-signer document is finished.
+
+Does validation prove a signature is legally valid everywhere?
+-------------------------------------------------------------
+
+No. :ref:`validate_document` checks technical evidence. Applicable laws,
+identity-assurance requirements, retention duties, and acceptance by a
+recipient depend on the context and jurisdiction. LibreSign is not a blanket
+GDPR/LGPD or legal-compliance certification.
+
+What if my invitation does not work?
+-----------------------------------
+
+Check that you opened the intended invitation, then ask the requester to
+verify its status, recipient, and configured identification method. Do not
+send your password or signing credential to support staff. See :doc:`support`.
diff --git a/versioned/base/user_manual/functionality.rst b/versioned/base/user_manual/functionality.rst
new file mode 100644
index 00000000..daa819b0
--- /dev/null
+++ b/versioned/base/user_manual/functionality.rst
@@ -0,0 +1,77 @@
+Documents, signatures, and validation
+=====================================
+
+.. _main_screen:
+
+Find your documents
+-------------------
+
+Open **LibreSign** in Nextcloud and choose **Files** to see documents and
+signature requests available to you. Select a file to inspect its details
+and signers. An individual signer can be **pending** or **signed**; do not
+assume the entire request is complete merely because one person has signed.
+
+.. _add_signature:
+
+Request signatures
+------------------
+
+#. Choose **Request Signatures**. Use **Upload** for a PDF on your device,
+ **Choose from Files** for an existing Nextcloud file, or **Upload from
+ URL** if your administrator allows it.
+#. Review the selected file before asking another person to sign.
+#. Use **Search signer** to select a recipient or an allowed identification
+ method, including an external email recipient where enabled.
+#. Check the signer's name and identification details and select **Save**.
+ Repeat for every required signer.
+#. Configure the remaining signing steps shown by LibreSign and submit the
+ request. Do not consider a draft a delivered invitation.
+#. Open the request details in **Files** to see who is still pending.
+
+Available signer identification methods, permissions, delivery channels, and
+signing order depend on the administrator's configuration. Use the options
+shown for your request rather than assuming every channel is enabled.
+
+.. _sign_invitation:
+
+Sign an invitation
+------------------
+
+#. Open the link supplied to you for the signing request; verify its sender
+ before entering any personal information.
+#. Read the PDF and check that you are the intended signer.
+#. Complete any requested identification step. If LibreSign asks for a
+ certificate or signature password, follow the instructions for your
+ configured signing method.
+#. Choose **Sign** or **Sign document** and confirm the operation.
+#. Check for the completion message. If other signers remain, the request
+ may still be in progress.
+
+If the link is expired, rejected, or requires a method you cannot use,
+contact the requester. Do not reuse someone else's invitation.
+
+.. _see_signed_file:
+
+Follow signing progress
+-----------------------
+
+Open the document details in **Files** and check the signer list. A signer
+marked **pending** has not completed their part; **signed** records a completed
+part. The document's overall completion depends on all required signatures
+and the configured workflow. Download the final PDF when it becomes available.
+
+.. _validate_document:
+
+Validate a signature
+--------------------
+
+#. Open LibreSign's **Validate signature** page.
+#. Choose **Upload** to select a PDF, drag and drop a PDF onto the page, or
+ choose **From UUID** if you have the document identifier.
+#. Run **Validation** and review the results, including certificate and
+ signing information shown by the application.
+#. Investigate any reported error instead of treating a visual stamp or QR
+ code as conclusive proof of validity.
+
+Validation evaluates the available cryptographic and certificate evidence.
+It does not, by itself, determine every legal requirement in your jurisdiction.
diff --git a/versioned/base/user_manual/index.rst b/versioned/base/user_manual/index.rst
index 3f95ab2d..832c5bae 100644
--- a/versioned/base/user_manual/index.rst
+++ b/versioned/base/user_manual/index.rst
@@ -1,14 +1,28 @@
User manual — LibreSign |LibreSignRelease|
==========================================
-This manual is for LibreSign |LibreSignRelease| running with
-Nextcloud |NextcloudRelease|.
+Use this manual for LibreSign |LibreSignRelease| on Nextcloud
+|NextcloudRelease|. It covers the signing and validation workflows available
+in this release, rather than features under development in ``main``.
-The version-specific manual is being expanded. It deliberately does not
-inherit development screenshots or workflows from ``main`` until they have
-been checked against this release line. For interface behavior, check the
-LibreSign application installed on your Nextcloud instance.
+Choose a task
+-------------
-You can switch versions using the documentation version selector. The
-`release lifecycle guide <../lifecycle.html>`_ explains the meaning of
-current, earlier and end-of-support versions.
+- :doc:`start` — find the correct entry point for requesting or signing.
+- :doc:`functionality` — prepare a document, invite signers, follow progress,
+ sign a request, or validate a PDF.
+- :doc:`faq` — understand account, certificate, and legal considerations.
+- :doc:`support` — troubleshoot a problem and find support channels.
+
+For installation and server configuration, use the
+`administrator manual <../admin_manual/index.html>`_. Integrations belong in
+the `developer manual <../developer_manual/index.html>`_.
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Tasks
+
+ start
+ functionality
+ faq
+ support
diff --git a/versioned/base/user_manual/support.rst b/versioned/base/user_manual/support.rst
new file mode 100644
index 00000000..e7171667
--- /dev/null
+++ b/versioned/base/user_manual/support.rst
@@ -0,0 +1,19 @@
+Help and support
+================
+
+If a signing request or validation fails, first note the action you were
+trying to perform and the exact error message, without copying private
+identification data or document contents into a public report.
+
+- For an invitation, an expired request, or a wrong recipient, contact the
+ person who requested the signature.
+- For missing permissions, signing methods, or server configuration, contact
+ your Nextcloud administrator.
+- For a reproducible LibreSign defect, consult the
+ `LibreSign issue tracker `_.
+- For project information and professional support options, see
+ `libresign.coop `_.
+
+Include your LibreSign and Nextcloud version numbers in technical reports.
+Never publish signature passwords, private certificates, invitation links,
+or documents containing personal data.
From e75de68aa661982325a023f7bd29b9c6b3fb919f Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 19:52:55 +0000
Subject: [PATCH 03/11] docs: restore stable administrator setup and operations
guides
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
versioned/base/admin_manual/configuration.rst | 36 ++++++++++++++++
versioned/base/admin_manual/index.rst | 33 ++++++++++-----
versioned/base/admin_manual/installation.rst | 41 +++++++++++++++++++
versioned/base/admin_manual/maintenance.rst | 37 +++++++++++++++++
versioned/base/admin_manual/security.rst | 38 +++++++++++++++++
5 files changed, 174 insertions(+), 11 deletions(-)
create mode 100644 versioned/base/admin_manual/configuration.rst
create mode 100644 versioned/base/admin_manual/installation.rst
create mode 100644 versioned/base/admin_manual/maintenance.rst
create mode 100644 versioned/base/admin_manual/security.rst
diff --git a/versioned/base/admin_manual/configuration.rst b/versioned/base/admin_manual/configuration.rst
new file mode 100644
index 00000000..8efd4376
--- /dev/null
+++ b/versioned/base/admin_manual/configuration.rst
@@ -0,0 +1,36 @@
+Configure signing
+=================
+
+Open **Administration settings** in Nextcloud and find LibreSign. Configuration
+is server-owned: users should not be asked to change a system-wide signing
+policy to complete a single request.
+
+Signing and identity
+--------------------
+
+Review the available signature engine and signing methods before enabling
+external signers. The user's available choices can depend on permissions,
+identity methods, and policy settings. Test the configured invitation method
+with a non-production request before relying on it.
+
+The administrative layout changes across supported releases. In LibreSign 13
+and 14, several settings appear as individual controls; LibreSign 15 includes
+the Policy Workbench for applicable configuration. Consult the visible
+controls in your installed version rather than looking for an identically
+named control in every release.
+
+Certificates and dependencies
+-----------------------------
+
+- Review **Certificate engine** and **Root certificate data** and the chosen
+ trust model before issuing signatures.
+- Use **Configuration check** and the **Dependencies** section to diagnose
+ an incomplete installation.
+- Record the selected certificate policy and secure storage location as part
+ of your deployment's operational documentation.
+
+Changing a trust anchor or regenerating a root certificate is not routine
+configuration. See :doc:`security` and :doc:`maintenance` first.
+
+For integration and version-pinned API payloads, use the
+`developer API reference <../developer_manual/api/index.html>`_.
diff --git a/versioned/base/admin_manual/index.rst b/versioned/base/admin_manual/index.rst
index d30169de..fbaa7911 100644
--- a/versioned/base/admin_manual/index.rst
+++ b/versioned/base/admin_manual/index.rst
@@ -1,17 +1,28 @@
Administrator manual — LibreSign |LibreSignRelease|
===================================================
-The LibreSign |LibreSignRelease| line requires a compatible Nextcloud
-|NextcloudRelease| instance, as declared by its application manifest.
+This manual covers LibreSign |LibreSignRelease| for Nextcloud
+|NextcloudRelease|. Check the matching app release before changing server
+settings or restoring data. Procedures are limited to the stable versions
+listed in the documentation version selector.
-Install or upgrade the application version compatible with your Nextcloud
-release, and inspect the application configuration in the Nextcloud
-administration interface. Before upgrading, consult the release notes in
-`LibreSign/libresign `_.
+Choose an operation
+-------------------
-This manual intentionally omits unverified configuration steps from
-the development branch. Version-specific operational guides can be
-added here without changing other published release lines.
+- :doc:`installation` — install LibreSign and complete initial setup.
+- :doc:`configuration` — find the signing and certificate configuration.
+- :doc:`maintenance` — back up, upgrade, and troubleshoot an installation.
+- :doc:`security` — protect signing credentials and review security choices.
-For support-lifecycle information see the
-`release lifecycle guide <../lifecycle.html>`_.
+For the signing experience, see the `user manual
+<../user_manual/index.html>`_; for API authentication and integration,
+consult the `developer manual <../developer_manual/index.html>`_.
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Operations
+
+ installation
+ configuration
+ maintenance
+ security
diff --git a/versioned/base/admin_manual/installation.rst b/versioned/base/admin_manual/installation.rst
new file mode 100644
index 00000000..a37932d2
--- /dev/null
+++ b/versioned/base/admin_manual/installation.rst
@@ -0,0 +1,41 @@
+Install and initialize LibreSign
+================================
+
+Prerequisites
+-------------
+
+Use a supported Nextcloud instance and the matching LibreSign release. The
+application declares compatibility in its ``appinfo/info.xml``; this site's
+release selector distinguishes LibreSign versions from Nextcloud versions.
+Use an administrator account and plan for adequate disk space and network
+access if the application must download signing dependencies.
+
+Install the app
+---------------
+
+#. Open Nextcloud's **Apps** administration page.
+#. Search for **LibreSign** and install or enable the release offered for
+ your compatible Nextcloud version.
+#. Open the LibreSign administration settings and inspect **Configuration
+ check** for resources requiring attention.
+#. In **Dependencies**, use **Download binaries** if prompted, then
+ **Validate setup** to check the installation. The operation can take time
+ and requires server resources.
+#. Configure the certificate engine and the **Root certificate data**
+ appropriate to your organization. For the OpenSSL engine, the root
+ certificate form asks for a **Common Name (CN)** and allows generating a
+ root certificate when the installation requires it.
+#. Resolve remaining configuration errors before sending real invitations.
+
+The location and presentation of some settings differ between LibreSign
+releases; see :doc:`configuration`. Do not regenerate an existing production
+root certificate merely to repeat initial setup.
+
+Check the installation
+----------------------
+
+Open LibreSign with a permitted user account. In a test environment, create
+a request, complete its supported signing method, and open **Validate
+signature** on the result. A successful installation check is not equivalent
+to verifying mail delivery, external identity providers, or production
+certificate policy; exercise those separately when enabled.
diff --git a/versioned/base/admin_manual/maintenance.rst b/versioned/base/admin_manual/maintenance.rst
new file mode 100644
index 00000000..ca2b3e9d
--- /dev/null
+++ b/versioned/base/admin_manual/maintenance.rst
@@ -0,0 +1,37 @@
+Maintain an installation
+========================
+
+Before upgrading
+----------------
+
+#. Confirm the target LibreSign release is compatible with the installed
+ Nextcloud version; do not assume matching numbers refer to the same product.
+#. Record the current application and Nextcloud versions, configuration,
+ certificate engine, and enabled signing or identification methods.
+#. Back up the Nextcloud database, configuration, related files, and the
+ certificate material and signing keys required by your deployment.
+ Protect these backups according to their sensitivity.
+#. Follow Nextcloud's supported application upgrade procedure and consult
+ the `LibreSign releases `_
+ for changes relevant to your target version.
+#. Check **Configuration check** after the upgrade; perform a test signing
+ and validate its resulting PDF before resuming production activity.
+
+Backups must be recoverable: verify recovery on an isolated system, including
+access to the certificate material necessary for previously signed documents.
+Do not expose private keys in tickets, logs, or example configurations.
+
+Troubleshooting
+---------------
+
+- **Cannot request a signature:** check the user's permissions and the
+ allowed identification methods in :doc:`configuration`.
+- **Setup is incomplete:** inspect **Configuration check** and
+ **Dependencies**, and check Nextcloud's application logs.
+- **An invitation was not received:** verify the request status and the
+ configured delivery channel; inspect the mail system only if email delivery
+ is configured. Avoid resending invitations blindly.
+- **Validation fails:** inspect the reported certificate or PDF error, and
+ confirm that the signing environment's trust material is still available.
+
+Do not regenerate the root certificate as a generic troubleshooting step.
diff --git a/versioned/base/admin_manual/security.rst b/versioned/base/admin_manual/security.rst
new file mode 100644
index 00000000..c52e6fba
--- /dev/null
+++ b/versioned/base/admin_manual/security.rst
@@ -0,0 +1,38 @@
+Security and trust
+==================
+
+Protect signing credentials
+---------------------------
+
+Restrict administrator access to certificate configuration and any signing
+keys. Protect backups and limit access to credentials; do not copy private
+keys into public reports or screenshots. Keep Nextcloud, LibreSign, and the
+underlying TLS configuration maintained.
+
+Certificate lifecycle
+---------------------
+
+LibreSign's **Root certificate data** interface provides a root certificate
+configuration. The OpenSSL engine explicitly warns that **Regenerate root
+certificate** invalidates existing signing keys. Treat regeneration as a
+planned key lifecycle or recovery operation, not as ordinary maintenance.
+Prepare and test a recovery and validation plan before changing a trust
+anchor used by existing documents.
+
+Signers and access
+------------------
+
+Review which accounts may create requests and which identification methods
+are available to external signers. A signing invitation is sensitive: avoid
+publishing the link or including it in a public issue. Test the separation
+between request owner, intended signer, and unrelated users when configuring
+external access.
+
+Validation and compliance
+-------------------------
+
+Provide recipients with a way to validate signed PDFs. Technical signature
+validation and certificate status do not by themselves prove legal compliance
+in every jurisdiction or that a signer's identity was established to a
+particular assurance level. Document applicable organizational rules
+separately from the application's cryptographic capabilities.
From d4b14444f366eb4c8e70797d4edc17f203e68854 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 19:53:43 +0000
Subject: [PATCH 04/11] test(docs): protect stable manuals and point indexed
links to stable topics
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
tests/test_seo.py | 4 +--
tests/test_stable_manuals.py | 58 ++++++++++++++++++++++++++++++
versioned/base/user_manual/faq.rst | 8 ++---
versioned/legacy-routes.json | 16 ++++-----
4 files changed, 72 insertions(+), 14 deletions(-)
create mode 100644 tests/test_stable_manuals.py
diff --git a/tests/test_seo.py b/tests/test_seo.py
index 47975801..24cdba3c 100644
--- a/tests/test_seo.py
+++ b/tests/test_seo.py
@@ -41,9 +41,9 @@ def test_historic_routes_cover_all_existing_manual_pages(self):
self.assertEqual(set(routes), source)
self.assertEqual(len(routes), 46)
self.assertEqual(routes["user_manual/functionality.html"],
- "main/user_manual/functionality.html")
+ "15/user_manual/functionality.html")
self.assertEqual(routes["admin_manual/installation.html"],
- "main/admin_manual/installation.html")
+ "15/admin_manual/installation.html")
self.assertEqual(routes["developer_manual/architecture.html"],
"main/developer_manual/architecture.html")
diff --git a/tests/test_stable_manuals.py b/tests/test_stable_manuals.py
new file mode 100644
index 00000000..6fd2b00b
--- /dev/null
+++ b/tests/test_stable_manuals.py
@@ -0,0 +1,58 @@
+"""Protect task-oriented documentation for every published stable release.
+
+SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
+SPDX-License-Identifier: CC-BY-3.0
+"""
+
+import json
+import unittest
+from pathlib import Path
+
+ROOT = Path(__file__).resolve().parent.parent
+REQUIRED_PAGES = {
+ "user_manual": ("start", "functionality", "faq", "support"),
+ "admin_manual": ("installation", "configuration", "maintenance", "security"),
+}
+
+
+class StableManualCoverageTests(unittest.TestCase):
+ def test_stable_manuals_have_real_tasks_in_toctree(self):
+ for manual, pages in REQUIRED_PAGES.items():
+ with self.subTest(manual=manual):
+ source = ROOT / "versioned/base" / manual
+ index = (source / "index.rst").read_text(encoding="utf-8")
+ self.assertIn(".. toctree::", index)
+ self.assertNotIn("being expanded", index)
+ self.assertNotIn("intentionally omits unverified", index)
+ for name in pages:
+ with self.subTest(manual=manual, page=name):
+ self.assertIn(f" {name}\n", index)
+ content = (source / f"{name}.rst").read_text(encoding="utf-8")
+ self.assertGreater(len(content), 350)
+ self.assertIn("\n", content)
+
+ def test_old_user_and_admin_articles_land_on_stable_topics(self):
+ routes = json.loads((ROOT / "versioned/legacy-routes.json").read_text())
+ for manual, pages in REQUIRED_PAGES.items():
+ for page in pages:
+ previous = "suport" if page == "support" else page
+ old = f"{manual}/{previous}.html"
+ with self.subTest(route=old):
+ self.assertEqual(routes[old], f"15/{manual}/{page}.html")
+ self.assertTrue((ROOT / "versioned/base" / manual / f"{page}.rst").is_file())
+
+ def test_legacy_user_anchors_remain_available(self):
+ content = (ROOT / "versioned/base/user_manual/functionality.rst").read_text()
+ for anchor in ("main_screen", "add_signature", "see_signed_file"):
+ with self.subTest(anchor=anchor):
+ self.assertIn(f".. _{anchor}:", content)
+
+ def test_faq_avoids_unqualified_legal_guarantees(self):
+ content = (ROOT / "versioned/base/user_manual/faq.rst").read_text().lower()
+ self.assertNotIn("meets all the requirements", content)
+ self.assertIn("jurisdiction", content)
+ self.assertIn("validation", content)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/versioned/base/user_manual/faq.rst b/versioned/base/user_manual/faq.rst
index 07803c4f..35eb4eab 100644
--- a/versioned/base/user_manual/faq.rst
+++ b/versioned/base/user_manual/faq.rst
@@ -2,7 +2,7 @@ Frequently asked questions
==========================
Do I need a Nextcloud account to sign?
-------------------------------------
+--------------------------------------
Not always. A requester can invite an external email signer without creating
an account when the administrator enables that identification method. Creating
@@ -18,13 +18,13 @@ will prompt for it. A drawn or typed appearance is not the same thing as the
cryptographic signature embedded in a signed PDF.
How do I know whether everyone has signed?
------------------------------------------
+------------------------------------------
Check the request details and each signer's progress in :ref:`see_signed_file`.
One completed signer does not prove a multi-signer document is finished.
Does validation prove a signature is legally valid everywhere?
--------------------------------------------------------------
+--------------------------------------------------------------
No. :ref:`validate_document` checks technical evidence. Applicable laws,
identity-assurance requirements, retention duties, and acceptance by a
@@ -32,7 +32,7 @@ recipient depend on the context and jurisdiction. LibreSign is not a blanket
GDPR/LGPD or legal-compliance certification.
What if my invitation does not work?
------------------------------------
+------------------------------------
Check that you opened the intended invitation, then ask the requester to
verify its status, recipient, and configured identification method. Do not
diff --git a/versioned/legacy-routes.json b/versioned/legacy-routes.json
index 1d8a66ab..5e401d24 100644
--- a/versioned/legacy-routes.json
+++ b/versioned/legacy-routes.json
@@ -1,9 +1,9 @@
{
- "admin_manual/configuration.html": "main/admin_manual/configuration.html",
+ "admin_manual/configuration.html": "15/admin_manual/configuration.html",
"admin_manual/index.html": "15/admin_manual/index.html",
- "admin_manual/installation.html": "main/admin_manual/installation.html",
- "admin_manual/maintenance.html": "main/admin_manual/maintenance.html",
- "admin_manual/security.html": "main/admin_manual/security.html",
+ "admin_manual/installation.html": "15/admin_manual/installation.html",
+ "admin_manual/maintenance.html": "15/admin_manual/maintenance.html",
+ "admin_manual/security.html": "15/admin_manual/security.html",
"developer_manual/api/external-email-signers.html": "15/developer_manual/api/external-email-signers.html",
"developer_manual/api/guide-api.html": "main/developer_manual/api/guide-api.html",
"developer_manual/api/index.html": "15/developer_manual/api/index.html",
@@ -40,9 +40,9 @@
"developer_manual/release-process/versioning.html": "main/developer_manual/release-process/versioning.html",
"developer_manual/requesting-features.html": "main/developer_manual/requesting-features.html",
"developer_manual/translation.html": "main/developer_manual/translation.html",
- "user_manual/faq.html": "main/user_manual/faq.html",
- "user_manual/functionality.html": "main/user_manual/functionality.html",
+ "user_manual/faq.html": "15/user_manual/faq.html",
+ "user_manual/functionality.html": "15/user_manual/functionality.html",
"user_manual/index.html": "15/user_manual/index.html",
- "user_manual/start.html": "main/user_manual/start.html",
- "user_manual/suport.html": "main/user_manual/suport.html"
+ "user_manual/start.html": "15/user_manual/start.html",
+ "user_manual/suport.html": "15/user_manual/support.html"
}
From 69524b50ace54b28182c88167d12120fe942455c Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 19:59:53 +0000
Subject: [PATCH 05/11] docs: restore entry points to stable APIs and
contributor guidance
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
tests/test_stable_manuals.py | 7 ++++++
versioned/base/developer_manual/index.rst | 27 ++++++++++++++++++-----
2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/tests/test_stable_manuals.py b/tests/test_stable_manuals.py
index 6fd2b00b..374ce3fa 100644
--- a/tests/test_stable_manuals.py
+++ b/tests/test_stable_manuals.py
@@ -47,6 +47,13 @@ def test_legacy_user_anchors_remain_available(self):
with self.subTest(anchor=anchor):
self.assertIn(f".. _{anchor}:", content)
+ def test_stable_developer_index_links_current_contributor_docs(self):
+ content = (ROOT / "versioned/base/developer_manual/index.rst").read_text()
+ self.assertIn(" api/index", content)
+ self.assertIn(" integration/index", content)
+ self.assertIn("../../main/developer_manual/index.html", content)
+ self.assertIn("unreleased functionality", content)
+
def test_faq_avoids_unqualified_legal_guarantees(self):
content = (ROOT / "versioned/base/user_manual/faq.rst").read_text().lower()
self.assertNotIn("meets all the requirements", content)
diff --git a/versioned/base/developer_manual/index.rst b/versioned/base/developer_manual/index.rst
index 98576b3e..29cec956 100644
--- a/versioned/base/developer_manual/index.rst
+++ b/versioned/base/developer_manual/index.rst
@@ -2,17 +2,32 @@ Developer manual — LibreSign |LibreSignRelease|
===============================================
This is the **release-specific API contract** for LibreSign
-|LibreSignRelease| and Nextcloud |NextcloudRelease|.
+|LibreSignRelease| and Nextcloud |NextcloudRelease|. The schema is pinned
+to an application commit on the corresponding stable branch. Development-only
+API calls and payloads are not presented as features of this release.
-The schema is pinned to an application commit on the corresponding stable
-branch. API calls and payloads available only in the development branch
-are not presented as features of this release.
+Integrate an external application
+---------------------------------
-For supported integration strategies, see the architecture decision guides;
-for executable API requests, use the release-specific email signer guide.
+- :doc:`integration/index` — choose an integration architecture for an
+ existing application.
+- :doc:`api/external-email-signers` — follow a release-specific API example
+ for inviting an external email signer.
+- :doc:`api/openapi` — inspect the OpenAPI schema pinned to this release.
+
+Contribute or develop LibreSign
+-------------------------------
+
+Source architecture, coding standards, development environment, tests, and
+release engineering follow the project's current development branch. They
+are available in the `development and contributor manual
+<../../main/developer_manual/index.html>`_. That manual may describe
+unreleased functionality. For integrating with LibreSign |LibreSignRelease|,
+continue to use the version-specific reference above.
.. toctree::
:maxdepth: 2
+ :caption: Release-specific integration
api/index
integration/index
From 382a32feb075b1889091cf5c2fcb4336ce7aba1c Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 20:00:43 +0000
Subject: [PATCH 06/11] docs: add task-based navigation to stable documentation
homepage
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
_templates/home.html | 12 ++++++++++++
assets/home.css | 20 ++++++++++++++++++++
tests/test_versioning.py | 18 ++++++++++++++++++
3 files changed, 50 insertions(+)
diff --git a/_templates/home.html b/_templates/home.html
index 4655f44e..afa3fcb4 100644
--- a/_templates/home.html
+++ b/_templates/home.html
@@ -36,6 +36,18 @@ Find documentation for your version of LibreSign.
{% endfor %}
+
+ Find a task
+ Start with the latest stable LibreSign {{ current_stable }} manual, or choose your
+ installed version below.
+
+
Available versions
diff --git a/assets/home.css b/assets/home.css
index 192b7eb1..55a2adec 100644
--- a/assets/home.css
+++ b/assets/home.css
@@ -108,6 +108,26 @@ h1 {
.hero > p:not(.eyebrow) { font-size: 1.04rem; line-height: 1.7; color: var(--muted); }
.hero .latest-reference { margin-top: 22px; font-size: .96rem; color: var(--text); }
.latest-reference a { font-weight: 700; }
+.quick-tasks {
+ margin: 0 0 46px;
+ padding: 24px 28px;
+ border: 1px solid var(--border);
+ border-radius: 7px;
+ background: var(--surface);
+}
+.quick-tasks p {
+ margin: 8px 0 16px;
+ color: var(--muted);
+ line-height: 1.5;
+}
+.quick-tasks ul {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
+ gap: 12px 24px;
+ margin: 0;
+ padding-left: 20px;
+}
+.quick-tasks a { font-weight: 550; }
.section-heading {
display: flex;
flex-wrap: wrap;
diff --git a/tests/test_versioning.py b/tests/test_versioning.py
index 420bbe20..3bb64681 100644
--- a/tests/test_versioning.py
+++ b/tests/test_versioning.py
@@ -171,6 +171,24 @@ def test_homepage_lists_latest_stable_first_and_main_last(self):
self.assertIn('Development (not a stable release)', page)
self.assertNotIn('http-equiv="refresh"', page)
+ def test_homepage_exposes_latest_stable_task_routes(self):
+ catalog = {"current_stable": "15", "versions": [
+ {"slug": "15", "status": "current", "nextcloud_min": 35,
+ "nextcloud_max": 35},
+ {"slug": "main", "status": "development", "nextcloud_min": 36,
+ "nextcloud_max": 36}]}
+ page = version_overview(catalog)
+ for route in (
+ "15/user_manual/start.html",
+ "15/user_manual/functionality.html",
+ "15/admin_manual/installation.html",
+ "15/developer_manual/integration/index.html",
+ ):
+ with self.subTest(route=route):
+ self.assertIn(f'href="{route}"', page)
+ self.assertIn('id="quick-tasks-title"', page)
+ self.assertNotIn('href="main/user_manual/functionality.html"', page)
+
def test_homepage_loads_theme_before_css_and_exposes_accessible_toggle(self):
catalog = {"current_stable": "15", "versions": [
{"slug": "15", "status": "current", "nextcloud_min": 35,
From 060e235359f5c2e461d6ba9e1a6261b096d28de3 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 20:01:51 +0000
Subject: [PATCH 07/11] test(docs): include task shortcut targets in homepage
preview fixture
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
tests/test_versioning.py | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tests/test_versioning.py b/tests/test_versioning.py
index 3bb64681..e8278f96 100644
--- a/tests/test_versioning.py
+++ b/tests/test_versioning.py
@@ -220,6 +220,17 @@ def test_preview_review_link_is_valid_during_initial_site_verification(self):
directory = root / slug / manual
directory.mkdir(parents=True, exist_ok=True)
(directory / "index.html").write_text("Manual")
+ # The public homepage offers task shortcuts; include their targets
+ # in this minimal preview fixture before checking local links.
+ for route in (
+ "15/user_manual/start.html",
+ "15/user_manual/functionality.html",
+ "15/admin_manual/installation.html",
+ "15/developer_manual/integration/index.html",
+ ):
+ target = root / route
+ target.parent.mkdir(parents=True, exist_ok=True)
+ target.write_text("Fixture page")
for filename in ("home.css", "home-theme.js", "logo.png"):
(root / filename).write_text("asset")
with patch.dict("os.environ", {"LIBRESIGN_PREVIEW_PR": "127"}):
From 1f41343aa54700d8c7cb784c22f01d862d6e0441 Mon Sep 17 00:00:00 2001
From: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
Date: Mon, 9 Nov 2026 20:57:05 +0000
Subject: [PATCH 08/11] test(docs): avoid brittle assertions about
documentation layout
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
---
tests/test_seo.py | 15 ---------------
tests/test_versioning.py | 31 +------------------------------
2 files changed, 1 insertion(+), 45 deletions(-)
diff --git a/tests/test_seo.py b/tests/test_seo.py
index 24cdba3c..dfdd53c3 100644
--- a/tests/test_seo.py
+++ b/tests/test_seo.py
@@ -32,21 +32,6 @@ def page(self, name: str, body: str = "Article
"):
f"{body}