diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md
index 780e43e..5cf9900 100644
--- a/.claude/CLAUDE.md
+++ b/.claude/CLAUDE.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # CLAUDE.md - Claude Integrations
 
 ## Project Overview
@@ -83,7 +87,7 @@ Route to:
 name = "model-router"
 version = "0.1.0"
 authors = ["Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>"]
-license = "PMPL-1.0-or-later"
+license = "MPL-2.0-or-later"
 
 [dependencies]
 clap = { version = "4", features = ["derive"] }
@@ -113,6 +117,6 @@ model-router classify --repo /path/to/repo "add authentication"
 
 ## Code Style
 
-- SPDX headers: `PMPL-1.0-or-later`
+- SPDX headers: `MPL-2.0-or-later`
 - Author: Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 - Browser extensions use `MPL-2.0` fallback (store requirements)
diff --git a/.claude/PROJECT.md b/.claude/PROJECT.md
index 67bc22f..0f9e3f9 100644
--- a/.claude/PROJECT.md
+++ b/.claude/PROJECT.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # CI Infrastructure - Claude Code Instructions
 
 This repository contains CI/CD infrastructure configurations and scripts.
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 7f60a0c..3a3b7f2 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,9 +1,34 @@
-# Code Owners
+# SPDX-License-Identifier: MPL-2.0
+# CODEOWNERS - Define code review assignments for GitHub
+# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
 
-# Default: All contributors with write access are code owners
-* @metadatastician
+# Default: sole maintainer for all files
+* @hyperpolymath
 
-# For specific paths, add explicit owners below
-# Example:
-# /src/* @team-lead
-# /docs/* @docs-maintainer
+# Security-sensitive files require explicit ownership
+SECURITY.md @hyperpolymath
+.github/workflows/ @hyperpolymath
+.machine_readable/ @hyperpolymath
+contractiles/ @hyperpolymath
+
+# License files
+LICENSE @hyperpolymath
+LICENSES/ @hyperpolymath
+
+# Configuration
+.gitignore @hyperpolymath
+.github/ @hyperpolymath
+
+# Documentation
+README* @hyperpolymath
+CONTRIBUTING* @hyperpolymath
+CODE_OF_CONDUCT* @hyperpolymath
+GOVERNANCE* @hyperpolymath
+MAINTAINERS* @hyperpolymath
+CHANGELOG* @hyperpolymath
+ROADMAP* @hyperpolymath
+
+# Build and CI
+Justfile @hyperpolymath
+Makefile @hyperpolymath
+*.sh @hyperpolymath
diff --git a/.github/copilot/coding-agent.yml b/.github/copilot/coding-agent.yml
new file mode 100644
index 0000000..a719a77
--- /dev/null
+++ b/.github/copilot/coding-agent.yml
@@ -0,0 +1,6 @@
+mcp_servers:
+  boj-server:
+    command: npx
+    args: ["-y", "@hyperpolymath/boj-server@latest"]
+    env:
+      BOJ_URL: http://localhost:7700
diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml
index 019d7cf..8161ec2 100644
--- a/.github/workflows/governance.yml
+++ b/.github/workflows/governance.yml
@@ -1,21 +1,11 @@
-# SPDX-License-Identifier: MPL-2.0
-# governance.yml — single wrapper calling the shared estate governance bundle
-# in hyperpolymath/standards instead of carrying per-repo copies.
-#
-# Replaces the per-repo governance scaffolding removed in the same commit:
-#   quality.yml, guix-nix-policy.yml, npm-bun-blocker.yml, ts-blocker.yml,
-#   security-policy.yml, rsr-antipattern.yml, wellknown-enforcement.yml,
-#   workflow-linter.yml
-#
-# Load-bearing build/security workflows stay standalone in the repo
-# (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing).
-
+# SPDX-License-Identifier: PMPL-1.0-or-later
 name: Governance
 
 on:
   push:
     branches: [main, master]
   pull_request:
+    branches: [main, master]
   workflow_dispatch:
 
 permissions:
@@ -23,4 +13,4 @@ permissions:
 
 jobs:
   governance:
-    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9
\ No newline at end of file
+    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@5a93d9d57cc04de4002d6d0ecd336fc7a8698910
diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml
index 2e7e939..e715848 100644
--- a/.github/workflows/hypatia-scan.yml
+++ b/.github/workflows/hypatia-scan.yml
@@ -1,7 +1,4 @@
-# SPDX-License-Identifier: MPL-2.0
-# Thin wrapper around hyperpolymath/standards hypatia-scan-reusable.yml.
-# See standards#191 for the reusable's purpose and design.
-
+# SPDX-License-Identifier: PMPL-1.0-or-later
 name: Hypatia Security Scan
 
 on:
@@ -13,17 +10,10 @@ on:
     - cron: '0 0 * * 0'
   workflow_dispatch:
 
-# Estate guardrail: cancel superseded runs so re-pushes don't pile up.
-concurrency:
-  group: ${{ github.workflow }}-${{ github.ref }}
-  cancel-in-progress: true
-
 permissions:
   contents: read
-  security-events: write
-  pull-requests: write
+  security-events: read
 
 jobs:
-  hypatia:
-    uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9
-    secrets: inherit
\ No newline at end of file
+  scan:
+    uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@5a93d9d57cc04de4002d6d0ecd336fc7a8698910
diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml
index 9ed74ef..10729d0 100644
--- a/.github/workflows/secret-scanner.yml
+++ b/.github/workflows/secret-scanner.yml
@@ -1,23 +1,26 @@
 # SPDX-License-Identifier: MPL-2.0
 name: Secret Scanner
-
 on:
   pull_request:
   push:
     branches: [main]
-
 concurrency:
   group: ${{ github.workflow }}-${{ github.ref }}
   cancel-in-progress: true
-
 permissions:
   contents: read
-
 jobs:
   scan:
-    permissions:
-      contents: read
-      pull-requests: write
-      actions: read
-    uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@d135b05bfc647d0c0fbfedc7e80f37ea50f49236
-    secrets: inherit
\ No newline at end of file
+    uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@3e4bd4c93911750727e2e4c66dff859e00079da0
+    timeout-minutes: 10
+    secrets: inherit
+  trufflehog:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+      - name: TruffleHog Secret Scan
+        uses: trufflesecurity/trufflehog@main
+        with:
+          extra_args: --only-verified --fail
diff --git a/.machine_readable/6a2/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/0-AI-MANIFEST.a2ml
new file mode 100644
index 0000000..6bf1f8c
--- /dev/null
+++ b/.machine_readable/6a2/0-AI-MANIFEST.a2ml
@@ -0,0 +1,31 @@
+# AI Manifest for 6a2 Directory
+
+## Purpose
+
+This manifest declares the AI-assistant context for the 6a2 machine-readable metadata directory.
+
+## Canonical Locations
+
+The 6 core A2ML files MUST exist in this directory:
+1. AGENTIC.a2ml
+2. ECOSYSTEM.a2ml
+3. META.a2ml
+4. NEUROSYM.a2ml
+5. PLAYBOOK.a2ml
+6. STATE.a2ml
+
+## Invariants
+
+- No duplicate files in root directory
+- Single source of truth: this directory is authoritative
+- No stale metadata
+
+## Protocol
+
+When multiple agents may write to A2ML files concurrently:
+1. Read file and record git-sha-at-read in [provenance] section
+2. Lock by creating .lock-<FILENAME>
+3. Write updated file with new [provenance] metadata
+4. Release by removing lock file
+5. On conflict: re-read and retry if git-sha-at-read does not match HEAD
+
diff --git a/.machine_readable/6a2/AGENTIC.a2ml b/.machine_readable/6a2/AGENTIC.a2ml
new file mode 100644
index 0000000..b21d81b
--- /dev/null
+++ b/.machine_readable/6a2/AGENTIC.a2ml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# AGENTIC.a2ml — AI agent constraints and capabilities
+# Defines what AI agents can and cannot do in this repository.
+
+[metadata]
+version = "0.1.0"
+last-updated = "2026-04-11"
+
+[agent-permissions]
+can-edit-source = true
+can-edit-tests = true
+can-edit-docs = true
+can-edit-config = true
+can-create-files = true
+
+[agent-constraints]
+# What AI agents must NOT do:
+# - Never use banned language patterns (believe_me, unsafeCoerce, etc.)
+# - Never commit secrets or credentials
+# - Never use banned languages (TypeScript, Python, Go, etc.)
+# - Never place state files in repository root (must be in .machine_readable/)
+# - Never use AGPL license (use MPL-2.0)
+
+[maintenance-integrity]
+fail-closed = true
+require-evidence-per-step = true
+allow-silent-skip = false
+require-rerun-after-fix = true
+release-claim-requires-hard-pass = true
+
+# ============================================================================
+# METHODOLOGY (ADR-002)
+# ============================================================================
+# Detailed methodology configuration lives in:
+#   .machine_readable/bot_directives/methodology.a2ml
+#   .machine_readable/bot_directives/coverage.a2ml
+#   .machine_readable/bot_directives/debt.a2ml
+#
+# AGENTIC.a2ml declares WHAT agents can do (permissions, gating).
+# bot_directives/ declares HOW agents should work (methodology).
+
+[methodology]
+instructions-dir = ".machine_readable/bot_directives/"
+default-mode = "hybrid"
+
+[automation-hooks]
+# on-enter: Read 0-AI-MANIFEST.a2ml, then STATE.a2ml, then bot_directives/
+# on-exit: Update STATE.a2ml, coverage.a2ml, and debt.a2ml with session outcomes
+# on-commit: Run just validate-rsr
diff --git a/.machine_readable/ECOSYSTEM.scm b/.machine_readable/6a2/ECOSYSTEM.a2ml
similarity index 67%
rename from .machine_readable/ECOSYSTEM.scm
rename to .machine_readable/6a2/ECOSYSTEM.a2ml
index 4885678..0be8472 100644
--- a/.machine_readable/ECOSYSTEM.scm
+++ b/.machine_readable/6a2/ECOSYSTEM.a2ml
@@ -1,4 +1,12 @@
-; SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# ECOSYSTEM.a2ml — Transpiled from .scm format
+[metadata]
+converted-from-scm = true
+conversion-date = "2026-06-01T01:32:50Z"
+
+; SPDX-License-Identifier: PMPL-1.0-or-later
 ; ECOSYSTEM.scm - Ecosystem position for claude-integrations
 
 (ecosystem
diff --git a/.machine_readable/META.scm b/.machine_readable/6a2/META.a2ml
similarity index 70%
rename from .machine_readable/META.scm
rename to .machine_readable/6a2/META.a2ml
index b8dfae5..2981ef5 100644
--- a/.machine_readable/META.scm
+++ b/.machine_readable/6a2/META.a2ml
@@ -1,4 +1,12 @@
-; SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# META.a2ml — Transpiled from .scm format
+[metadata]
+converted-from-scm = true
+conversion-date = "2026-06-01T01:32:50Z"
+
+; SPDX-License-Identifier: PMPL-1.0-or-later
 ; META.scm - Meta-level information for claude-integrations
 
 (meta
diff --git a/.machine_readable/6a2/NEUROSYM.a2ml b/.machine_readable/6a2/NEUROSYM.a2ml
new file mode 100644
index 0000000..1acf7a3
--- /dev/null
+++ b/.machine_readable/6a2/NEUROSYM.a2ml
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# NEUROSYM.a2ml — Neurosymbolic integration metadata
+# Configuration for Hypatia scanning and symbolic reasoning.
+
+[metadata]
+version = "0.1.0"
+last-updated = "2026-04-11"
+
+[hypatia-config]
+scan-enabled = true
+scan-depth = "standard"  # quick | standard | deep
+report-format = "logtalk"
+
+[symbolic-rules]
+# Custom symbolic rules for this project
+# - { name = "no-unsafe-ffi", pattern = "believe_me|unsafeCoerce", severity = "critical" }
+
+[neural-config]
+# Neural pattern detection settings
+# confidence-threshold = 0.85
+# model = "hypatia-v2"
diff --git a/.machine_readable/6a2/PLAYBOOK.a2ml b/.machine_readable/6a2/PLAYBOOK.a2ml
new file mode 100644
index 0000000..676ec4c
--- /dev/null
+++ b/.machine_readable/6a2/PLAYBOOK.a2ml
@@ -0,0 +1,137 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# PLAYBOOK.a2ml — Operational playbook
+# Runbooks, incident response, deployment procedures.
+
+[metadata]
+version = "0.1.0"
+last-updated = "2026-04-11"
+
+[deployment]
+# method = "gitops"  # gitops | manual | ci-triggered
+# target = "container"  # container | binary | library | wasm
+
+[incident-response]
+# 1. Check .machine_readable/STATE.a2ml for current status
+# 2. Review recent commits and CI results
+# 3. Run `just validate` to check compliance
+# 4. Run `just security` to audit for vulnerabilities
+
+[release-process]
+# 1. Update version in STATE.a2ml, META.a2ml, Justfile
+# 2. Run `just release-preflight` (validate + quality + security + maint-hard-pass)
+# 3. Optional local permission hardening: `just perms-snapshot && just perms-lock`
+# 4. Tag and push
+# 5. Restore local permissions if needed: `just perms-restore`
+# 6. Run `just container-push` if applicable
+
+[maintenance-operations]
+# Baseline audit:
+#   just maint-audit
+# Hard release gate:
+#   just maint-hard-pass
+# Permission audit:
+#   just perms-audit
+
+[rsr-repo-skeleton]
+# Canonical organisation of any RSR-derived repository.
+# Used by tooling, human onboarding, and the scheduled downstream sweep agent.
+# The 5-PR cleanup pattern (below) brings a non-conforming repository into
+# compliance with this skeleton.
+#
+# This section is the single source of truth for "what does an RSR repo look
+# like?". Other docs (TOPOLOGY, AUDIT, etc.) describe the repo at hand;
+# this describes the canonical shape that all RSR repos share.
+
+skeleton-version = "1.0"
+last-updated = "2026-04-30"
+authority-allowlist = ".machine_readable/root-allow.txt"
+enforcement-workflow = ".github/workflows/estate-rules.yml"
+
+# === Required at root ===
+# README.adoc          High-level pitch (project entry point)
+# AUDIT.adoc           Local gate summary (release-readiness)
+# EXPLAINME.adoc       Developer deep-dive (architecture & invariants)
+# 0-AI-MANIFEST.a2ml   AI agent work-allocation policy
+# LICENSE              Repo license (root-bound by convention)
+# CHANGELOG.md         One of the recognised .md exceptions (see below)
+# Justfile             Task runner — thin, imports per-section files from build/just/
+# coordination.k9      Repo-local session binding
+
+# === Required directories ===
+# .github/             CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, workflows/
+# .machine_readable/   AI manifests (0.1-AI-MANIFEST.a2ml), 6a2/ checkpoints,
+#                      contractiles/, configs/, anchors/, policies/, scripts/, svc/
+# build/               contractile.just, flake.nix, guix.scm, Containerfile,
+#                      just/*.just (Justfile section imports)
+# docs/                onboarding/, status/, architecture/, governance/  (all .adoc)
+# session/             dispatch.sh, custom-checks.k9, local-hooks.sh
+# src/                 Project source (Idris2 ABI under abi/, Zig FFI under ffi/)
+# tests/, benches/, examples/, features/, scripts/, verification/, container/
+
+# === Documentation format rule ===
+# `.adoc` is the default for all general docs (TOPOLOGY, READINESS, ROADMAP,
+# TEST-NEEDS, PROOF-NEEDS, PROOF-STATUS, llm-warmup-*, etc.).
+#
+# `.md` is reserved ONLY for files GitHub's community-health rules
+# special-case by name:
+#   CONTRIBUTING.md  CODE_OF_CONDUCT.md  SECURITY.md  CHANGELOG.md
+#
+# Enforcement: `scripts/check-no-md-in-docs.sh` (fails if any *.md under docs/).
+
+# === Banned: ziguage ===
+# V (vlang.io) is banned estate-wide. Replaced by `zig-unified-api-adapter`
+# (16 endpoints + transaction-based firewall gating). Do not introduce
+# zig code, scaffolders, or references. Note that Coq theorem files use
+# the same `.v` extension and are unaffected — the rule looks at content
+# patterns, not the extension.
+#
+# Enforcement: `scripts/check-no-vlang.sh`.
+
+# === Justfile structure (post-split) ===
+# The root Justfile is thin — it holds `set` directives, project metadata
+# variables, and the `default`/`help`/`info` recipes. Each major section
+# lives in its own file under build/just/ and is brought in via `import?`.
+#
+# Imported sections (in the canonical split):
+#   build/just/init.just       INIT recipe (template bootstrap)
+#   build/just/assess.just     self-assess + verify (OpenSSF compliance)
+#   build/just/validate.just   validate-rsr/state/ai-install + aggregate
+#   build/just/proofs.just     proof-check-{all,idris2,lean4,agda,coq},
+#                              proof-scan-dangerous, proof-status
+#   build/just/groove.just     Groove protocol setup (after zig removed)
+#
+# Daily-use recipes (BUILD, TEST, LINT, RUN, DEPS, DOCS, CONTAINER, CI,
+# SECURITY, STATE, GUIX/NIX, MATRIX, VERSION CONTROL, UTILITIES, SESSION)
+# stay in the root Justfile where users expect to find them.
+
+# === 5-PR cleanup pattern ===
+# Apply these branches (in order) to bring a non-conforming downstream repo
+# into compliance with this skeleton:
+#
+# 1. chore/root-cleanup       Relocate root sprawl per root-allow.txt; add
+#                             scripts/check-root-shape.sh; remove stub
+#                             health files shadowed by .github/ versions.
+# 2. chore/remove-zig      Purge zig remnants (gen-v-connector recipe,
+#                             "V-TRIPLE" section header, "V-triple
+#                             connectors" comment in groove.a2ml).
+# 3. chore/md-to-adoc         Port general docs in docs/ from .md to .adoc;
+#                             update validate-template.sh to accept .adoc
+#                             fallbacks.
+# 4. chore/estate-rules-ci    Add scripts/check-no-md-in-docs.sh + check-no-
+#                             vlang.sh + .github/workflows/estate-rules.yml.
+# 5. chore/<repo>-hygiene     Repo-specific drift cleanup (case collisions,
+#                             template-derivation drift in titles, etc.).
+
+# === Reference scripts ===
+# scripts/check-root-shape.sh      Root allowlist validator
+# scripts/check-no-md-in-docs.sh   AsciiDoc-by-default validator
+# scripts/check-no-vlang.sh        zig ban validator
+# scripts/validate-template.sh     Aggregate RSR compliance (workflows, SPDX, etc.)
+
+# === Reference memory entries (for AI agents) ===
+# feedback_adoc_default_md_for_githealth   AsciiDoc-by-default rule
+# feedback_v_lang_banned                   zig ban
+# project_zig_unified_api                  Replacement for v-triple/zig
+# feedback_gh_workflow_scope               OAuth scope for workflow files
diff --git a/.machine_readable/6a2/README.adoc b/.machine_readable/6a2/README.adoc
new file mode 100644
index 0000000..bc033d7
--- /dev/null
+++ b/.machine_readable/6a2/README.adoc
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+# A2ML 6a2 Directory
+
+This directory contains the 6 core A2ML machine-readable metadata files for this repository.
+
+## Files
+
+- `AGENTIC.a2ml` - AI agent operational gating, safety controls
+- `ECOSYSTEM.a2ml` - Project ecosystem position, relationships, explicit boundaries
+- `META.a2ml` - Architecture decisions (ADRs), development practices, design rationale
+- `NEUROSYM.a2ml` - Symbolic semantics, composition algebra
+- `PLAYBOOK.a2ml` - Executable plans, operational runbooks
+- `STATE.a2ml` - Project state, phase, milestones, session history
+
+## Standards Compliance
+
+These files follow the A2ML Format Family specification from:
+https://github.com/hyperpolymath/standards/tree/main/a2ml
+
+## Generation
+
+These files may be generated from .scm source files using transpilation tools.
+Source .scm files should be removed after successful transpilation.
+
+## See Also
+
+- [A2ML Repository Template](https://github.com/hyperpolymath/standards/blob/main/A2ML-REPO-TEMPLATE.adoc)
+- [6A2 Format Family](https://github.com/hyperpolymath/standards#a2ml-format-family-7-formats)
+
diff --git a/.machine_readable/STATE.scm b/.machine_readable/6a2/STATE.a2ml
similarity index 71%
rename from .machine_readable/STATE.scm
rename to .machine_readable/6a2/STATE.a2ml
index 0d82960..d0c05b5 100644
--- a/.machine_readable/STATE.scm
+++ b/.machine_readable/6a2/STATE.a2ml
@@ -1,4 +1,12 @@
-; SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# STATE.a2ml — Transpiled from .scm format
+[metadata]
+converted-from-scm = true
+conversion-date = "2026-06-01T01:32:50Z"
+
+; SPDX-License-Identifier: PMPL-1.0-or-later
 ; STATE.scm - Current project state for claude-integrations
 
 (state
diff --git a/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml
new file mode 100644
index 0000000..0dd6825
--- /dev/null
+++ b/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml
@@ -0,0 +1,21 @@
+# AI Manifest for Anchor Directory
+
+## Purpose
+
+This manifest declares the AI-assistant context for the anchor machine-readable metadata directory.
+
+## Canonical Locations
+
+ANCHOR.a2ml files MUST exist in this directory.
+
+## Multiple Versions
+
+Unlike other A2ML files, multiple versions of ANCHOR.a2ml with different dates MAY exist.
+Each version represents a specific recalibration point.
+
+## Invariants
+
+- Multiple versions with different dates are permitted
+- No other A2ML files in this directory
+- Single source of truth for anchor documents
+
diff --git a/.machine_readable/6a2/anchor/README.adoc b/.machine_readable/6a2/anchor/README.adoc
new file mode 100644
index 0000000..bd23e35
--- /dev/null
+++ b/.machine_readable/6a2/anchor/README.adoc
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+# A2ML Anchor Directory
+
+This directory contains ANCHOR.a2ml files for project recalibration and scope intervention.
+
+## Files
+
+- `ANCHOR.a2ml` - Project recalibration, scope intervention, canonical authority
+
+## Multiple Versions
+
+Unlike other A2ML files, multiple versions of ANCHOR.a2ml with different dates may exist.
+Each version represents a specific recalibration point in the project history.
+
+## Standards Compliance
+
+These files follow the ANCHOR.a2ml specification from:
+https://github.com/hyperpolymath/standards/tree/main/anchor-a2ml
+
+## See Also
+
+- [A2ML Repository Template](https://github.com/hyperpolymath/standards/blob/main/A2ML-REPO-TEMPLATE.adoc)
+- [Anchor A2ML Spec](https://github.com/hyperpolymath/standards/tree/main/anchor-a2ml)
+
diff --git a/.machine_readable/contractiles/Adjustfile.a2ml b/.machine_readable/contractiles/Adjustfile.a2ml
new file mode 100644
index 0000000..6f01e89
--- /dev/null
+++ b/.machine_readable/contractiles/Adjustfile.a2ml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: MPL-2.0
+# Adjustfile — Drift-tolerance contract for rsr-template-repo
+# Author: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+#
+# Cumulative-drift catchment: tolerance bands + corrective actions.
+# Authority: advisory (Yard) — continue-with-warnings; auto_fix where deterministic.
+# Run with: adjust check
+# Fix with: adjust fix (applies deterministic patches; advisory otherwise)
+
+@abstract:
+Drift tolerances and corrective actions for rsr-template-repo. Unlike
+MUST (hard gate), ADJUST tracks cumulative drift against tolerance bands
+and proposes corrective actions. Advisory — it warns and trends, it does
+not block.
+@end
+
+## Template Drift
+
+### placeholder-drift
+- description: Template placeholders should be replaced when copied
+- tolerance: 0 placeholder markers in copied repos
+- corrective: Search and replace all {{PLACEHOLDER}} markers
+- severity: advisory
+- notes: This check only applies to repos that copied from this template
+
+### template-version-drift
+- description: Template version should match RSR spec version
+- tolerance: Template version matches current RSR spec
+- corrective: Update template to match latest RSR spec
+- severity: advisory
+
+## Documentation Drift
+
+### readme-completeness
+- description: README should document all template features
+- tolerance: README covers all contractiles and directory structure
+- corrective: Update README.adoc with missing sections
+- severity: advisory
+
+### example-accuracy
+- description: Examples in documentation should match actual template content
+- tolerance: All code examples in docs are accurate
+- corrective: Audit and fix examples in documentation
+- severity: advisory
+
+## Structural Drift
+
+### contractile-sync
+- description: All contractiles should have matching a2ml and ncl implementations
+- tolerance: Every .a2ml has a corresponding .ncl
+- corrective: Generate missing .ncl files from .a2ml
+- severity: advisory
+
+### no-broken-symlinks
+- description: No broken symbolic links in template structure
+- tolerance: 0 broken symlinks
+- corrective: Run symlink-check script
+- severity: advisory
+
+## Accessibility Drift
+
+### adoc-not-md
+- description: Template docs should prefer AsciiDoc
+- tolerance: New prose docs are *.adoc
+- corrective: Convert any new *.md to *.adoc
+- severity: advisory
+
+### spdx-header-consistency
+- description: All template files have correct SPDX headers
+- tolerance: 0 files missing SPDX-License-Identifier
+- corrective: Add SPDX headers to files that need them
+- severity: advisory
diff --git a/.machine_readable/contractiles/Intentfile.a2ml b/.machine_readable/contractiles/Intentfile.a2ml
new file mode 100644
index 0000000..ef74f45
--- /dev/null
+++ b/.machine_readable/contractiles/Intentfile.a2ml
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: MPL-2.0
+# Intentfile (A2ML Canonical) — north-star contractile for rsr-template-repo
+# Author: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+#
+# Paired runner: intend.ncl
+# Verb:          intend
+#
+# Semantics: North-star contractile. Declares BOTH concrete committed
+#            next-actions AND horizon aspirations the project wishes to
+#            become. Two sections share one file because they answer
+#            the same question at different ranges:
+#              [[intents]] — "we WILL do this; track progress"
+#                            status: declared → in_progress → done |
+#                                    deferred | retired
+#              [[wishes]]  — "we WISH this were true; revisit later"
+#                            status: declared → in_progress → achieved |
+#                                    abandoned
+#                            grouped by horizon: near / mid / far.
+#            Non-gating — this is a report, not a gate. See the `must`
+#            contractile for hard gates.
+
+@abstract:
+North-star contractile for rsr-template-repo. This repository is the
+canonical template for Rhodium Standard Repository compliance. It provides
+the scaffold that all hyperpolymath repos should copy and customize.
+@end
+
+## Purpose
+
+The rsr-template-repo serves as the master template for all hyperpolymath
+repositories. It contains the complete set of contractile files, machine-readable
+specifications, and governance documentation that define the Rhodium Standard.
+
+Every new repository in the hyperpolymath estate should be initialized by
+copying this template and substituting the placeholder values with
+repo-specific content.
+
+## Anti-Purpose
+
+This repository is NOT:
+- A general-purpose project scaffold for external use (hyperpolymath-only)
+- A replacement for per-repo customization (all files must be bespoke)
+- A static template that never changes (evolves with RSR spec)
+- A runtime library or framework (build-time only)
+
+## If In Doubt
+
+If you are unsure whether a change is in scope, ask. Sensitive areas:
+- .machine_readable/ contractile definitions
+- RSR specification files
+- Governance templates
+- License policy documents
+
+## Committed Next-Actions
+
+### repo-initialization
+- description: Provide just copy-and-substitute template for new repos
+- probe: test -f scripts/init-repo.sh
+- status: done
+- notes: Run with source scripts/init-repo.sh <new-repo-name>
+
+### contractile-completeness
+- description: Every RSR contractile has an a2ml and ncl implementation
+- probe: ls .machine_readable/contractiles/*.a2ml | wc -l | grep -q "^6$"
+- status: in_progress
+- notes: Currently 6 contractile verbs: intend, must, trust, adjust, bust, dust
+
+### automation-scripts
+- description: All repetitive tasks have just recipes
+- probe: grep -c "^# " Justfile | grep -q "^[6-9][0-9]*$"
+- status: in_progress
+
+## Wishes
+
+### Near Horizon
+
+#### cross-repo-validation
+- description: Tooling to validate all repos against RSR spec
+- horizon: near
+- status: declared
+
+#### automated-substitution
+- description: Script to automate repo-specific substitution in template
+- horizon: near
+- status: declared
+
+### Mid Horizon
+
+#### formal-verification
+- description: Idris2 proofs for all critical contractile invariants
+- horizon: mid
+- status: declared
+
+### Far Horizon
+
+#### ecosystem-visualization
+- description: Interactive graph of all hyperpolymath repos and dependencies
+- horizon: far
+- status: declared
diff --git a/.machine_readable/contractiles/Justfile b/.machine_readable/contractiles/Justfile
new file mode 100644
index 0000000..d388444
--- /dev/null
+++ b/.machine_readable/contractiles/Justfile
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
+#
+# claude-integrations - Unified Claude browser/service integrations monorepo.
+
+# List available recipes
+default:
+	@just --list
+
+# --- Firefox LSP (Elixir) ---
+
+# Build the Firefox LSP component
+build-firefox-lsp:
+	cd firefox-lsp && mix deps.get && mix compile
+
+# Run Firefox LSP tests
+test-firefox-lsp:
+	cd firefox-lsp && mix test
+
+# --- Firefox MCP (Deno) ---
+
+# Build the Firefox MCP component
+build-firefox-mcp:
+	cd firefox-mcp && deno cache src/main.ts 2>/dev/null || echo "No Deno entrypoint cached"
+
+# Run Firefox MCP tests
+test-firefox-mcp:
+	cd firefox-mcp && deno test 2>/dev/null || echo "No Deno tests configured"
+
+# --- Gecko Browser Extension ---
+
+# Build the Gecko browser extension
+build-gecko-extension:
+	@echo "Gecko extension is pure JS/WebExtensions - no build step required."
+	@echo "Load as temporary add-on in about:debugging"
+
+# Lint the Gecko browser extension
+lint-gecko-extension:
+	cd gecko-browser-extension && web-ext lint 2>/dev/null || echo "Install web-ext: npm i -g web-ext"
+
+# --- GitLab Bridge (ReScript/Deno) ---
+
+# Build the GitLab Bridge component
+build-gitlab-bridge:
+	cd gitlab-bridge && deno cache src/main.ts 2>/dev/null || echo "No Deno entrypoint cached"
+
+# Run GitLab Bridge tests
+test-gitlab-bridge:
+	cd gitlab-bridge && deno test 2>/dev/null || echo "No Deno tests configured"
+
+# --- Mozilla Extension ---
+
+# Build the Mozilla extension
+build-mozilla-extension:
+	@echo "Mozilla extension is pure JS/WebExtensions - no build step required."
+	@echo "Load as temporary add-on in about:debugging"
+
+# Lint the Mozilla extension
+lint-mozilla-extension:
+	cd mozilla-extension && web-ext lint 2>/dev/null || echo "Install web-ext: npm i -g web-ext"
+
+# --- Aggregate Recipes ---
+
+# Build all components
+build-all: build-firefox-lsp build-firefox-mcp build-gecko-extension build-gitlab-bridge build-mozilla-extension
+
+# Run all tests
+test-all: test-firefox-lsp test-firefox-mcp test-gitlab-bridge
+
+# Lint all lintable components
+lint-all: lint-gecko-extension lint-mozilla-extension
+
+# Show status of all components
+status:
+	@echo "=== Firefox LSP ===" && ls firefox-lsp/mix.exs 2>/dev/null && echo "OK" || echo "MISSING"
+	@echo "=== Firefox MCP ===" && ls firefox-mcp/deno.json 2>/dev/null && echo "OK" || echo "MISSING"
+	@echo "=== Gecko Extension ===" && ls gecko-browser-extension/manifest.json 2>/dev/null && echo "OK" || echo "MISSING"
+	@echo "=== GitLab Bridge ===" && ls gitlab-bridge/deno.json 2>/dev/null && echo "OK" || echo "MISSING"
+	@echo "=== Mozilla Extension ===" && ls mozilla-extension/src/ 2>/dev/null && echo "OK" || echo "MISSING"
+
+secret-scan-trufflehog:
+    @command -v trufflehog >/dev/null && trufflehog filesystem . --only-verified || true
diff --git a/.machine_readable/contractiles/Mustfile.a2ml b/.machine_readable/contractiles/Mustfile.a2ml
new file mode 100644
index 0000000..55f8ab4
--- /dev/null
+++ b/.machine_readable/contractiles/Mustfile.a2ml
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: MPL-2.0
+# Mustfile — Physical state contract for rsr-template-repo
+# Author: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+#
+# What MUST be true about this repository. Hard requirements.
+# Run with: must check
+# Fix with: must fix (where a deterministic fix exists)
+
+@abstract:
+Physical-state invariants for rsr-template-repo. This is the canonical
+RSR template repository. These are hard requirements — CI and pre-commit
+hooks fail if any check fails.
+@end
+
+## File Presence
+
+### license-present
+- description: LICENSE file must exist
+- run: test -f LICENSE
+- severity: critical
+
+### readme-present
+- description: README.adoc must exist
+- run: test -f README.adoc
+- severity: critical
+
+### security-policy
+- description: SECURITY.md must exist
+- run: test -f SECURITY.md
+- severity: critical
+
+### ai-manifest
+- description: 0-AI-MANIFEST.a2ml must exist
+- run: test -f 0-AI-MANIFEST.a2ml
+- severity: critical
+
+### governance-docs
+- description: GOVERNANCE.adoc, MAINTAINERS.adoc, CODEOWNERS must exist
+- run: test -f GOVERNANCE.adoc && test -f MAINTAINERS.adoc && test -f .github/CODEOWNERS
+- severity: critical
+
+### machine-readable-dir
+- description: .machine_readable/ directory must exist
+- run: test -d .machine_readable
+- severity: critical
+
+## Directory Structure
+
+### contractiles-complete
+- description: All required contractile directories exist
+- run: test -d .machine_readable/contractiles && test -d .machine_readable/contractiles/bust && test -d .machine_readable/contractiles/dust
+- severity: critical
+
+### contractiles-files-present
+- description: All four primary contractile files exist
+- run: test -f .machine_readable/contractiles/Intentfile.a2ml && test -f .machine_readable/contractiles/Mustfile.a2ml && test -f .machine_readable/contractiles/Trustfile.a2ml && test -f .machine_readable/contractiles/Adjustfile.a2ml
+- severity: critical
+
+### bust-dust-files-present
+- description: Bustfile and Dustfile exist in their directories
+- run: test -f .machine_readable/contractiles/bust/Bustfile.a2ml && test -f .machine_readable/contractiles/dust/Dustfile.a2ml
+- severity: critical
+
+### six-directory-present
+- description: 6a2 directory exists with required files
+- run: test -d .machine_readable/6a2 && test -f .machine_readable/6a2/META.a2ml && test -f .machine_readable/6a2/ECOSYSTEM.a2ml && test -f .machine_readable/6a2/STATE.a2ml && test -f .machine_readable/6a2/PLAYBOOK.a2ml && test -f .machine_readable/6a2/AGENTIC.a2ml && test -f .machine_readable/6a2/NEUROSYM.a2ml
+- severity: critical
+
+### anchors-directory
+- description: anchors directory exists in 6a2
+- run: test -d .machine_readable/6a2/anchors
+- severity: warning
+
+### self-validating-structure
+- description: self-validating directory has k9-svc and examples
+- run: test -d .machine_readable/self-validating && test -d .machine_readable/self-validating/k9-svc && test -d .machine_readable/self-validating/examples
+- severity: warning
+
+## Template Integrity
+
+### no-placeholder-values
+- description: No placeholder values remain in template files
+- run: test -z "$(grep -r '{{' .machine_readable/contractiles/ 2>/dev/null)"
+- severity: critical
+- notes: All placeholders must be substituted when copying this template
+
+### template-readonly
+- description: Template marker files are not modified
+- run: grep -q 'RSR_TEMPLATE_DO_NOT_EDIT' .machine_readable/0.1-AI-MANIFEST.a2ml
+- severity: warning
+
+## Git State
+
+### no-untracked-contractiles
+- description: All contractile files are tracked in git
+- run: test -z "$(git ls-files -o --exclude-standard .machine_readable/contractiles/ 2>/dev/null)"
+- severity: critical
+
+### signed-commits
+- description: All commits must be signed
+- run: git verify-commit HEAD
+- severity: critical
diff --git a/.machine_readable/contractiles/Trustfile.a2ml b/.machine_readable/contractiles/Trustfile.a2ml
new file mode 100644
index 0000000..e2028b5
--- /dev/null
+++ b/.machine_readable/contractiles/Trustfile.a2ml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: MPL-2.0
+# Trustfile — Trust boundaries and integrity invariants for rsr-template-repo
+# Author: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+#
+# Defines what LLM/SLM agents are trusted to do without asking, and
+# integrity invariants that verify the repo has not been tampered with.
+
+@abstract:
+Trust boundaries and integrity checks for rsr-template-repo. This file
+combines the trust-level definitions from the original TRUST.contractile
+with the integrity invariants from the old Trustfile.a2ml. It defines
+what AI agents may do autonomously and what requires human approval,
+plus checks that verify repository integrity.
+@end
+
+## Trust Levels
+
+The rsr-template-repo operates at trust level: maximal
+
+Trust levels:
+- maximal:    Agent may read, build, test, lint, format, heal freely.
+             Only destructive/external actions require approval.
+- standard:   Agent may read and build. Test/lint need approval.
+- restricted: Agent may read only. All modifications need approval.
+- minimal:    Agent may read specific files only. Everything else blocked.
+
+Current trust level: maximal
+
+## Integrity Invariants
+
+### Secrets
+
+#### no-secrets-committed
+- description: No credential files in repo
+- run: test ! -f .env && test ! -f credentials.json && test ! -f .env.local && test ! -f .env.production
+- severity: critical
+
+#### no-private-keys
+- description: No private key files committed
+- run: "! find . -name '*.pem' -o -name '*.key' -o -name 'id_rsa' -o -name 'id_ed25519' 2>/dev/null | grep -v node_modules | head -1 | grep -q ."
+- severity: critical
+
+#### no-tokens-in-source
+- description: No hardcoded API tokens in source
+- run: "! grep -rE '(api[_-]?key|secret|token|password)\s*[:=]\s*[\"'\\''][A-Za-z0-9]{16,}' --include='*.js' --include='*.ts' --include='*.res' --include='*.py' . 2>/dev/null | grep -v node_modules | head -1 | grep -q ."
+- severity: critical
+
+## Provenance
+
+#### author-correct
+- description: Git author matches expected identity
+- run: "git log -1 --format='%ae' | grep -qE '(hyperpolymath|j\\.d\\.a\\.jewell)'"
+- severity: warning
+
+#### license-content
+- description: LICENSE contains expected identifier
+- run: grep -q 'PMPL\|MPL\|MIT\|Apache\|LGPL' LICENSE
+- severity: warning
+
+## Template-Specific Trust
+
+### template-files-readonly
+- description: Template scaffold files should not be modified except by maintainer
+- run: test -z "$(git status --short .machine_readable/ 2>/dev/null | grep -v '^??' || true)"
+- severity: advisory
+- notes: Changes to template files require careful review
+
+### trust-deny-areas
+- description: Sensitive areas from INTENT.contractile require explicit approval
+- run: echo "Check .machine_readable/ contractiles and governance docs"
+- severity: advisory
+- areas:
+  - .machine_readable/
+  - GOVERNANCE.adoc
+  - MAINTAINERS.adoc
+  - .github/CODEOWNERS
+
+## Container Security
+
+#### container-images-pinned
+- description: Containerfile uses pinned base images
+- run: test ! -f Containerfile || grep -q 'cgr.dev\|@sha256:' Containerfile
+- severity: warning
+
+#### no-dockerfile
+- description: No Dockerfile (use Containerfile)
+- run: test ! -f Dockerfile
+- severity: warning
diff --git a/.machine_readable/contractiles/bust/Bustfile.a2ml b/.machine_readable/contractiles/bust/Bustfile.a2ml
new file mode 100644
index 0000000..87e666c
--- /dev/null
+++ b/.machine_readable/contractiles/bust/Bustfile.a2ml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: MPL-2.0
+# Bustfile — failure mode contractile for claude-integrations
+# Author: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+#
+# Paired runner: bust.ncl
+# Verb:          bust
+# Semantics:     Every declared failure mode must have a working recovery path
+#                that has been exercised. Status moves:
+#                  declared → drilled (probe run) → verified (recovery confirmed)
+#                  or → failing (recovery broken)
+#
+# CLI:
+#   contractile bust check  → list failure modes + recovery status
+#   contractile bust drill  → inject failures, verify recovery paths
+#
+# This repository: claude-integrations is the canonical template for RSR compliance.
+# Failure modes here relate to template distribution and substitution.
+
+@abstract:
+Bustfile for claude-integrations. Lists failure modes specific to the template
+repository itself, particularly around template distribution, substitution,
+and synchronization across the hyperpolymath estate.
+@end
+
+## Failure Modes
+
+### template-substitution-failure
+- class: template_processing
+- description: Template substitution fails when initializing a new repo from this template
+- injection_probe: "cp -r claude-integrations test-repo && cd test-repo && sed -i 's/claude-integrations/TEST/g' .machine_readable/contractiles/Intentfile.a2ml && grep -q 'TEST' .machine_readable/contractiles/Intentfile.a2ml"
+- recovery_probe: "git -C test-repo diff --quiet .machine_readable/contractiles/Intentfile.a2ml"
+- expected_recovery_time_seconds: 10
+- status: declared
+- notes: Verify that substitution scripts handle all placeholder replacements correctly
+
+### sync-drift-between-repos
+- class: synchronization
+- description: Drift occurs between claude-integrations and other repos after template updates
+- injection_probe: "echo 'template_updated' > /tmp/test_drift_marker"
+- recovery_probe: "test -f /tmp/test_drift_marker && rm /tmp/test_drift_marker"
+- expected_recovery_time_seconds: 60
+- status: declared
+- notes: The estate-wide sync scripts (see scripts/) should prevent this; verify with scripts/verify-sync.sh
+
+### contractile-parse-error
+- class: contractile_format
+- description: A contractile file fails to parse due to syntax errors
+- injection_probe: "echo 'invalid syntax' >> claude-integrations/.machine_readable/contractiles/Intentfile.a2ml"
+- recovery_probe: "git checkout claude-integrations/.machine_readable/contractiles/Intentfile.a2ml"
+- expected_recovery_time_seconds: 5
+- status: declared
+- notes: All .a2ml files should be valid A2ML; use a2ml-validate runner
diff --git a/.machine_readable/contractiles/dust/Dustfile.a2ml b/.machine_readable/contractiles/dust/Dustfile.a2ml
new file mode 100644
index 0000000..c9324c6
--- /dev/null
+++ b/.machine_readable/contractiles/dust/Dustfile.a2ml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: MPL-2.0
+# Dustfile — Cleanup and hygiene contract for claude-integrations
+# Author: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+#
+# Paired runner: dust.ncl
+# Verb:          dust
+# Semantics:     What should be cleaned up. Housekeeping, not blockers.
+#
+# This repository: claude-integrations is the canonical template.
+# Cleanup items here ensure the template itself remains pristine.
+
+@abstract:
+Cleanup and hygiene items for claude-integrations. These are maintenance tasks
+that ensure the template repository remains clean and ready for distribution
+to new repositories.
+@end
+
+## Stale Files
+
+### no-template-artifacts
+- description: No generated files from template testing in root
+- run: test -z "$(ls template-test-* 2>/dev/null)"
+- severity: info
+- notes: Template testing should use /tmp or dedicated test directories
+
+### no-example-placeholders
+- description: No example placeholder files (EXAMPLE-, SAMPLE-) in contractiles/
+- run: test -z "$(find .machine_readable/contractiles/ -name 'EXAMPLE-*' -o -name 'SAMPLE-*' 2>/dev/null)"
+- severity: warning
+- notes: All placeholders should be replaced with actual content or removed
+
+### no-old-contractile-formats
+- description: No old .contractile or .hs files remaining
+- run: test -z "$(find .machine_readable/contractiles/ \( -name '*.contractile' -o -name '*.hs' \) 2>/dev/null)"
+- severity: warning
+- notes: All contractiles should be .a2ml format
+
+## Format Duplicates
+
+### no-duplicate-justfile
+- description: Only one Justfile (hardlinked from root to .machine_readable/contractiles/)
+- run: test $(stat -c '%i' Justfile) = $(stat -c '%i' .machine_readable/contractiles/Justfile 2>/dev/null)
+- severity: warning
+- notes: Justfile should be hardlinked, not copied
+
+### no-duplicate-readme-format
+- description: Only one README format in contractiles/ (.adoc canonical)
+- run: test ! -f .machine_readable/contractiles/README.md
+- severity: info
+
+## Template Hygiene
+
+### no-stale-template-references
+- description: No references to claude-integrations in generic template files
+- run: test -z "$(grep -r 'claude-integrations' machine-readable-design/ 2>/dev/null)"
+- severity: warning
+- notes: Generic templates should use {{PROJECT_NAME}} or similar placeholders
+
+### version-sync-checked
+- description: Version in canonical-directory-structure matches .machine_readable/contractiles
+- verification: compare version identifiers in both locations
+- severity: info
diff --git a/.machine_readable/svc/README.adoc b/.machine_readable/svc/README.adoc
index 840ae51..b1f2928 100644
--- a/.machine_readable/svc/README.adoc
+++ b/.machine_readable/svc/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = `.machine_readable/svc/` — Service components for claude-integrations
 :toc:
 
diff --git a/.machine_readable/svc/k9/README.adoc b/.machine_readable/svc/self-validating/README.adoc
similarity index 85%
rename from .machine_readable/svc/k9/README.adoc
rename to .machine_readable/svc/self-validating/README.adoc
index 6f9ac77..909ebcf 100644
--- a/.machine_readable/svc/k9/README.adoc
+++ b/.machine_readable/svc/self-validating/README.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = K9 Contractiles
 :toc: left
 :icons: font
@@ -71,13 +72,13 @@ Choose the appropriate security level for your use case:
 [source,bash]
 ----
 # Kennel: Pure configuration
-cp contractiles/k9/examples/project-metadata.k9.ncl config/metadata.k9.ncl
+cp contractiles/self-validating/examples/project-metadata.k9.ncl config/metadata.k9.ncl
 
 # Yard: Validated configuration
-cp contractiles/k9/examples/ci-config.k9.ncl .github/ci.k9.ncl
+cp contractiles/self-validating/examples/ci-config.k9.ncl .github/ci.k9.ncl
 
 # Hunt: Full automation
-cp contractiles/k9/examples/setup-repo.k9.ncl scripts/setup.k9.ncl
+cp contractiles/self-validating/examples/setup-repo.k9.ncl scripts/setup.k9.ncl
 ----
 
 === 2. Validate Components
@@ -130,7 +131,7 @@ K9 contractiles integrate with other RSR standards:
 ⚠️ **Never run as root unless required** +
 ⚠️ **Sandbox external components**
 
-**See:** https://github.com/hyperpolymath/k9-svc/blob/main/docs/SECURITY-BEST-PRACTICES.adoc
+**See:** https://github.com/hyperpolymath/self-validating/blob/main/docs/SECURITY-BEST-PRACTICES.adoc
 
 == Template Files
 
@@ -159,9 +160,9 @@ git clone https://github.com/hyperpolymath/k9-svc.git
 
 == Learn More
 
-- **K9-SVC Specification:** https://github.com/hyperpolymath/k9-svc/blob/main/SPEC.adoc
-- **K9 User Guide:** https://github.com/hyperpolymath/k9-svc/blob/main/GUIDE.adoc
-- **Security Documentation:** https://github.com/hyperpolymath/k9-svc/blob/main/docs/SECURITY-FAQ.adoc
+- **K9-SVC Specification:** https://github.com/hyperpolymath/self-validating/blob/main/SPEC.adoc
+- **K9 User Guide:** https://github.com/hyperpolymath/self-validating/blob/main/GUIDE.adoc
+- **Security Documentation:** https://github.com/hyperpolymath/self-validating/blob/main/docs/SECURITY-FAQ.adoc
 - **IANA Media Type:** `application/vnd.k9+nickel`
 
 == Contributing
diff --git a/.machine_readable/svc/k9/examples/ci-config.k9.ncl b/.machine_readable/svc/self-validating/examples/ci-config.k9.ncl
similarity index 100%
rename from .machine_readable/svc/k9/examples/ci-config.k9.ncl
rename to .machine_readable/svc/self-validating/examples/ci-config.k9.ncl
diff --git a/.machine_readable/svc/k9/examples/project-metadata.k9.ncl b/.machine_readable/svc/self-validating/examples/project-metadata.k9.ncl
similarity index 100%
rename from .machine_readable/svc/k9/examples/project-metadata.k9.ncl
rename to .machine_readable/svc/self-validating/examples/project-metadata.k9.ncl
diff --git a/.machine_readable/svc/k9/examples/setup-repo.k9.ncl b/.machine_readable/svc/self-validating/examples/setup-repo.k9.ncl
similarity index 99%
rename from .machine_readable/svc/k9/examples/setup-repo.k9.ncl
rename to .machine_readable/svc/self-validating/examples/setup-repo.k9.ncl
index d23b033..ed3a025 100644
--- a/.machine_readable/svc/k9/examples/setup-repo.k9.ncl
+++ b/.machine_readable/svc/self-validating/examples/setup-repo.k9.ncl
@@ -95,7 +95,7 @@ K9!
       commands = [
         "mkdir -p src/ docs/ tests/ scripts/",
         "mkdir -p .github/workflows/",
-        "mkdir -p contractiles/k9/",
+        "mkdir -p contractiles/self-validating/",
         "echo '✓ Directory structure created'",
       ],
     },
diff --git a/.machine_readable/svc/k9/template-hunt.k9.ncl b/.machine_readable/svc/self-validating/template-hunt.k9.ncl
similarity index 100%
rename from .machine_readable/svc/k9/template-hunt.k9.ncl
rename to .machine_readable/svc/self-validating/template-hunt.k9.ncl
diff --git a/.machine_readable/svc/k9/template-kennel.k9.ncl b/.machine_readable/svc/self-validating/template-kennel.k9.ncl
similarity index 100%
rename from .machine_readable/svc/k9/template-kennel.k9.ncl
rename to .machine_readable/svc/self-validating/template-kennel.k9.ncl
diff --git a/.machine_readable/svc/k9/template-yard.k9.ncl b/.machine_readable/svc/self-validating/template-yard.k9.ncl
similarity index 100%
rename from .machine_readable/svc/k9/template-yard.k9.ncl
rename to .machine_readable/svc/self-validating/template-yard.k9.ncl
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25f5def..ebeea26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,7 @@
 <!--
-SPDX-License-Identifier: CC-BY-SA-4.0
-SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath)
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 -->
-
 # Changelog
 
 All notable changes to `claude-integrations` will be documented in this file.
diff --git a/GOVERNANCE.adoc b/GOVERNANCE.adoc
new file mode 100644
index 0000000..8bbf167
--- /dev/null
+++ b/GOVERNANCE.adoc
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: MPL-2.0
+// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+= Governance Model
+:toc: preamble
+
+This document describes the governance model for this repository.
+
+== Overview
+
+This repository follows a **Sole Maintainer Governance Model**:
+
+* Single maintainer (@hyperpolymath) has full authority over the project
+* All contributions are welcome and reviewed by the maintainer
+* Decisions are made transparently through GitHub issues and discussions
+* The project adheres to the hyperpolymath estate policies where applicable
+
+== Core Principles
+
+[cols="1,2"]
+|===
+| Principle | Description
+
+| **Benevolent Dictatorship** | Maintainer has final decision authority but seeks community input
+
+| **Meritocracy** | Contributions are judged on technical merit, not contributor identity
+
+| **Transparency** | All significant decisions are documented publicly
+
+| **Consensus-Seeking** | Maintainer prefers consensus but will decide when necessary
+
+| **Open Contribution** | Anyone can contribute via fork and pull request
+
+|===
+
+== Roles and Permissions
+
+[cols="1,2,2"]
+|===
+| Role | Permissions | Assignment
+
+| **Maintainer** | Write access, merge rights, admin | @hyperpolymath
+| **Contributors** | Read access, fork, submit PRs | All GitHub users
+| **Users** | Use the software, report issues | All GitHub users
+
+|===
+
+== Decision Making Framework
+
+=== Routine Decisions
+
+* Bug fixes
+* Documentation improvements
+* Minor feature additions
+* Dependency updates
+
+**Process**: Maintainer reviews and merges PRs that meet quality standards.
+
+=== Significant Changes
+
+* New major features
+* API changes
+* Architecture modifications
+* Breaking changes
+
+**Process**:
+. Open issue describing the change
+. Discuss with community (minimum 72 hours)
+. Maintainer makes final decision
+. Document rationale in issue/PR
+
+=== Structural Decisions
+
+* Repository purpose/renaming
+* License changes
+* Ownership transfer
+* Deprecation/archival
+
+**Process**: 
+. Extended discussion (minimum 1 week)
+. Maintainer makes final decision
+. Document in CHANGELOG and governance docs
+
+== Contribution Lifecycle
+
+[cols="1,2"]
+|===
+| Stage | Process
+
+| **Ideation** | Open issue, discuss feasibility
+
+| **Development** | Fork, implement, test thoroughly
+
+| **Review** | Submit PR, maintainer reviews within 7 days
+
+| **Merge** | Maintainer merges or requests changes
+
+| **Release** | Maintainer publishes according to project conventions
+
+|===
+
+== Conflict Resolution
+
+In case of disagreements:
+
+. Discuss in the relevant GitHub issue or PR
+. Provide technical justification for positions
+. Maintainer mediates and makes final decision
+. Decision is documented and can be revisited later
+
+== Project Policies
+
+This repository adheres to hyperpolymath estate-wide policies:
+
+* **License**: MPL-2.0 for code, CC-BY-SA-4.0 for prose (per standards/LICENCE-POLICY.adoc)
+* **Code of Conduct**: Follows hyperpolymath CODE_OF_CONDUCT.md
+* **Security**: Follows hyperpolymath SECURITY.md
+* **Contributing**: Follows hyperpolymath CONTRIBUTING.adoc conventions
+
+== Repository-Specific Conventions
+
+[cols="1,2"]
+|===
+| Convention | Description
+
+| **Signing** | All commits must be signed (SSH or GPG)
+
+| **SPDX Headers** | All source files must have SPDX license identifiers
+
+| **Contractiles** | Mustfile, Trustfile, Intendfile, Adjustfile in root
+
+| **Machine Readable** | META.a2ml in .machine_readable/6a2/
+
+| **CI/CD** | GitHub Actions workflows in .github/workflows/
+
+|===
+
+== Governance Evolution
+
+As the project grows, this governance model may evolve:
+
+* **Adding Co-Maintainers**: When contribution volume warrants it
+* **Forming a Team**: For complex multi-maintainer projects
+* **Adopting TPCF**: For large, multi-repository projects (see rhodium-standard-repositories)
+
+Changes to this document require the same process as Significant Changes above.
+
+== See Also
+
+* link:MAINTAINERS.adoc[Maintainers]
+* link:CODE_OF_CONDUCT.md[Code of Conduct]
+* link:CONTRIBUTING.adoc[Contributing Guide]
+* link:https://github.com/hyperpolymath/standards/blob/main/LICENCE-POLICY.adoc[Estate License Policy]
+* link:https://github.com/hyperpolymath/standards[rhodium-standard-repositories (TPCF)]
+
+== Changelog
+
+[cols="1,1,1"]
+|===
+| Date | Change | By
+
+| 2026-06-07 | Initial governance model established | @hyperpolymath
+|===
diff --git a/Justfile b/Justfile
index 10778eb..34597c0 100644
--- a/Justfile
+++ b/Justfile
@@ -77,3 +77,6 @@ status:
 	@echo "=== Gecko Extension ===" && ls gecko-browser-extension/manifest.json 2>/dev/null && echo "OK" || echo "MISSING"
 	@echo "=== GitLab Bridge ===" && ls gitlab-bridge/deno.json 2>/dev/null && echo "OK" || echo "MISSING"
 	@echo "=== Mozilla Extension ===" && ls mozilla-extension/src/ 2>/dev/null && echo "OK" || echo "MISSING"
+
+secret-scan-trufflehog:
+    @command -v trufflehog >/dev/null && trufflehog filesystem . --only-verified || true
diff --git a/LICENSE b/LICENSE
index 14e2f77..ee6256c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -357,7 +357,7 @@ Exhibit A - Source Code Form License Notice
 
   This Source Code Form is subject to the terms of the Mozilla Public
   License, v. 2.0. If a copy of the MPL was not distributed with this
-  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+  file, You can obtain one at https://mozilla.org/MPL/2.0/.
 
 If it is not possible or desirable to put the notice in a particular
 file, then You may include the notice in a location (such as a LICENSE
diff --git a/MAINTAINERS.adoc b/MAINTAINERS.adoc
new file mode 100644
index 0000000..9910dd8
--- /dev/null
+++ b/MAINTAINERS.adoc
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: MPL-2.0
+// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+= Maintainers
+:toc: preamble
+
+== Current Maintainers
+
+[cols="2,3,2",options="header"]
+|===
+| Name | Role | Contact
+
+| Jonathan D.A. Jewell | Sole Maintainer | https://github.com/hyperpolymath[@hyperpolymath]
+|===
+
+== Maintainer Responsibilities
+
+As the sole maintainer, all responsibilities apply to @hyperpolymath:
+
+* Reviewing and merging pull requests
+* Triaging issues and feature requests
+* Ensuring code quality and security standards
+* Managing releases and versioning
+* Upholding the project's Code of Conduct
+* Maintaining documentation and examples
+* Responding to security vulnerabilities
+
+== Contribution Process
+
+This is a sole-maintainer project. All contributions are welcome via:
+
+1. **Issues**: Report bugs, request features, ask questions
+2. **Pull Requests**: Submit improvements for review
+3. **Discussions**: Engage in community discussions
+
+All contributions will be reviewed by the maintainer.
+
+== Decision Making
+
+* Routine decisions (bug fixes, minor improvements): Made by maintainer
+* Significant changes: Discussed in issues before implementation
+* Breaking changes: Announced in advance with migration path
+
+== Becoming a Maintainer
+
+This project currently has a single maintainer. If you're interested in becoming a co-maintainer:
+
+1. Demonstrate consistent, high-quality contributions
+2. Show understanding of project goals and standards
+3. Participate constructively in discussions
+4. Express interest to the current maintainer
+
+Co-maintainers may be added at the discretion of the current maintainer.
+
+== Contact
+
+For questions about project governance:
+
+* Open a GitHub issue in this repository
+* Contact: https://github.com/hyperpolymath
+
+== See Also
+
+* link:GOVERNANCE.adoc[Governance Model]
+* link:CODE_OF_CONDUCT.md[Code of Conduct]
+* link:CONTRIBUTING.adoc[Contributing Guide]
diff --git a/docs/architecture.adoc b/docs/architecture.adoc
index d1a9b91..6b480c5 100644
--- a/docs/architecture.adoc
+++ b/docs/architecture.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <6759885+hyperpolymath@users.noreply.github.com>
 = Architecture — claude-integrations
 :revdate: 2026-MM-DD
diff --git a/docs/contributing.adoc b/docs/contributing.adoc
index baa1bbc..9ffbd06 100644
--- a/docs/contributing.adoc
+++ b/docs/contributing.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <6759885+hyperpolymath@users.noreply.github.com>
 = Contributing — claude-integrations
 :revdate: 2026-MM-DD
diff --git a/docs/decisions/0001-template.adoc b/docs/decisions/0001-template.adoc
index 0ebe392..02ede78 100644
--- a/docs/decisions/0001-template.adoc
+++ b/docs/decisions/0001-template.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <6759885+hyperpolymath@users.noreply.github.com>
 = ADR-0001 — Use Architecture Decision Records
 :revdate: 2026-MM-DD
diff --git a/docs/tech-debt-2026-05-26.md b/docs/tech-debt-2026-05-26.md
index 140a9a2..b8dc32f 100644
--- a/docs/tech-debt-2026-05-26.md
+++ b/docs/tech-debt-2026-05-26.md
@@ -1,8 +1,7 @@
 <!--
-SPDX-License-Identifier: CC-BY-SA-4.0
-SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath)
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 -->
-
 # Tech-Debt Audit — claude-integrations — 2026-05-26
 
 **Source:** estate-wide automated scan 2026-05-26.
@@ -22,9 +21,10 @@ No proof-bearing files (`*.v`, `*.lean`, `*.agda`, `*.idr`, `*.idr2`, `*.fst`, `
 | Field | Value |
 |---|---|
 | LICENSE file | `LICENSE` |
-| SPDX header | `PMPL-1.0-or-later
` |
+| SPDX header | `MPL-2.0-or-later
+` |
 | Manifest licence | `NONE` |
-| Body classifier | `PMPL-1.0-or-later` |
+| Body classifier | `MPL-2.0-or-later` |
 | Severity | `ok` |
 
 **Recommended next move:** none for licence.
diff --git a/docs/troubleshooting.adoc b/docs/troubleshooting.adoc
index db8c901..6293b1f 100644
--- a/docs/troubleshooting.adoc
+++ b/docs/troubleshooting.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <6759885+hyperpolymath@users.noreply.github.com>
 = Troubleshooting — claude-integrations
 :revdate: 2026-MM-DD
diff --git a/docs/usage.adoc b/docs/usage.adoc
index d9c7ffe..dd772f9 100644
--- a/docs/usage.adoc
+++ b/docs/usage.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) <6759885+hyperpolymath@users.noreply.github.com>
 = Usage — claude-integrations
 :revdate: 2026-MM-DD
diff --git a/firefox-lsp/.formatter.exs b/firefox-lsp/.formatter.exs
index d2cda26..a1285df 100644
--- a/firefox-lsp/.formatter.exs
+++ b/firefox-lsp/.formatter.exs
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # Used by "mix format"
 [
   inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
diff --git a/firefox-lsp/.github/release-template.md b/firefox-lsp/.github/release-template.md
index 31e04e8..e9417d8 100644
--- a/firefox-lsp/.github/release-template.md
+++ b/firefox-lsp/.github/release-template.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # v1.0.0 - Production Release 🎉
 
 First production-ready release of this LSP server!
diff --git a/firefox-lsp/.github/workflows/codeql.yml b/firefox-lsp/.github/workflows/codeql.yml
index 471e9db..66447b1 100644
--- a/firefox-lsp/.github/workflows/codeql.yml
+++ b/firefox-lsp/.github/workflows/codeql.yml
@@ -1,22 +1,20 @@
-# SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: MPL-2.0-or-later
 name: CodeQL
-
 on:
   push:
-    branches: [ main ]
+    branches: [main]
   pull_request:
-    branches: [ main ]
+    branches: [main]
   schedule:
     - cron: '0 0 * * 1'
-
 permissions:
   security-events: write
   contents: read
-
 jobs:
   analyze:
     name: Analyze
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       - name: Initialize CodeQL
diff --git a/firefox-lsp/.github/workflows/coverage.yml b/firefox-lsp/.github/workflows/coverage.yml
index 6a72835..1e69cc2 100644
--- a/firefox-lsp/.github/workflows/coverage.yml
+++ b/firefox-lsp/.github/workflows/coverage.yml
@@ -1,16 +1,14 @@
 # SPDX-License-Identifier: MPL-2.0
 name: Test Coverage
-
 on:
   push:
-    branches: [ main ]
-
+    branches: [main]
 permissions: read-all
-
 jobs:
   coverage:
     name: Test Coverage
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       - name: Set up Elixir
diff --git a/firefox-lsp/.github/workflows/elixir-ci.yml b/firefox-lsp/.github/workflows/elixir-ci.yml
index 969233c..65c8b20 100644
--- a/firefox-lsp/.github/workflows/elixir-ci.yml
+++ b/firefox-lsp/.github/workflows/elixir-ci.yml
@@ -1,18 +1,16 @@
 # SPDX-License-Identifier: MPL-2.0
 name: Elixir CI
-
 on:
   push:
-    branches: [ main ]
+    branches: [main]
   pull_request:
-    branches: [ main ]
-
+    branches: [main]
 permissions: read-all
-
 jobs:
   test:
     name: Test (Elixir ${{matrix.elixir}} / OTP ${{matrix.otp}})
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     strategy:
       matrix:
         elixir: ['1.17']
diff --git a/firefox-lsp/.github/workflows/governance.yml b/firefox-lsp/.github/workflows/governance.yml
index b0b1ed6..60e8e90 100644
--- a/firefox-lsp/.github/workflows/governance.yml
+++ b/firefox-lsp/.github/workflows/governance.yml
@@ -11,16 +11,14 @@
 # (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing).
 
 name: Governance
-
 on:
   push:
     branches: [main, master]
   pull_request:
   workflow_dispatch:
-
 permissions:
   contents: read
-
 jobs:
   governance:
-    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@main
+    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613
+    timeout-minutes: 10
diff --git a/firefox-lsp/CHANGELOG.md b/firefox-lsp/CHANGELOG.md
index 596e6db..85f3038 100644
--- a/firefox-lsp/CHANGELOG.md
+++ b/firefox-lsp/CHANGELOG.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Changelog
 
 All notable changes to this project will be documented in this file.
diff --git a/firefox-lsp/Justfile b/firefox-lsp/Justfile
index 1c00913..5e29ecc 100644
--- a/firefox-lsp/Justfile
+++ b/firefox-lsp/Justfile
@@ -95,3 +95,6 @@ vscode-package:
 
 # Run CI checks locally
 ci: quality test
+
+secret-scan-trufflehog:
+    @command -v trufflehog >/dev/null && trufflehog filesystem . --only-verified || true
diff --git a/firefox-lsp/PROJECT-SUMMARY.md b/firefox-lsp/PROJECT-SUMMARY.md
index bb5a5c3..b48ea77 100644
--- a/firefox-lsp/PROJECT-SUMMARY.md
+++ b/firefox-lsp/PROJECT-SUMMARY.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Claude Firefox LSP - Project Summary
 
 **Created:** 2026-02-05
@@ -73,7 +77,7 @@ claude-firefox-lsp/
 ├── CHANGELOG.md                 # Version history
 ├── ECOSYSTEM.scm                # Ecosystem positioning
 ├── Justfile                     # Task automation
-├── LICENSE                      # PMPL-1.0-or-later
+├── LICENSE                      # MPL-2.0-or-later
 ├── META.scm                     # ADRs and design rationale
 ├── mix.exs                      # Elixir project config
 ├── README.adoc                  # User documentation
@@ -210,7 +214,7 @@ just start   # Start server
 
 ## License
 
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 Copyright (c) 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
-Licensed under the Palimpsest License, version 1.0 or later.
+Licensed under the MPL-2.0, version 1.0 or later.
diff --git a/firefox-lsp/QUICKSTART.md b/firefox-lsp/QUICKSTART.md
index 1681a69..744c0d1 100644
--- a/firefox-lsp/QUICKSTART.md
+++ b/firefox-lsp/QUICKSTART.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Quick Start Guide
 
 ## Prerequisites
diff --git a/firefox-lsp/README.adoc b/firefox-lsp/README.adoc
index e1ee0f7..7ea7865 100644
--- a/firefox-lsp/README.adoc
+++ b/firefox-lsp/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Claude Firefox LSP
 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 :toc: left
@@ -192,11 +194,11 @@ Related projects:
 
 == License
 
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 
 Copyright (c) 2026 Jonathan D.A. Jewell
 
-Licensed under the Palimpsest License, version 1.0 or later.
+Licensed under the MPL-2.0, version 1.0 or later.
 
 == Contributing
 
diff --git a/firefox-lsp/USAGE.md b/firefox-lsp/USAGE.md
index 56906ba..5ec9a92 100644
--- a/firefox-lsp/USAGE.md
+++ b/firefox-lsp/USAGE.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Usage Guide
 
 > Comprehensive guide for using claude-firefox-lsp across VSCode, Neovim, and Emacs
@@ -471,4 +475,4 @@ user_pref("devtools.chrome.enabled", true);
 
 ## License
 
-PMPL-1.0-or-later
+MPL-2.0-or-later
diff --git a/firefox-lsp/lib/adapters/behaviour.ex b/firefox-lsp/lib/adapters/behaviour.ex
index c394994..aa33dfc 100644
--- a/firefox-lsp/lib/adapters/behaviour.ex
+++ b/firefox-lsp/lib/adapters/behaviour.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.Adapters.Behaviour do
diff --git a/firefox-lsp/lib/adapters/firefox.ex b/firefox-lsp/lib/adapters/firefox.ex
index e6a7a42..e16ad69 100644
--- a/firefox-lsp/lib/adapters/firefox.ex
+++ b/firefox-lsp/lib/adapters/firefox.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.Adapters.Firefox do
diff --git a/firefox-lsp/lib/adapters/supervisor.ex b/firefox-lsp/lib/adapters/supervisor.ex
index 922a46f..15b4caa 100644
--- a/firefox-lsp/lib/adapters/supervisor.ex
+++ b/firefox-lsp/lib/adapters/supervisor.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.Adapters.Supervisor do
diff --git a/firefox-lsp/lib/claude_firefox_lsp.ex b/firefox-lsp/lib/claude_firefox_lsp.ex
index d8d049b..8f8d62b 100644
--- a/firefox-lsp/lib/claude_firefox_lsp.ex
+++ b/firefox-lsp/lib/claude_firefox_lsp.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSP do
diff --git a/firefox-lsp/lib/claude_firefox_lsp/application.ex b/firefox-lsp/lib/claude_firefox_lsp/application.ex
index 18b58ef..7e96563 100644
--- a/firefox-lsp/lib/claude_firefox_lsp/application.ex
+++ b/firefox-lsp/lib/claude_firefox_lsp/application.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSP.Application do
diff --git a/firefox-lsp/lib/lsp/handlers/completion.ex b/firefox-lsp/lib/lsp/handlers/completion.ex
index 5ddec9c..70fe9a0 100644
--- a/firefox-lsp/lib/lsp/handlers/completion.ex
+++ b/firefox-lsp/lib/lsp/handlers/completion.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSP.Handlers.Completion do
diff --git a/firefox-lsp/lib/lsp/handlers/diagnostics.ex b/firefox-lsp/lib/lsp/handlers/diagnostics.ex
index 31c260a..0806d88 100644
--- a/firefox-lsp/lib/lsp/handlers/diagnostics.ex
+++ b/firefox-lsp/lib/lsp/handlers/diagnostics.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSP.Handlers.Diagnostics do
diff --git a/firefox-lsp/lib/lsp/handlers/hover.ex b/firefox-lsp/lib/lsp/handlers/hover.ex
index b7894f5..cd9cf79 100644
--- a/firefox-lsp/lib/lsp/handlers/hover.ex
+++ b/firefox-lsp/lib/lsp/handlers/hover.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSP.Handlers.Hover do
diff --git a/firefox-lsp/lib/lsp/server.ex b/firefox-lsp/lib/lsp/server.ex
index c83d85a..cb86d53 100644
--- a/firefox-lsp/lib/lsp/server.ex
+++ b/firefox-lsp/lib/lsp/server.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSP.Server do
diff --git a/firefox-lsp/manifest.scm b/firefox-lsp/manifest.scm
new file mode 100644
index 0000000..dd942c7
--- /dev/null
+++ b/firefox-lsp/manifest.scm
@@ -0,0 +1,24 @@
+;;; SPDX-License-Identifier: MPL-2.0
+;;; manifest.scm — Generic Guix manifest for RSR-compliant projects
+;;;
+;;; Usage:
+;;;   guix shell -m manifest.scm
+;;;
+
+(specifications->manifest
+  '(;; Core development tools
+    "git"
+    "just"
+    "nickel"
+    "curl"
+    "bash"
+    "coreutils"
+
+    ;; Documentation
+    "asciidoctor"
+    "pandoc"
+
+    ;; Common build dependencies
+    "openssl"
+    "zlib"
+    "pkg-config"))
diff --git a/firefox-lsp/mix.exs b/firefox-lsp/mix.exs
index 095d50a..660f3d6 100644
--- a/firefox-lsp/mix.exs
+++ b/firefox-lsp/mix.exs
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSP.MixProject do
diff --git a/firefox-lsp/test/adapters/firefox_test.exs b/firefox-lsp/test/adapters/firefox_test.exs
index 98fddbd..225f174 100644
--- a/firefox-lsp/test/adapters/firefox_test.exs
+++ b/firefox-lsp/test/adapters/firefox_test.exs
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 defmodule PolyLSP.Adapters.FirefoxTest do
   use ExUnit.Case
   alias PolyLSP.Adapters.Firefox
diff --git a/firefox-lsp/test/claude_firefox/lsp_test.exs b/firefox-lsp/test/claude_firefox/lsp_test.exs
index 5e8e72b..6b80649 100644
--- a/firefox-lsp/test/claude_firefox/lsp_test.exs
+++ b/firefox-lsp/test/claude_firefox/lsp_test.exs
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 defmodule ClaudeFirefox.LSPTest do
diff --git a/firefox-lsp/test/support/lsp_helpers.ex b/firefox-lsp/test/support/lsp_helpers.ex
index c30592f..244244b 100644
--- a/firefox-lsp/test/support/lsp_helpers.ex
+++ b/firefox-lsp/test/support/lsp_helpers.ex
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 defmodule LSPHelpers do
   @moduledoc """
   Common test helpers for LSP protocol testing.
diff --git a/firefox-lsp/test/test_helper.exs b/firefox-lsp/test/test_helper.exs
index 5fe04d8..10fad80 100644
--- a/firefox-lsp/test/test_helper.exs
+++ b/firefox-lsp/test/test_helper.exs
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: MPL-2.0
+# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
 ExUnit.start()
diff --git a/firefox-lsp/vscode-extension/README.md b/firefox-lsp/vscode-extension/README.md
index 7dda277..cc5df82 100644
--- a/firefox-lsp/vscode-extension/README.md
+++ b/firefox-lsp/vscode-extension/README.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Claude Firefox LSP - VS Code Extension
 
 VS Code extension for Firefox browser automation via Language Server Protocol.
@@ -54,6 +58,6 @@ npm run package
 
 ## License
 
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 
 Copyright (c) 2026 Jonathan D.A. Jewell
diff --git a/firefox-mcp/.github/workflows/casket-pages.yml b/firefox-mcp/.github/workflows/casket-pages.yml
index f6d4979..32c256f 100644
--- a/firefox-mcp/.github/workflows/casket-pages.yml
+++ b/firefox-mcp/.github/workflows/casket-pages.yml
@@ -1,39 +1,33 @@
 # SPDX-License-Identifier: MPL-2.0
 name: GitHub Pages
-
 on:
   push:
     branches: [main]
   workflow_dispatch:
-
 permissions:
   contents: read
   pages: write
   id-token: write
-
 concurrency:
   group: "pages"
   cancel-in-progress: false
-
 jobs:
   build:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - name: Checkout
         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
-
       - name: Checkout casket-ssg
         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
         with:
           repository: hyperpolymath/casket-ssg
           path: .casket-ssg
-
       - name: Setup GHCup
         uses: haskell-actions/setup@ec49483bfc012387b227434aba94f59a6ecd0900 # v2
         with:
           ghc-version: '9.8.2'
           cabal-version: '3.10'
-
       - name: Cache Cabal
         uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
         with:
@@ -42,11 +36,9 @@ jobs:
             ~/.cabal/store
             .casket-ssg/dist-newstyle
           key: ${{ runner.os }}-casket-${{ hashFiles('.casket-ssg/casket-ssg.cabal') }}
-
       - name: Build casket-ssg
         working-directory: .casket-ssg
         run: cabal build
-
       - name: Build site
         run: |
           mkdir -p site _site
@@ -77,20 +69,18 @@ jobs:
             fi
           fi
           cd .casket-ssg && cabal run casket-ssg -- build ../site ../_site
-
       - name: Setup Pages
         uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
-
       - name: Upload artifact
         uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
         with:
           path: '_site'
-
   deploy:
     environment:
       name: github-pages
       url: ${{ steps.deployment.outputs.page_url }}
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     needs: build
     steps:
       - name: Deploy to GitHub Pages
diff --git a/firefox-mcp/.github/workflows/codeql.yml b/firefox-mcp/.github/workflows/codeql.yml
index b317db1..c9b0575 100644
--- a/firefox-mcp/.github/workflows/codeql.yml
+++ b/firefox-mcp/.github/workflows/codeql.yml
@@ -1,6 +1,5 @@
-# SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: MPL-2.0-or-later
 name: CodeQL Security Analysis
-
 on:
   push:
     branches: [main, master]
@@ -8,12 +7,11 @@ on:
     branches: [main, master]
   schedule:
     - cron: '0 6 * * 1'
-
 permissions: read-all
-
 jobs:
   analyze:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       contents: read
       security-events: write
@@ -23,17 +21,14 @@ jobs:
         include:
           - language: javascript-typescript
             build-mode: none
-
     steps:
       - name: Checkout
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
-
       - name: Initialize CodeQL
         uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.28.1
         with:
           languages: ${{ matrix.language }}
           build-mode: ${{ matrix.build-mode }}
-
       - name: Perform CodeQL Analysis
         uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.28.1
         with:
diff --git a/firefox-mcp/.github/workflows/governance.yml b/firefox-mcp/.github/workflows/governance.yml
index b0b1ed6..60e8e90 100644
--- a/firefox-mcp/.github/workflows/governance.yml
+++ b/firefox-mcp/.github/workflows/governance.yml
@@ -11,16 +11,14 @@
 # (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing).
 
 name: Governance
-
 on:
   push:
     branches: [main, master]
   pull_request:
   workflow_dispatch:
-
 permissions:
   contents: read
-
 jobs:
   governance:
-    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@main
+    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613
+    timeout-minutes: 10
diff --git a/firefox-mcp/.github/workflows/hypatia-scan.yml b/firefox-mcp/.github/workflows/hypatia-scan.yml
index 5b59919..c3cb66b 100644
--- a/firefox-mcp/.github/workflows/hypatia-scan.yml
+++ b/firefox-mcp/.github/workflows/hypatia-scan.yml
@@ -1,41 +1,35 @@
 # SPDX-License-Identifier: MPL-2.0
 # Hypatia Neurosymbolic CI/CD Security Scan
 name: Hypatia Security Scan
-
 on:
   push:
-    branches: [ main, master, develop ]
+    branches: [main, master, develop]
   pull_request:
-    branches: [ main, master ]
+    branches: [main, master]
   schedule:
-    - cron: '0 0 * * 0'  # Weekly on Sunday
+    - cron: '0 0 * * 0' # Weekly on Sunday
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   scan:
     name: Hypatia Neurosymbolic Analysis
     runs-on: ubuntu-latest
-
+    timeout-minutes: 15
     steps:
       - name: Checkout repository
         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
         with:
-          fetch-depth: 0  # Full history for better pattern analysis
-
+          fetch-depth: 0 # Full history for better pattern analysis
       - name: Setup Elixir for Hypatia scanner
         uses: erlef/setup-beam@2f0cc07b4b9bea248ae098aba9e1a8a1de5ec24c # v1.18.2
         with:
           elixir-version: '1.19.4'
           otp-version: '28.3'
-
       - name: Clone Hypatia
         run: |
           if [ ! -d "$HOME/hypatia" ]; then
             git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
           fi
-
       - name: Build Hypatia scanner (if needed)
         working-directory: ${{ env.HOME }}/hypatia
         run: |
@@ -46,7 +40,6 @@ jobs:
             mix escript.build
             mv hypatia ../hypatia-v2
           fi
-
       - name: Run Hypatia scan
         id: scan
         run: |
@@ -73,35 +66,19 @@ jobs:
           echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
           echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
           echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
-
       - name: Upload findings artifact
         uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
         with:
           name: hypatia-findings
           path: hypatia-findings.json
           retention-days: 90
-
       - name: Submit findings to gitbot-fleet (Phase 2)
         if: steps.scan.outputs.findings_count > 0
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           GITHUB_REPOSITORY: ${{ github.repository }}
           GITHUB_SHA: ${{ github.sha }}
-        run: |
-          echo "📤 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet..."
-
-          # Clone gitbot-fleet to temp directory
-          FLEET_DIR="/tmp/gitbot-fleet-$$"
-          git clone https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"
-
-          # Run submission script
-          bash "$FLEET_DIR/scripts/submit-finding.sh" hypatia-findings.json
-
-          # Cleanup
-          rm -rf "$FLEET_DIR"
-
-          echo "✅ Finding submission complete"
-
+        run: "echo \"\U0001F4E4 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet...\"\n\n# Clone gitbot-fleet to temp directory\nFLEET_DIR=\"/tmp/gitbot-fleet-$$\"\ngit clone https://github.com/hyperpolymath/gitbot-fleet.git \"$FLEET_DIR\"\n\n# Run submission script\nbash \"$FLEET_DIR/scripts/submit-finding.sh\" hypatia-findings.json\n\n# Cleanup\nrm -rf \"$FLEET_DIR\"\n\necho \"✅ Finding submission complete\"\n"
       - name: Check for critical issues
         if: steps.scan.outputs.critical > 0
         run: |
@@ -109,7 +86,6 @@ jobs:
           echo "Review hypatia-findings.json for details"
           # Don't fail the build yet - just warn
           # exit 1
-
       - name: Generate scan report
         run: |
           cat << EOF > hypatia-report.md
@@ -143,37 +119,8 @@ jobs:
           EOF
 
           cat hypatia-report.md >> $GITHUB_STEP_SUMMARY
-
       - name: Comment on PR with findings
         if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
         uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
         with:
-          script: |
-            const fs = require('fs');
-            const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));
-
-            const critical = findings.filter(f => f.severity === 'critical').length;
-            const high = findings.filter(f => f.severity === 'high').length;
-
-            let comment = `## 🔍 Hypatia Security Scan\n\n`;
-            comment += `**Findings:** ${findings.length} issues detected\n\n`;
-            comment += `| Severity | Count |\n|----------|-------|\n`;
-            comment += `| 🔴 Critical | ${critical} |\n`;
-            comment += `| 🟠 High | ${high} |\n`;
-            comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;
-
-            if (critical > 0) {
-              comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
-            }
-
-            comment += `<details><summary>View findings</summary>\n\n`;
-            comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
-            comment += `</details>\n\n`;
-            comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;
-
-            github.rest.issues.createComment({
-              owner: context.repo.owner,
-              repo: context.repo.repo,
-              issue_number: context.issue.number,
-              body: comment
-            });
+          script: "const fs = require('fs');\nconst findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));\n\nconst critical = findings.filter(f => f.severity === 'critical').length;\nconst high = findings.filter(f => f.severity === 'high').length;\n\nlet comment = `## \U0001F50D Hypatia Security Scan\\n\\n`;\ncomment += `**Findings:** ${findings.length} issues detected\\n\\n`;\ncomment += `| Severity | Count |\\n|----------|-------|\\n`;\ncomment += `| \U0001F534 Critical | ${critical} |\\n`;\ncomment += `| \U0001F7E0 High | ${high} |\\n`;\ncomment += `| \U0001F7E1 Medium | ${findings.length - critical - high} |\\n\\n`;\n\nif (critical > 0) {\n  comment += `⚠️ **Action Required:** Critical security issues found!\\n\\n`;\n}\n\ncomment += `<details><summary>View findings</summary>\\n\\n`;\ncomment += `\\`\\`\\`json\\n${JSON.stringify(findings.slice(0, 10), null, 2)}\\n\\`\\`\\`\\n`;\ncomment += `</details>\\n\\n`;\ncomment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;\n\ngithub.rest.issues.createComment({\n  owner: context.repo.owner,\n  repo: context.repo.repo,\n  issue_number: context.issue.number,\n  body: comment\n});\n"
diff --git a/firefox-mcp/.github/workflows/scorecard.yml b/firefox-mcp/.github/workflows/scorecard.yml
index d50c271..4dd3b73 100644
--- a/firefox-mcp/.github/workflows/scorecard.yml
+++ b/firefox-mcp/.github/workflows/scorecard.yml
@@ -6,12 +6,11 @@ on:
   schedule:
     - cron: '0 4 * * *'
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   analysis:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       security-events: write
       id-token: write
@@ -19,13 +18,11 @@ jobs:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
           persist-credentials: false
-
       - name: Run Scorecard
         uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.3.1
         with:
           results_file: results.sarif
           results_format: sarif
-
       - name: Upload results
         uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.31.8
         with:
diff --git a/firefox-mcp/ABI-FFI-README.md b/firefox-mcp/ABI-FFI-README.md
index 08d35da..cf73490 100644
--- a/firefox-mcp/ABI-FFI-README.md
+++ b/firefox-mcp/ABI-FFI-README.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 {{~ Aditionally delete this line and fill out the template below ~}}
 
 # {{PROJECT}} ABI/FFI Documentation
diff --git a/firefox-mcp/CODE_OF_CONDUCT.md b/firefox-mcp/CODE_OF_CONDUCT.md
index 2777a72..9142f2a 100644
--- a/firefox-mcp/CODE_OF_CONDUCT.md
+++ b/firefox-mcp/CODE_OF_CONDUCT.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Code of Conduct
 
 <!-- 
diff --git a/firefox-mcp/CONTRIBUTING.md b/firefox-mcp/CONTRIBUTING.md
index b39b3f7..455e511 100644
--- a/firefox-mcp/CONTRIBUTING.md
+++ b/firefox-mcp/CONTRIBUTING.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Clone the repository
 git clone https://{{FORGE}}/{{OWNER}}/{{REPO}}.git
 cd {{REPO}}
diff --git a/firefox-mcp/MAINTAINERS.adoc b/firefox-mcp/MAINTAINERS.adoc
index 48d9781..becaa3e 100644
--- a/firefox-mcp/MAINTAINERS.adoc
+++ b/firefox-mcp/MAINTAINERS.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Maintainers
 :toc: preamble
 
diff --git a/firefox-mcp/README.adoc b/firefox-mcp/README.adoc
index d0113bb..601c735 100644
--- a/firefox-mcp/README.adoc
+++ b/firefox-mcp/README.adoc
@@ -1,12 +1,13 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 image:https://img.shields.io/badge/License-MPL_2.0-blue.svg[MPL-2.0-or-later,link="https://opensource.org/licenses/MPL-2.0"]
 
 == License & Philosophy
 
 This project must declare **MPL-2.0-or-later** for platform/tooling compatibility.
 
-Philosophy: **Palimpsest**. The Palimpsest-MPL (PMPL) text is provided in `license/PMPL-1.0.txt`, and the canonical source is the palimpsest-license repository.
+Philosophy: **Palimpsest**. The MPL-2.0 (PMPL) text is provided in `license/MPL-2.0.txt`, and the canonical source is the palimpsest-license repository.
 
-// SPDX-License-Identifier: CC-BY-SA-4.0
 = Claude Firefox MCP
 
 
@@ -171,12 +172,12 @@ The extension auto-reconnects to the MCP server. Click the extension icon to man
 |Proprietary
 
 |License
-|PMPL-1.0-or-later
+|MPL-2.0-or-later
 |Proprietary
 |===
 
 == License
 
-PMPL-1.0-or-later
+MPL-2.0-or-later
 
 This is an independent project. Not affiliated with Anthropic or Mozilla.
diff --git a/firefox-mcp/ROADMAP.adoc b/firefox-mcp/ROADMAP.adoc
index d8e1687..128ed39 100644
--- a/firefox-mcp/ROADMAP.adoc
+++ b/firefox-mcp/ROADMAP.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = YOUR Template Repo Roadmap
 
 == Current Status
diff --git a/firefox-mcp/RSR_OUTLINE.adoc b/firefox-mcp/RSR_OUTLINE.adoc
index 8a22906..6baed3c 100644
--- a/firefox-mcp/RSR_OUTLINE.adoc
+++ b/firefox-mcp/RSR_OUTLINE.adoc
@@ -1,6 +1,8 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = RSR Template Repository
 
-image:[Palimpsest-MPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
+image:[MPL-2.0-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
 :toc:
 :sectnums:
 
@@ -209,7 +211,7 @@ This template is part of:
 
 == License
 
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 
 == Links
 
diff --git a/firefox-mcp/SECURITY.md b/firefox-mcp/SECURITY.md
index 7dd7b29..09fc7b8 100644
--- a/firefox-mcp/SECURITY.md
+++ b/firefox-mcp/SECURITY.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Security Policy
 
 <!-- 
diff --git a/firefox-mcp/ai-cli-crash-capture/README.adoc b/firefox-mcp/ai-cli-crash-capture/README.adoc
index 2fcda87..689b158 100644
--- a/firefox-mcp/ai-cli-crash-capture/README.adoc
+++ b/firefox-mcp/ai-cli-crash-capture/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = AI CLI Crash Capture
 :revdate: 2026-01-17
 
diff --git a/firefox-mcp/contractiles/README.adoc b/firefox-mcp/contractiles/README.adoc
index d19a387..70ad712 100644
--- a/firefox-mcp/contractiles/README.adoc
+++ b/firefox-mcp/contractiles/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Contractiles Template Set
 :toc:
 :sectnums:
diff --git a/firefox-mcp/docs/CITATIONS.adoc b/firefox-mcp/docs/CITATIONS.adoc
index 564f0ae..52ba528 100644
--- a/firefox-mcp/docs/CITATIONS.adoc
+++ b/firefox-mcp/docs/CITATIONS.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = RSR-template-repo - Citation Guide
 :toc:
 
@@ -10,7 +12,7 @@
   title = {RSR-template-repo},
   year = {2025},
   url = {https://github.com/hyperpolymath/RSR-template-repo},
-  license = {AGPL-3.0-or-later}
+  license = {MPL-2.0}
 }
 ----
 
diff --git a/firefox-mcp/extension-mv3/background.js b/firefox-mcp/extension-mv3/background.js
index d37d3fd..a659545 100644
--- a/firefox-mcp/extension-mv3/background.js
+++ b/firefox-mcp/extension-mv3/background.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude Firefox MCP - Background Service Worker (MV3)
 // Handles service worker lifecycle with reconnection
 
@@ -132,7 +133,7 @@ async function executeToolCall(params) {
     click: click,
     type: typeText,
     scroll: scroll,
-    execute_js: executeJs,
+    // Security: execute_js tool removed to eliminate eval vulnerability
     find: findElements,
     form_input: formInput,
     tabs_list: tabsList,
@@ -383,21 +384,8 @@ async function scroll(args) {
   return { content: [{ type: 'text', text: `Scrolled ${direction}` }] };
 }
 
-// Execute JS
-async function executeJs(args) {
-  const tab = await getTab(args.tabId);
-  const results = await browser.scripting.executeScript({
-    target: { tabId: tab.id },
-    func: (code) => eval(code),
-    args: [args.code]
-  });
-
-  let text;
-  try { text = JSON.stringify(results[0]?.result, null, 2); }
-  catch { text = String(results[0]?.result); }
-
-  return { content: [{ type: 'text', text: text || 'undefined' }] };
-}
+// Security: executeJs function removed to eliminate eval vulnerability
+// This tool allowed arbitrary code execution which is a security risk
 
 // Find elements
 async function findElements(args) {
diff --git a/firefox-mcp/extension/background.js b/firefox-mcp/extension/background.js
index 5283176..d3be467 100644
--- a/firefox-mcp/extension/background.js
+++ b/firefox-mcp/extension/background.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude Firefox MCP - Background Script
 // Connects to native host via WebSocket
 
@@ -108,8 +109,7 @@ async function executeToolCall(params) {
       return await typeText(args);
     case 'scroll':
       return await scroll(args);
-    case 'execute_js':
-      return await executeJs(args);
+    // Security: execute_js case removed to eliminate code execution vulnerability
     case 'find':
       return await findElements(args);
     case 'form_input':
@@ -428,24 +428,8 @@ async function scroll(args) {
   };
 }
 
-// Execute JavaScript
-async function executeJs(args) {
-  const tab = await getTab(args.tabId);
-  const { code } = args;
-
-  const results = await browser.tabs.executeScript(tab.id, { code });
-
-  let resultText;
-  try {
-    resultText = JSON.stringify(results[0], null, 2);
-  } catch {
-    resultText = String(results[0]);
-  }
-
-  return {
-    content: [{ type: 'text', text: resultText || 'undefined' }]
-  };
-}
+// Security: executeJs function removed to eliminate code execution vulnerability
+// This tool allowed arbitrary code execution which is a security risk
 
 // Find elements
 async function findElements(args) {
diff --git a/firefox-mcp/extension/content/bridge.js b/firefox-mcp/extension/content/bridge.js
index 32580bc..22097a8 100644
--- a/firefox-mcp/extension/content/bridge.js
+++ b/firefox-mcp/extension/content/bridge.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude Firefox MCP - Content Script Bridge
 // Injected into pages for DOM access
 
@@ -7,16 +8,8 @@
 
 // Listen for messages from background script
 browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
-  if (message.type === 'EXECUTE_IN_PAGE') {
-    try {
-      // Execute the code in page context
-      const result = eval(message.code);
-      sendResponse({ success: true, result });
-    } catch (error) {
-      sendResponse({ success: false, error: error.message });
-    }
-    return true; // Async response
-  }
+  // Security: EXECUTE_IN_PAGE handler removed to eliminate eval vulnerability
+  // Code execution in page context is no longer supported
 
   if (message.type === 'GET_ELEMENT_AT') {
     const { x, y } = message;
diff --git a/gecko-browser-extension/.claude/CLAUDE.md b/gecko-browser-extension/.claude/CLAUDE.md
index a2076bd..30fca2e 100644
--- a/gecko-browser-extension/.claude/CLAUDE.md
+++ b/gecko-browser-extension/.claude/CLAUDE.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # CLAUDE.md - AI Assistant Instructions
 
 ## Machine-Readable Artefacts
diff --git a/gecko-browser-extension/.github/workflows/codeql.yml b/gecko-browser-extension/.github/workflows/codeql.yml
index e79e98a..735af54 100644
--- a/gecko-browser-extension/.github/workflows/codeql.yml
+++ b/gecko-browser-extension/.github/workflows/codeql.yml
@@ -1,19 +1,17 @@
-# SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: MPL-2.0-or-later
 name: CodeQL Security Analysis
-
 on:
   push:
     branches: [main, master]
   pull_request:
     branches: [main, master]
   schedule:
-    - cron: '0 6 1 * *'
-
+    - cron: '0 6 * * 1'
 permissions: read-all
-
 jobs:
   analyze:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       contents: read
       security-events: write
@@ -23,17 +21,14 @@ jobs:
         include:
           - language: javascript-typescript
             build-mode: none
-
     steps:
       - name: Checkout
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
-
       - name: Initialize CodeQL
         uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.28.1
         with:
           languages: ${{ matrix.language }}
           build-mode: ${{ matrix.build-mode }}
-
       - name: Perform CodeQL Analysis
         uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.28.1
         with:
diff --git a/gecko-browser-extension/.github/workflows/governance.yml b/gecko-browser-extension/.github/workflows/governance.yml
index b0b1ed6..60e8e90 100644
--- a/gecko-browser-extension/.github/workflows/governance.yml
+++ b/gecko-browser-extension/.github/workflows/governance.yml
@@ -11,16 +11,14 @@
 # (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing).
 
 name: Governance
-
 on:
   push:
     branches: [main, master]
   pull_request:
   workflow_dispatch:
-
 permissions:
   contents: read
-
 jobs:
   governance:
-    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@main
+    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613
+    timeout-minutes: 10
diff --git a/gecko-browser-extension/.github/workflows/mirror.yml b/gecko-browser-extension/.github/workflows/mirror.yml
index 2fb4575..3c08e0f 100644
--- a/gecko-browser-extension/.github/workflows/mirror.yml
+++ b/gecko-browser-extension/.github/workflows/mirror.yml
@@ -1,142 +1,125 @@
 # SPDX-License-Identifier: MPL-2.0
 # SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell
 name: Mirror to Git Forges
-
 on:
   push:
     branches: [main]
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   mirror-gitlab:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.GITLAB_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.GITLAB_SSH_KEY }}
-
       - name: Mirror to GitLab
         run: |
           ssh-keyscan -t ed25519 gitlab.com >> ~/.ssh/known_hosts
           git remote add gitlab git@gitlab.com:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force gitlab main
-
   mirror-bitbucket:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.BITBUCKET_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.BITBUCKET_SSH_KEY }}
-
       - name: Mirror to Bitbucket
         run: |
           ssh-keyscan -t ed25519 bitbucket.org >> ~/.ssh/known_hosts
           git remote add bitbucket git@bitbucket.org:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force bitbucket main
-
   mirror-codeberg:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.CODEBERG_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.CODEBERG_SSH_KEY }}
-
       - name: Mirror to Codeberg
         run: |
           ssh-keyscan -t ed25519 codeberg.org >> ~/.ssh/known_hosts
           git remote add codeberg git@codeberg.org:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force codeberg main
-
   mirror-sourcehut:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.SOURCEHUT_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.SOURCEHUT_SSH_KEY }}
-
       - name: Mirror to SourceHut
         run: |
           ssh-keyscan -t ed25519 git.sr.ht >> ~/.ssh/known_hosts
           git remote add sourcehut git@git.sr.ht:~hyperpolymath/${{ github.event.repository.name }} || true
           git push --force sourcehut main
-
   mirror-disroot:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.DISROOT_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.DISROOT_SSH_KEY }}
-
       - name: Mirror to Disroot
         run: |
           ssh-keyscan -t ed25519 git.disroot.org >> ~/.ssh/known_hosts
           git remote add disroot git@git.disroot.org:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force disroot main
-
   mirror-gitea:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.GITEA_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.GITEA_SSH_KEY }}
-
       - name: Mirror to Gitea
         run: |
           ssh-keyscan -t ed25519 ${{ vars.GITEA_HOST }} >> ~/.ssh/known_hosts
           git remote add gitea git@${{ vars.GITEA_HOST }}:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force gitea main
-
   mirror-radicle:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.RADICLE_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
           fetch-depth: 0
-
       - name: Setup Rust
         uses: dtolnay/rust-toolchain@f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 # stable
         with:
           toolchain: stable
-
       - name: Install Radicle
         run: |
           # Install via cargo (safer than curl|sh)
           cargo install radicle-cli --locked
           echo "$HOME/.cargo/bin" >> $GITHUB_PATH
-
       - name: Mirror to Radicle
         run: |
           echo "${{ secrets.RADICLE_KEY }}" > ~/.radicle/keys/radicle
diff --git a/gecko-browser-extension/.github/workflows/scorecard.yml b/gecko-browser-extension/.github/workflows/scorecard.yml
index e6e2aa0..56c1514 100644
--- a/gecko-browser-extension/.github/workflows/scorecard.yml
+++ b/gecko-browser-extension/.github/workflows/scorecard.yml
@@ -6,12 +6,11 @@ on:
   schedule:
     - cron: '0 4 * * *'
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   analysis:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       security-events: write
       id-token: write
@@ -19,13 +18,11 @@ jobs:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           persist-credentials: false
-
       - name: Run Scorecard
         uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.3.1
         with:
           results_file: results.sarif
           results_format: sarif
-
       - name: Upload results
         uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.31.8
         with:
diff --git a/gecko-browser-extension/.github/workflows/secret-scanner.yml b/gecko-browser-extension/.github/workflows/secret-scanner.yml
index ffd2912..13222e1 100644
--- a/gecko-browser-extension/.github/workflows/secret-scanner.yml
+++ b/gecko-browser-extension/.github/workflows/secret-scanner.yml
@@ -1,46 +1,30 @@
 # SPDX-License-Identifier: MPL-2.0
 # Prevention workflow - scans for hardcoded secrets before they reach main
 name: Secret Scanner
-
 on:
   pull_request:
   push:
     branches: [main]
-
 permissions: read-all
-
 jobs:
   trufflehog:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
         with:
-          fetch-depth: 0  # Full history for scanning
-
+          fetch-depth: 0 # Full history for scanning
       - name: TruffleHog Secret Scan
         uses: trufflesecurity/trufflehog@116e7171542d2f1dad8810f00dcfacbe0b809183 # v3
         with:
           extra_args: --only-verified --fail
-
-  gitleaks:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
-        with:
-          fetch-depth: 0
-
-      - name: Gitleaks Secret Scan
-        uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
   # Rust-specific: Check for hardcoded crypto values
   rust-secrets:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: hashFiles('**/Cargo.toml') != ''
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
-
       - name: Check for hardcoded secrets in Rust
         run: |
           # Patterns that suggest hardcoded secrets
diff --git a/gecko-browser-extension/.machine_readable/6a2/AGENTIC.a2ml b/gecko-browser-extension/.machine_readable/6a2/AGENTIC.a2ml
new file mode 100644
index 0000000..c25b68b
--- /dev/null
+++ b/gecko-browser-extension/.machine_readable/6a2/AGENTIC.a2ml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[metadata]
+claude-code = [
+  ["model", "claude-opus-4-5-20251101"],
+  [
+  "tools",
+  ["read", "edit", "bash", "grep", "glob"],
+],
+  ["permissions", "read-all"],
+]
+constraints = [
+  [
+  "languages",
+  [],
+],
+  [
+  "banned",
+  ["typescript", "go", "python", "makefile"],
+],
+]
+patterns = [
+  ["code-review", "thorough"],
+  ["refactoring", "conservative"],
+  ["testing", "comprehensive"],
+]
+version = "1.0.0"
+
+
diff --git a/gecko-browser-extension/.machine_readable/6a2/ECOSYSTEM.a2ml b/gecko-browser-extension/.machine_readable/6a2/ECOSYSTEM.a2ml
new file mode 100644
index 0000000..1c4bba7
--- /dev/null
+++ b/gecko-browser-extension/.machine_readable/6a2/ECOSYSTEM.a2ml
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[ecosystem]
+name = "claude-gecko-browser-extension"
+position-in-ecosystem = ["category", ""]
+purpose = ""
+related-projects = []
+type = ""
+version = "1.0"
+what-this-is = []
+what-this-is-not = []
+
+
diff --git a/gecko-browser-extension/.machine_readable/6a2/META.a2ml b/gecko-browser-extension/.machine_readable/6a2/META.a2ml
new file mode 100644
index 0000000..700b724
--- /dev/null
+++ b/gecko-browser-extension/.machine_readable/6a2/META.a2ml
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[meta]
+architecture-decisions = []
+design-rationale = []
+development-practices = [
+  "code-style",
+  [],
+]
+
+
diff --git a/gecko-browser-extension/.machine_readable/6a2/NEUROSYM.a2ml b/gecko-browser-extension/.machine_readable/6a2/NEUROSYM.a2ml
new file mode 100644
index 0000000..d1f7205
--- /dev/null
+++ b/gecko-browser-extension/.machine_readable/6a2/NEUROSYM.a2ml
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[metadata]
+integration = []
+neural-layer = [
+  ["embeddings", "false"],
+  ["fine-tuning", "false"],
+]
+symbolic-layer = [
+  ["type", "scheme"],
+  ["reasoning", "deductive"],
+  ["verification", "formal"],
+]
+version = "1.0.0"
+
+
diff --git a/gecko-browser-extension/.machine_readable/6a2/PLAYBOOK.a2ml b/gecko-browser-extension/.machine_readable/6a2/PLAYBOOK.a2ml
new file mode 100644
index 0000000..08fa460
--- /dev/null
+++ b/gecko-browser-extension/.machine_readable/6a2/PLAYBOOK.a2ml
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[metadata]
+alerts = []
+contacts = []
+procedures = [
+  [
+  "deploy",
+  [
+  ["build", "just build"],
+  ["test", "just test"],
+  ["release", "just release"],
+],
+],
+  [
+  "rollback",
+  [],
+],
+  [
+  "debug",
+  [],
+],
+]
+version = "1.0.0"
+
+
diff --git a/gecko-browser-extension/.machine_readable/6a2/STATE.a2ml b/gecko-browser-extension/.machine_readable/6a2/STATE.a2ml
new file mode 100644
index 0000000..93e1a13
--- /dev/null
+++ b/gecko-browser-extension/.machine_readable/6a2/STATE.a2ml
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[state]
+blockers-and-issues = ["critical"]
+critical-next-actions = ["immediate"]
+current-position = ["phase", "initial"]
+metadata = ["version", "0.0.1"]
+project-context = ["name", "claude-gecko-browser-extension"]
+route-to-mvp = [
+  "milestones",
+  [],
+]
+session-history = []
+
+
diff --git a/gecko-browser-extension/ABI-FFI-README.md b/gecko-browser-extension/ABI-FFI-README.md
index 08d35da..cf73490 100644
--- a/gecko-browser-extension/ABI-FFI-README.md
+++ b/gecko-browser-extension/ABI-FFI-README.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 {{~ Aditionally delete this line and fill out the template below ~}}
 
 # {{PROJECT}} ABI/FFI Documentation
diff --git a/gecko-browser-extension/CODE_OF_CONDUCT.md b/gecko-browser-extension/CODE_OF_CONDUCT.md
index caeda1c..9020def 100644
--- a/gecko-browser-extension/CODE_OF_CONDUCT.md
+++ b/gecko-browser-extension/CODE_OF_CONDUCT.md
@@ -1,4 +1,7 @@
-<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Contributor Covenant Code of Conduct
 
 ## Our Pledge
diff --git a/gecko-browser-extension/CONTRIBUTING.adoc b/gecko-browser-extension/CONTRIBUTING.adoc
index eb045d6..2ead10c 100644
--- a/gecko-browser-extension/CONTRIBUTING.adoc
+++ b/gecko-browser-extension/CONTRIBUTING.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Contributing Guide
 
 == Getting Started
diff --git a/gecko-browser-extension/CONTRIBUTING.md b/gecko-browser-extension/CONTRIBUTING.md
index b39b3f7..455e511 100644
--- a/gecko-browser-extension/CONTRIBUTING.md
+++ b/gecko-browser-extension/CONTRIBUTING.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Clone the repository
 git clone https://{{FORGE}}/{{OWNER}}/{{REPO}}.git
 cd {{REPO}}
diff --git a/gecko-browser-extension/Justfile b/gecko-browser-extension/Justfile
index 615c8f3..9161b43 100644
--- a/gecko-browser-extension/Justfile
+++ b/gecko-browser-extension/Justfile
@@ -31,3 +31,6 @@ check: lint test
 release VERSION:
     @echo "Releasing {{VERSION}}..."
 
+
+secret-scan-trufflehog:
+    @command -v trufflehog >/dev/null && trufflehog filesystem . --only-verified || true
diff --git a/gecko-browser-extension/MAINTAINERS.adoc b/gecko-browser-extension/MAINTAINERS.adoc
index 48d9781..becaa3e 100644
--- a/gecko-browser-extension/MAINTAINERS.adoc
+++ b/gecko-browser-extension/MAINTAINERS.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Maintainers
 :toc: preamble
 
diff --git a/gecko-browser-extension/PALIMPSEST.adoc b/gecko-browser-extension/PALIMPSEST.adoc
index 124589a..f9cf207 100644
--- a/gecko-browser-extension/PALIMPSEST.adoc
+++ b/gecko-browser-extension/PALIMPSEST.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Palimpsest Licence
 :toc:
 :toc-placement!:
diff --git a/gecko-browser-extension/README.adoc b/gecko-browser-extension/README.adoc
index 287f254..3269e76 100644
--- a/gecko-browser-extension/README.adoc
+++ b/gecko-browser-extension/README.adoc
@@ -1,7 +1,8 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 image:https://img.shields.io/badge/license-PMPL--1.0-blue.svg[License,link="https://github.com/hyperpolymath/palimpsest-license"]
 
 
-// SPDX-License-Identifier: CC-BY-SA-4.0
 // SPDX-FileCopyrightText: 2025 hyperpolymath
 
 = Claude for Gecko
@@ -119,15 +120,15 @@ The extension will be submitted to https://addons.mozilla.org[Firefox Add-ons] o
 
 === Legal License
 
-This project is licensed under the **Palimpsest-MPL License v1.0 (PMPL-1.0)** - see link:LICENSE[LICENSE] for details.
+This project is licensed under the **MPL-2.0 License v1.0 (MPL-2.0)** - see link:LICENSE[LICENSE] for details.
 
 You are free to use, modify, and distribute this software.
 
-=== Philosophical Companion: Palimpsest License
+=== Philosophical Companion: MPL-2.0
 
-We encourage adopters to also consider the principles of the **Palimpsest License** - a philosophical manifesto for building technology that serves humanity's long-term flourishing.
+We encourage adopters to also consider the principles of the **MPL-2.0** - a philosophical manifesto for building technology that serves humanity's long-term flourishing.
 
-The Palimpsest License is not a legal document but a commitment to:
+The MPL-2.0 is not a legal document but a commitment to:
 
 * Building on the work of others with gratitude
 * Leaving the codebase better than you found it
@@ -161,7 +162,7 @@ claude-gecko-browser-extension/
 │       └── icon-*.png      # Extension icons
 ├── docs/
 │   └── PALIMPSEST.adoc     # Philosophical license
-├── LICENSE                 # Palimpsest-MPL License v1.0 (PMPL-1.0)
+├── LICENSE                 # MPL-2.0 License v1.0 (MPL-2.0)
 ├── README.adoc             # This file
 └── STATE.scm               # Project state checkpoint
 ----
diff --git a/gecko-browser-extension/ROADMAP.adoc b/gecko-browser-extension/ROADMAP.adoc
index d4857db..b2970a9 100644
--- a/gecko-browser-extension/ROADMAP.adoc
+++ b/gecko-browser-extension/ROADMAP.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Claude Gecko Browser Extension Roadmap
 
 == Current Status
diff --git a/gecko-browser-extension/RSR_OUTLINE.adoc b/gecko-browser-extension/RSR_OUTLINE.adoc
index 8a22906..6baed3c 100644
--- a/gecko-browser-extension/RSR_OUTLINE.adoc
+++ b/gecko-browser-extension/RSR_OUTLINE.adoc
@@ -1,6 +1,8 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = RSR Template Repository
 
-image:[Palimpsest-MPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
+image:[MPL-2.0-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
 :toc:
 :sectnums:
 
@@ -209,7 +211,7 @@ This template is part of:
 
 == License
 
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 
 == Links
 
diff --git a/gecko-browser-extension/SECURITY.md b/gecko-browser-extension/SECURITY.md
index 84937e0..a6a2a3a 100644
--- a/gecko-browser-extension/SECURITY.md
+++ b/gecko-browser-extension/SECURITY.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Security Policy
 
 We take security seriously and appreciate your efforts to responsibly disclose vulnerabilities. This policy outlines how to report security issues, what to expect, and how we recognize contributions.
diff --git a/gecko-browser-extension/ai-cli-crash-capture/README.adoc b/gecko-browser-extension/ai-cli-crash-capture/README.adoc
index 2fcda87..689b158 100644
--- a/gecko-browser-extension/ai-cli-crash-capture/README.adoc
+++ b/gecko-browser-extension/ai-cli-crash-capture/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = AI CLI Crash Capture
 :revdate: 2026-01-17
 
diff --git a/gecko-browser-extension/contractiles/README.adoc b/gecko-browser-extension/contractiles/README.adoc
index d19a387..70ad712 100644
--- a/gecko-browser-extension/contractiles/README.adoc
+++ b/gecko-browser-extension/contractiles/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Contractiles Template Set
 :toc:
 :sectnums:
diff --git a/gecko-browser-extension/docs/CITATIONS.adoc b/gecko-browser-extension/docs/CITATIONS.adoc
index 564f0ae..52ba528 100644
--- a/gecko-browser-extension/docs/CITATIONS.adoc
+++ b/gecko-browser-extension/docs/CITATIONS.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = RSR-template-repo - Citation Guide
 :toc:
 
@@ -10,7 +12,7 @@
   title = {RSR-template-repo},
   year = {2025},
   url = {https://github.com/hyperpolymath/RSR-template-repo},
-  license = {AGPL-3.0-or-later}
+  license = {MPL-2.0}
 }
 ----
 
diff --git a/gecko-browser-extension/docs/PALIMPSEST.adoc b/gecko-browser-extension/docs/PALIMPSEST.adoc
index 7421908..5f69031 100644
--- a/gecko-browser-extension/docs/PALIMPSEST.adoc
+++ b/gecko-browser-extension/docs/PALIMPSEST.adoc
@@ -1,5 +1,6 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
-= The Palimpsest License
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+= The MPL-2.0
 :author: hyperpolymath
 :revdate: 2025
 
@@ -14,7 +15,7 @@ ____
 
 This is not a legal license. It is a philosophical companion to whatever legal license you choose.
 
-The Palimpsest License is a commitment - to yourself, to your collaborators, and to those who will inherit your code long after you have moved on.
+The MPL-2.0 is a commitment - to yourself, to your collaborators, and to those who will inherit your code long after you have moved on.
 
 == The Principles
 
@@ -87,7 +88,7 @@ Build with care, but hold loosely.
 
 == Adoption
 
-To adopt the Palimpsest License:
+To adopt the MPL-2.0:
 
 . Include it alongside your legal license
 . Reference it in your README
@@ -110,4 +111,4 @@ ____
 
 ---
 
-_The Palimpsest License is released to the public domain under CC0. Copy it, modify it, make it your own._
+_The MPL-2.0 is released to the public domain under CC0. Copy it, modify it, make it your own._
diff --git a/gecko-browser-extension/manifest.scm b/gecko-browser-extension/manifest.scm
new file mode 100644
index 0000000..dd942c7
--- /dev/null
+++ b/gecko-browser-extension/manifest.scm
@@ -0,0 +1,24 @@
+;;; SPDX-License-Identifier: MPL-2.0
+;;; manifest.scm — Generic Guix manifest for RSR-compliant projects
+;;;
+;;; Usage:
+;;;   guix shell -m manifest.scm
+;;;
+
+(specifications->manifest
+  '(;; Core development tools
+    "git"
+    "just"
+    "nickel"
+    "curl"
+    "bash"
+    "coreutils"
+
+    ;; Documentation
+    "asciidoctor"
+    "pandoc"
+
+    ;; Common build dependencies
+    "openssl"
+    "zlib"
+    "pkg-config"))
diff --git a/gecko-browser-extension/src/background/background.js b/gecko-browser-extension/src/background/background.js
index 80b960e..468abf6 100644
--- a/gecko-browser-extension/src/background/background.js
+++ b/gecko-browser-extension/src/background/background.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude for Gecko - Background Service Worker
 
 const ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages";
diff --git a/gecko-browser-extension/src/content/content.js b/gecko-browser-extension/src/content/content.js
index 37e3d1c..9079c7f 100644
--- a/gecko-browser-extension/src/content/content.js
+++ b/gecko-browser-extension/src/content/content.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude for Gecko - Content Script
 
 /**
@@ -12,22 +13,44 @@ function showResponseOverlay(text, isError = false) {
 
   const overlay = document.createElement("div");
   overlay.id = "claude-gecko-overlay";
-  overlay.innerHTML = `
-    <div class="claude-gecko-response ${isError ? 'error' : ''}">
-      <div class="claude-gecko-header">
-        <span class="claude-gecko-title">Claude</span>
-        <button class="claude-gecko-close" title="Close">&times;</button>
-      </div>
-      <div class="claude-gecko-content"></div>
-      <div class="claude-gecko-actions">
-        <button class="claude-gecko-copy" title="Copy to clipboard">Copy</button>
-      </div>
-    </div>
-  `;
+  
+  // Create overlay structure safely without innerHTML
+  const responseDiv = document.createElement("div");
+  responseDiv.className = `claude-gecko-response ${isError ? 'error' : ''}`;
+  
+  const headerDiv = document.createElement("div");
+  headerDiv.className = "claude-gecko-header";
+  
+  const titleSpan = document.createElement("span");
+  titleSpan.className = "claude-gecko-title";
+  titleSpan.textContent = "Claude";
+  headerDiv.appendChild(titleSpan);
+  
+  const closeBtn = document.createElement("button");
+  closeBtn.className = "claude-gecko-close";
+  closeBtn.title = "Close";
+  closeBtn.textContent = "×";
+  headerDiv.appendChild(closeBtn);
+  
+  const contentDiv = document.createElement("div");
+  contentDiv.className = "claude-gecko-content";
+  contentDiv.textContent = text;
+  
+  const actionsDiv = document.createElement("div");
+  actionsDiv.className = "claude-gecko-actions";
+  
+  const copyBtn = document.createElement("button");
+  copyBtn.className = "claude-gecko-copy";
+  copyBtn.title = "Copy to clipboard";
+  copyBtn.textContent = "Copy";
+  actionsDiv.appendChild(copyBtn);
+  
+  responseDiv.appendChild(headerDiv);
+  responseDiv.appendChild(contentDiv);
+  responseDiv.appendChild(actionsDiv);
+  overlay.appendChild(responseDiv);
 
   // Set content safely
-  const contentDiv = overlay.querySelector(".claude-gecko-content");
-  contentDiv.textContent = text;
 
   // Close button handler
   overlay.querySelector(".claude-gecko-close").addEventListener("click", removeOverlay);
diff --git a/gecko-browser-extension/src/popup/options.js b/gecko-browser-extension/src/popup/options.js
index 87e7959..1ad57b5 100644
--- a/gecko-browser-extension/src/popup/options.js
+++ b/gecko-browser-extension/src/popup/options.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude for Gecko - Options Page Script
 
 const apiKeyInput = document.getElementById("api-key");
diff --git a/gecko-browser-extension/src/popup/popup.js b/gecko-browser-extension/src/popup/popup.js
index 8d5cbae..3227426 100644
--- a/gecko-browser-extension/src/popup/popup.js
+++ b/gecko-browser-extension/src/popup/popup.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude for Gecko - Popup Script
 
 const messagesContainer = document.getElementById("messages");
@@ -38,7 +39,9 @@ function addMessage(text, role, isLoading = false) {
 
   if (isLoading) {
     messageDiv.classList.add("loading");
-    messageDiv.innerHTML = "<p>Thinking</p>";
+    const paragraph = document.createElement("p");
+    paragraph.textContent = "Thinking";
+    messageDiv.appendChild(paragraph);
   } else {
     const paragraph = document.createElement("p");
     paragraph.textContent = text;
@@ -58,7 +61,10 @@ function addMessage(text, role, isLoading = false) {
  */
 function updateMessage(element, text) {
   element.classList.remove("loading");
-  element.innerHTML = "";
+  // Clear element safely
+  while (element.firstChild) {
+    element.removeChild(element.firstChild);
+  }
   const paragraph = document.createElement("p");
   paragraph.textContent = text;
   element.appendChild(paragraph);
diff --git a/gitlab-bridge/.claude/CLAUDE.md b/gitlab-bridge/.claude/CLAUDE.md
index c878259..ce34367 100644
--- a/gitlab-bridge/.claude/CLAUDE.md
+++ b/gitlab-bridge/.claude/CLAUDE.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 ## Machine-Readable Artefacts
 
 The following files in `.machine_readable/` contain structured project metadata:
@@ -19,14 +23,14 @@ The following files in `.machine_readable/` contain structured project metadata:
 
 | Language/Tool | Use Case | Notes |
 |---------------|----------|-------|
-| **ReScript** | Primary application code | Compiles to JS, type-safe |
+| **AffineScript** | Primary application code | Compiles to JS, type-safe |
 | **Deno** | Runtime & package management | Replaces Node/npm/bun |
 | **Rust** | Performance-critical, systems, WASM | Preferred for CLI tools |
 | **Tauri 2.0+** | Mobile apps (iOS/Android) | Rust backend + web UI |
 | **Dioxus** | Mobile apps (native UI) | Pure Rust, React-like |
 | **Gleam** | Backend services | Runs on BEAM or compiles to JS |
 | **Bash/POSIX Shell** | Scripts, automation | Keep minimal |
-| **JavaScript** | Only where ReScript cannot | MCP protocol glue, Deno APIs |
+| **JavaScript** | Only where AffineScript cannot | MCP protocol glue, Deno APIs |
 | **Nickel** | Configuration language | For complex configs |
 | **Guile Scheme** | State/meta files | STATE.scm, META.scm, ECOSYSTEM.scm |
 | **Julia** | Batch scripts, data processing | Per RSR |
@@ -37,7 +41,7 @@ The following files in `.machine_readable/` contain structured project metadata:
 
 | Banned | Replacement |
 |--------|-------------|
-| TypeScript | ReScript |
+| TypeScript | AffineScript |
 | Node.js | Deno |
 | npm | Deno |
 | Bun | Deno |
@@ -53,18 +57,18 @@ The following files in `.machine_readable/` contain structured project metadata:
 
 **No exceptions for Kotlin/Swift** - use Rust-first approach:
 
-1. **Tauri 2.0+** - Web UI (ReScript) + Rust backend, MIT/Apache-2.0
+1. **Tauri 2.0+** - Web UI (AffineScript) + Rust backend, MIT/Apache-2.0
 2. **Dioxus** - Pure Rust native UI, MIT/Apache-2.0
 
 Both are FOSS with independent governance (no Big Tech).
 
 ### Enforcement Rules
 
-1. **No new TypeScript files** - Convert existing TS to ReScript
-2. **No package.json for runtime deps** - Use deno.json imports
+1. **No new TypeScript files** - Convert existing TS to AffineScript
+2. **No package.json - use deno.json deps** - Use deno.json imports
 3. **No node_modules in production** - Deno caches deps automatically
 4. **No Go code** - Use Rust instead
-5. **No Python anywhere** - Use Julia for data/batch, Rust for systems, ReScript for apps
+5. **No Python anywhere** - Use Julia for data/batch, Rust for systems, AffineScript for apps
 6. **No Kotlin/Swift for mobile** - Use Tauri 2.0+ or Dioxus
 
 ### Package Management
diff --git a/gitlab-bridge/.github/ISSUE_TEMPLATE/bug_report.md b/gitlab-bridge/.github/ISSUE_TEMPLATE/bug_report.md
index 987aab6..45a6c02 100644
--- a/gitlab-bridge/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/gitlab-bridge/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 ---
 name: Bug report
 about: Create a report to help us improve
diff --git a/gitlab-bridge/.github/ISSUE_TEMPLATE/custom.md b/gitlab-bridge/.github/ISSUE_TEMPLATE/custom.md
index 48d5f81..99ebf00 100644
--- a/gitlab-bridge/.github/ISSUE_TEMPLATE/custom.md
+++ b/gitlab-bridge/.github/ISSUE_TEMPLATE/custom.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 ---
 name: Custom issue template
 about: Describe this issue template's purpose here.
diff --git a/gitlab-bridge/.github/ISSUE_TEMPLATE/documentation.md b/gitlab-bridge/.github/ISSUE_TEMPLATE/documentation.md
index 4fcb9f9..b1d16df 100644
--- a/gitlab-bridge/.github/ISSUE_TEMPLATE/documentation.md
+++ b/gitlab-bridge/.github/ISSUE_TEMPLATE/documentation.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 ---
 name: Documentation
 about: Report unclear, missing, or incorrect documentation
diff --git a/gitlab-bridge/.github/ISSUE_TEMPLATE/feature_request.md b/gitlab-bridge/.github/ISSUE_TEMPLATE/feature_request.md
index 3e8fa7e..a5a5693 100644
--- a/gitlab-bridge/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/gitlab-bridge/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 ---
 name: Feature request
 about: Suggest an idea for this project
diff --git a/gitlab-bridge/.github/ISSUE_TEMPLATE/question.md b/gitlab-bridge/.github/ISSUE_TEMPLATE/question.md
index fd0e2a5..c2d1f57 100644
--- a/gitlab-bridge/.github/ISSUE_TEMPLATE/question.md
+++ b/gitlab-bridge/.github/ISSUE_TEMPLATE/question.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 ---
 name: Question
 about: Ask a question about usage or behaviour
diff --git a/gitlab-bridge/.github/workflows/codeql.yml b/gitlab-bridge/.github/workflows/codeql.yml
index 391dc78..bc3fae4 100644
--- a/gitlab-bridge/.github/workflows/codeql.yml
+++ b/gitlab-bridge/.github/workflows/codeql.yml
@@ -1,6 +1,5 @@
-# SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: MPL-2.0-or-later
 name: CodeQL Security Analysis
-
 on:
   push:
     branches: [main, master]
@@ -8,12 +7,11 @@ on:
     branches: [main, master]
   schedule:
     - cron: '0 6 * * 1'
-
 permissions: read-all
-
 jobs:
   analyze:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       contents: read
       security-events: write
@@ -23,17 +21,14 @@ jobs:
         include:
           - language: javascript-typescript
             build-mode: none
-
     steps:
       - name: Checkout
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
-
       - name: Initialize CodeQL
         uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.28.1
         with:
           languages: ${{ matrix.language }}
           build-mode: ${{ matrix.build-mode }}
-
       - name: Perform CodeQL Analysis
         uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.28.1
         with:
diff --git a/gitlab-bridge/.github/workflows/governance.yml b/gitlab-bridge/.github/workflows/governance.yml
index b0b1ed6..60e8e90 100644
--- a/gitlab-bridge/.github/workflows/governance.yml
+++ b/gitlab-bridge/.github/workflows/governance.yml
@@ -11,16 +11,14 @@
 # (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing).
 
 name: Governance
-
 on:
   push:
     branches: [main, master]
   pull_request:
   workflow_dispatch:
-
 permissions:
   contents: read
-
 jobs:
   governance:
-    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@main
+    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613
+    timeout-minutes: 10
diff --git a/gitlab-bridge/.github/workflows/hypatia-scan.yml b/gitlab-bridge/.github/workflows/hypatia-scan.yml
index 5b59919..c3cb66b 100644
--- a/gitlab-bridge/.github/workflows/hypatia-scan.yml
+++ b/gitlab-bridge/.github/workflows/hypatia-scan.yml
@@ -1,41 +1,35 @@
 # SPDX-License-Identifier: MPL-2.0
 # Hypatia Neurosymbolic CI/CD Security Scan
 name: Hypatia Security Scan
-
 on:
   push:
-    branches: [ main, master, develop ]
+    branches: [main, master, develop]
   pull_request:
-    branches: [ main, master ]
+    branches: [main, master]
   schedule:
-    - cron: '0 0 * * 0'  # Weekly on Sunday
+    - cron: '0 0 * * 0' # Weekly on Sunday
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   scan:
     name: Hypatia Neurosymbolic Analysis
     runs-on: ubuntu-latest
-
+    timeout-minutes: 15
     steps:
       - name: Checkout repository
         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
         with:
-          fetch-depth: 0  # Full history for better pattern analysis
-
+          fetch-depth: 0 # Full history for better pattern analysis
       - name: Setup Elixir for Hypatia scanner
         uses: erlef/setup-beam@2f0cc07b4b9bea248ae098aba9e1a8a1de5ec24c # v1.18.2
         with:
           elixir-version: '1.19.4'
           otp-version: '28.3'
-
       - name: Clone Hypatia
         run: |
           if [ ! -d "$HOME/hypatia" ]; then
             git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
           fi
-
       - name: Build Hypatia scanner (if needed)
         working-directory: ${{ env.HOME }}/hypatia
         run: |
@@ -46,7 +40,6 @@ jobs:
             mix escript.build
             mv hypatia ../hypatia-v2
           fi
-
       - name: Run Hypatia scan
         id: scan
         run: |
@@ -73,35 +66,19 @@ jobs:
           echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
           echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
           echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
-
       - name: Upload findings artifact
         uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
         with:
           name: hypatia-findings
           path: hypatia-findings.json
           retention-days: 90
-
       - name: Submit findings to gitbot-fleet (Phase 2)
         if: steps.scan.outputs.findings_count > 0
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           GITHUB_REPOSITORY: ${{ github.repository }}
           GITHUB_SHA: ${{ github.sha }}
-        run: |
-          echo "📤 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet..."
-
-          # Clone gitbot-fleet to temp directory
-          FLEET_DIR="/tmp/gitbot-fleet-$$"
-          git clone https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"
-
-          # Run submission script
-          bash "$FLEET_DIR/scripts/submit-finding.sh" hypatia-findings.json
-
-          # Cleanup
-          rm -rf "$FLEET_DIR"
-
-          echo "✅ Finding submission complete"
-
+        run: "echo \"\U0001F4E4 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet...\"\n\n# Clone gitbot-fleet to temp directory\nFLEET_DIR=\"/tmp/gitbot-fleet-$$\"\ngit clone https://github.com/hyperpolymath/gitbot-fleet.git \"$FLEET_DIR\"\n\n# Run submission script\nbash \"$FLEET_DIR/scripts/submit-finding.sh\" hypatia-findings.json\n\n# Cleanup\nrm -rf \"$FLEET_DIR\"\n\necho \"✅ Finding submission complete\"\n"
       - name: Check for critical issues
         if: steps.scan.outputs.critical > 0
         run: |
@@ -109,7 +86,6 @@ jobs:
           echo "Review hypatia-findings.json for details"
           # Don't fail the build yet - just warn
           # exit 1
-
       - name: Generate scan report
         run: |
           cat << EOF > hypatia-report.md
@@ -143,37 +119,8 @@ jobs:
           EOF
 
           cat hypatia-report.md >> $GITHUB_STEP_SUMMARY
-
       - name: Comment on PR with findings
         if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
         uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
         with:
-          script: |
-            const fs = require('fs');
-            const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));
-
-            const critical = findings.filter(f => f.severity === 'critical').length;
-            const high = findings.filter(f => f.severity === 'high').length;
-
-            let comment = `## 🔍 Hypatia Security Scan\n\n`;
-            comment += `**Findings:** ${findings.length} issues detected\n\n`;
-            comment += `| Severity | Count |\n|----------|-------|\n`;
-            comment += `| 🔴 Critical | ${critical} |\n`;
-            comment += `| 🟠 High | ${high} |\n`;
-            comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;
-
-            if (critical > 0) {
-              comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
-            }
-
-            comment += `<details><summary>View findings</summary>\n\n`;
-            comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
-            comment += `</details>\n\n`;
-            comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;
-
-            github.rest.issues.createComment({
-              owner: context.repo.owner,
-              repo: context.repo.repo,
-              issue_number: context.issue.number,
-              body: comment
-            });
+          script: "const fs = require('fs');\nconst findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));\n\nconst critical = findings.filter(f => f.severity === 'critical').length;\nconst high = findings.filter(f => f.severity === 'high').length;\n\nlet comment = `## \U0001F50D Hypatia Security Scan\\n\\n`;\ncomment += `**Findings:** ${findings.length} issues detected\\n\\n`;\ncomment += `| Severity | Count |\\n|----------|-------|\\n`;\ncomment += `| \U0001F534 Critical | ${critical} |\\n`;\ncomment += `| \U0001F7E0 High | ${high} |\\n`;\ncomment += `| \U0001F7E1 Medium | ${findings.length - critical - high} |\\n\\n`;\n\nif (critical > 0) {\n  comment += `⚠️ **Action Required:** Critical security issues found!\\n\\n`;\n}\n\ncomment += `<details><summary>View findings</summary>\\n\\n`;\ncomment += `\\`\\`\\`json\\n${JSON.stringify(findings.slice(0, 10), null, 2)}\\n\\`\\`\\`\\n`;\ncomment += `</details>\\n\\n`;\ncomment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;\n\ngithub.rest.issues.createComment({\n  owner: context.repo.owner,\n  repo: context.repo.repo,\n  issue_number: context.issue.number,\n  body: comment\n});\n"
diff --git a/gitlab-bridge/.github/workflows/jekyll-gh-pages.yml b/gitlab-bridge/.github/workflows/jekyll-gh-pages.yml
index 1f4d35c..7ad9b91 100644
--- a/gitlab-bridge/.github/workflows/jekyll-gh-pages.yml
+++ b/gitlab-bridge/.github/workflows/jekyll-gh-pages.yml
@@ -1,31 +1,27 @@
 # SPDX-License-Identifier: MPL-2.0
 # Sample workflow for building and deploying a Jekyll site to GitHub Pages
 name: Deploy Jekyll with GitHub Pages dependencies preinstalled
-
 on:
   # Runs on pushes targeting the default branch
   push:
     branches: ["main"]
-
   # Allows you to run this workflow manually from the Actions tab
   workflow_dispatch:
-
 # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
 permissions:
   contents: read
   pages: write
   id-token: write
-
 # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
 # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
 concurrency:
   group: "pages"
   cancel-in-progress: false
-
 jobs:
   # Build job
   build:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - name: Checkout
         uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -38,13 +34,13 @@ jobs:
           destination: ./_site
       - name: Upload artifact
         uses: actions/upload-pages-artifact@v4
-
   # Deployment job
   deploy:
     environment:
       name: github-pages
       url: ${{ steps.deployment.outputs.page_url }}
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     needs: build
     steps:
       - name: Deploy to GitHub Pages
diff --git a/gitlab-bridge/.github/workflows/mirror.yml b/gitlab-bridge/.github/workflows/mirror.yml
index 7af3b2f..922db39 100644
--- a/gitlab-bridge/.github/workflows/mirror.yml
+++ b/gitlab-bridge/.github/workflows/mirror.yml
@@ -1,142 +1,125 @@
 # SPDX-License-Identifier: MPL-2.0
 # SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell
 name: Mirror to Git Forges
-
 on:
   push:
     branches: [main]
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   mirror-gitlab:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.GITLAB_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.GITLAB_SSH_KEY }}
-
       - name: Mirror to GitLab
         run: |
           ssh-keyscan -t ed25519 gitlab.com >> ~/.ssh/known_hosts
           git remote add gitlab git@gitlab.com:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force gitlab main
-
   mirror-bitbucket:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.BITBUCKET_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.BITBUCKET_SSH_KEY }}
-
       - name: Mirror to Bitbucket
         run: |
           ssh-keyscan -t ed25519 bitbucket.org >> ~/.ssh/known_hosts
           git remote add bitbucket git@bitbucket.org:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force bitbucket main
-
   mirror-codeberg:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.CODEBERG_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.CODEBERG_SSH_KEY }}
-
       - name: Mirror to Codeberg
         run: |
           ssh-keyscan -t ed25519 codeberg.org >> ~/.ssh/known_hosts
           git remote add codeberg git@codeberg.org:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force codeberg main
-
   mirror-sourcehut:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.SOURCEHUT_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.SOURCEHUT_SSH_KEY }}
-
       - name: Mirror to SourceHut
         run: |
           ssh-keyscan -t ed25519 git.sr.ht >> ~/.ssh/known_hosts
           git remote add sourcehut git@git.sr.ht:~hyperpolymath/${{ github.event.repository.name }} || true
           git push --force sourcehut main
-
   mirror-disroot:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.DISROOT_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.DISROOT_SSH_KEY }}
-
       - name: Mirror to Disroot
         run: |
           ssh-keyscan -t ed25519 git.disroot.org >> ~/.ssh/known_hosts
           git remote add disroot git@git.disroot.org:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force disroot main
-
   mirror-gitea:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.GITEA_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           fetch-depth: 0
-
       - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
         with:
           ssh-private-key: ${{ secrets.GITEA_SSH_KEY }}
-
       - name: Mirror to Gitea
         run: |
           ssh-keyscan -t ed25519 ${{ vars.GITEA_HOST }} >> ~/.ssh/known_hosts
           git remote add gitea git@${{ vars.GITEA_HOST }}:hyperpolymath/${{ github.event.repository.name }}.git || true
           git push --force gitea main
-
   mirror-radicle:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: vars.RADICLE_MIRROR_ENABLED == 'true'
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           fetch-depth: 0
-
       - name: Setup Rust
         uses: dtolnay/rust-toolchain@f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 # stable
         with:
           toolchain: stable
-
       - name: Install Radicle
         run: |
           # Install via cargo (safer than curl|sh)
           cargo install radicle-cli --locked
           echo "$HOME/.cargo/bin" >> $GITHUB_PATH
-
       - name: Mirror to Radicle
         run: |
           echo "${{ secrets.RADICLE_KEY }}" > ~/.radicle/keys/radicle
diff --git a/gitlab-bridge/.github/workflows/rescript-deno-ci.yml b/gitlab-bridge/.github/workflows/rescript-deno-ci.yml
index 26771c6..af1ee4c 100644
--- a/gitlab-bridge/.github/workflows/rescript-deno-ci.yml
+++ b/gitlab-bridge/.github/workflows/rescript-deno-ci.yml
@@ -1,37 +1,32 @@
 # SPDX-License-Identifier: MPL-2.0
 name: ReScript/Deno CI
 on: [push, pull_request]
-
 jobs:
   build:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       - uses: denoland/setup-deno@v2
         with:
           deno-version: v1.x
-      
       - name: Deno lint
         run: deno lint
-      
       - name: Deno fmt check
         run: deno fmt --check
-      
       - name: Deno test
         run: deno test --allow-all --coverage=coverage
-      
       - name: ReScript build
         run: |
           if [ -f "rescript.json" ] || [ -f "bsconfig.json" ]; then
             npm install
             npx rescript
           fi
-      
       - name: Type check
         run: deno check **/*.ts || true
-
   security:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       - uses: denoland/setup-deno@v2
diff --git a/gitlab-bridge/.github/workflows/scorecard-enforcer.yml b/gitlab-bridge/.github/workflows/scorecard-enforcer.yml
index 5537465..1aa0c99 100644
--- a/gitlab-bridge/.github/workflows/scorecard-enforcer.yml
+++ b/gitlab-bridge/.github/workflows/scorecard-enforcer.yml
@@ -1,39 +1,34 @@
 # SPDX-License-Identifier: MPL-2.0
 # Prevention workflow - runs OpenSSF Scorecard and fails on low scores
 name: OpenSSF Scorecard Enforcer
-
 on:
   push:
     branches: [main]
   schedule:
-    - cron: '0 6 * * 1'  # Weekly on Monday
+    - cron: '0 6 * * 1' # Weekly on Monday
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   scorecard:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       security-events: write
-      id-token: write  # For OIDC
+      id-token: write # For OIDC
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
           persist-credentials: false
-
       - name: Run Scorecard
         uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
         with:
           results_file: results.sarif
           results_format: sarif
           publish_results: true
-
       - name: Upload SARIF
         uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3
         with:
           sarif_file: results.sarif
-
       - name: Check minimum score
         run: |
           # Parse score from results
@@ -48,20 +43,18 @@ jobs:
             echo "::error::Scorecard score $SCORE is below minimum $MIN_SCORE"
             exit 1
           fi
-
   # Check specific high-priority items
   check-critical:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
-
       - name: Check SECURITY.md exists
         run: |
           if [ ! -f "SECURITY.md" ]; then
             echo "::error::SECURITY.md is required"
             exit 1
           fi
-
       - name: Check for pinned dependencies
         run: |
           # Check workflows for unpinned actions
diff --git a/gitlab-bridge/.github/workflows/scorecard.yml b/gitlab-bridge/.github/workflows/scorecard.yml
index 443d4c8..a2b1d43 100644
--- a/gitlab-bridge/.github/workflows/scorecard.yml
+++ b/gitlab-bridge/.github/workflows/scorecard.yml
@@ -6,12 +6,11 @@ on:
   schedule:
     - cron: '0 4 * * *'
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   analysis:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       security-events: write
       id-token: write
@@ -19,13 +18,11 @@ jobs:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
           persist-credentials: false
-
       - name: Run Scorecard
         uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.3.1
         with:
           results_file: results.sarif
           results_format: sarif
-
       - name: Upload results
         uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.31.8
         with:
diff --git a/gitlab-bridge/.github/workflows/secret-scanner.yml b/gitlab-bridge/.github/workflows/secret-scanner.yml
index 680cbcd..bf9a58a 100644
--- a/gitlab-bridge/.github/workflows/secret-scanner.yml
+++ b/gitlab-bridge/.github/workflows/secret-scanner.yml
@@ -1,46 +1,30 @@
 # SPDX-License-Identifier: MPL-2.0
 # Prevention workflow - scans for hardcoded secrets before they reach main
 name: Secret Scanner
-
 on:
   pull_request:
   push:
     branches: [main]
-
 permissions: read-all
-
 jobs:
   trufflehog:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
         with:
-          fetch-depth: 0  # Full history for scanning
-
+          fetch-depth: 0 # Full history for scanning
       - name: TruffleHog Secret Scan
         uses: trufflesecurity/trufflehog@ef6e76c3c4023279497fab4721ffa071a722fd05 # v3
         with:
           extra_args: --only-verified --fail
-
-  gitleaks:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
-        with:
-          fetch-depth: 0
-
-      - name: Gitleaks Secret Scan
-        uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
   # Rust-specific: Check for hardcoded crypto values
   rust-secrets:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     if: hashFiles('**/Cargo.toml') != ''
     steps:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4
-
       - name: Check for hardcoded secrets in Rust
         run: |
           # Patterns that suggest hardcoded secrets
diff --git a/gitlab-bridge/.machine_readable/6a2/AGENTIC.a2ml b/gitlab-bridge/.machine_readable/6a2/AGENTIC.a2ml
new file mode 100644
index 0000000..c25b68b
--- /dev/null
+++ b/gitlab-bridge/.machine_readable/6a2/AGENTIC.a2ml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[metadata]
+claude-code = [
+  ["model", "claude-opus-4-5-20251101"],
+  [
+  "tools",
+  ["read", "edit", "bash", "grep", "glob"],
+],
+  ["permissions", "read-all"],
+]
+constraints = [
+  [
+  "languages",
+  [],
+],
+  [
+  "banned",
+  ["typescript", "go", "python", "makefile"],
+],
+]
+patterns = [
+  ["code-review", "thorough"],
+  ["refactoring", "conservative"],
+  ["testing", "comprehensive"],
+]
+version = "1.0.0"
+
+
diff --git a/gitlab-bridge/.machine_readable/6a2/ECOSYSTEM.a2ml b/gitlab-bridge/.machine_readable/6a2/ECOSYSTEM.a2ml
new file mode 100644
index 0000000..651c13d
--- /dev/null
+++ b/gitlab-bridge/.machine_readable/6a2/ECOSYSTEM.a2ml
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[ecosystem]
+name = "claude-gitlab-bridge"
+position-in-ecosystem = ["category", ""]
+purpose = ""
+related-projects = []
+type = ""
+version = "1.0"
+what-this-is = []
+what-this-is-not = []
+
+
diff --git a/gitlab-bridge/.machine_readable/6a2/META.a2ml b/gitlab-bridge/.machine_readable/6a2/META.a2ml
new file mode 100644
index 0000000..700b724
--- /dev/null
+++ b/gitlab-bridge/.machine_readable/6a2/META.a2ml
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[meta]
+architecture-decisions = []
+design-rationale = []
+development-practices = [
+  "code-style",
+  [],
+]
+
+
diff --git a/gitlab-bridge/.machine_readable/6a2/NEUROSYM.a2ml b/gitlab-bridge/.machine_readable/6a2/NEUROSYM.a2ml
new file mode 100644
index 0000000..d1f7205
--- /dev/null
+++ b/gitlab-bridge/.machine_readable/6a2/NEUROSYM.a2ml
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[metadata]
+integration = []
+neural-layer = [
+  ["embeddings", "false"],
+  ["fine-tuning", "false"],
+]
+symbolic-layer = [
+  ["type", "scheme"],
+  ["reasoning", "deductive"],
+  ["verification", "formal"],
+]
+version = "1.0.0"
+
+
diff --git a/gitlab-bridge/.machine_readable/6a2/PLAYBOOK.a2ml b/gitlab-bridge/.machine_readable/6a2/PLAYBOOK.a2ml
new file mode 100644
index 0000000..08fa460
--- /dev/null
+++ b/gitlab-bridge/.machine_readable/6a2/PLAYBOOK.a2ml
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[metadata]
+alerts = []
+contacts = []
+procedures = [
+  [
+  "deploy",
+  [
+  ["build", "just build"],
+  ["test", "just test"],
+  ["release", "just release"],
+],
+],
+  [
+  "rollback",
+  [],
+],
+  [
+  "debug",
+  [],
+],
+]
+version = "1.0.0"
+
+
diff --git a/gitlab-bridge/.machine_readable/6a2/STATE.a2ml b/gitlab-bridge/.machine_readable/6a2/STATE.a2ml
new file mode 100644
index 0000000..eec647e
--- /dev/null
+++ b/gitlab-bridge/.machine_readable/6a2/STATE.a2ml
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: PMPL-1.0-or-later
+# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
+#
+# Converted from .scm format
+
+# SPDX-License-Identifier: PMPL-1.0-or-later
+
+[state]
+blockers-and-issues = ["critical"]
+critical-next-actions = ["immediate"]
+current-position = ["phase", "initial"]
+metadata = ["version", "0.0.1"]
+project-context = ["name", "claude-gitlab-bridge"]
+route-to-mvp = [
+  "milestones",
+  [],
+]
+session-history = []
+
+
diff --git a/gitlab-bridge/ABI-FFI-README.md b/gitlab-bridge/ABI-FFI-README.md
index 08d35da..cf73490 100644
--- a/gitlab-bridge/ABI-FFI-README.md
+++ b/gitlab-bridge/ABI-FFI-README.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 {{~ Aditionally delete this line and fill out the template below ~}}
 
 # {{PROJECT}} ABI/FFI Documentation
diff --git a/gitlab-bridge/CLAUDE.md b/gitlab-bridge/CLAUDE.md
index 90d5eb4..cef0fc6 100644
--- a/gitlab-bridge/CLAUDE.md
+++ b/gitlab-bridge/CLAUDE.md
@@ -1,8 +1,7 @@
 <!--
-SPDX-License-Identifier: CC-BY-SA-4.0
-SPDX-FileCopyrightText: 2024 hyperpolymath
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 -->
-
 # Claude GitLab Bridge
 
 ## Project Overview
diff --git a/gitlab-bridge/CODE_OF_CONDUCT.adoc b/gitlab-bridge/CODE_OF_CONDUCT.adoc
index 8d20384..684bdab 100644
--- a/gitlab-bridge/CODE_OF_CONDUCT.adoc
+++ b/gitlab-bridge/CODE_OF_CONDUCT.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Contributor Covenant Code of Conduct
 :toc:
 :toclevels: 2
diff --git a/gitlab-bridge/CODE_OF_CONDUCT.md b/gitlab-bridge/CODE_OF_CONDUCT.md
index caeda1c..9020def 100644
--- a/gitlab-bridge/CODE_OF_CONDUCT.md
+++ b/gitlab-bridge/CODE_OF_CONDUCT.md
@@ -1,4 +1,7 @@
-<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Contributor Covenant Code of Conduct
 
 ## Our Pledge
diff --git a/gitlab-bridge/COMPLETION-REPORT.adoc b/gitlab-bridge/COMPLETION-REPORT.adoc
index d03f7ae..f4837a8 100644
--- a/gitlab-bridge/COMPLETION-REPORT.adoc
+++ b/gitlab-bridge/COMPLETION-REPORT.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Claude GitLab Bridge - Completion Report
 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 v2.0.0, 2025-01-23
@@ -26,7 +28,7 @@ All requested features for the Claude GitLab Bridge have been successfully imple
 
 |License updates
 |✅ Complete
-|PMPL-1.0-or-later applied throughout
+|MPL-2.0-or-later applied throughout
 
 |Documentation
 |✅ Complete
@@ -233,7 +235,7 @@ All requested features for the Claude GitLab Bridge have been successfully imple
 
 - All files have SPDX headers
 - Proper copyright attribution (Jonathan D.A. Jewell)
-- PMPL-1.0-or-later license throughout
+- MPL-2.0-or-later license throughout
 - Descriptive variable names
 - Comprehensive type definitions
 - Documented functions with DocStrings
@@ -439,7 +441,7 @@ The Claude GitLab Bridge v2.0 is feature-complete for the initial roadmap:
 
 **Project Status:** 🟢 **Ready for Development & Testing**
 
-**License:** PMPL-1.0-or-later (Palimpsest License)
+**License:** MPL-2.0-or-later (MPL-2.0)
 
 **Author:** Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 
diff --git a/gitlab-bridge/CONTRIBUTING.adoc b/gitlab-bridge/CONTRIBUTING.adoc
index 2b0ad29..bc9c959 100644
--- a/gitlab-bridge/CONTRIBUTING.adoc
+++ b/gitlab-bridge/CONTRIBUTING.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Contributing to Claude GitLab Bridge
 :toc:
 :toclevels: 3
diff --git a/gitlab-bridge/CONTRIBUTING.md b/gitlab-bridge/CONTRIBUTING.md
index b39b3f7..455e511 100644
--- a/gitlab-bridge/CONTRIBUTING.md
+++ b/gitlab-bridge/CONTRIBUTING.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Clone the repository
 git clone https://{{FORGE}}/{{OWNER}}/{{REPO}}.git
 cd {{REPO}}
diff --git a/gitlab-bridge/CONTRIBUTORS.md b/gitlab-bridge/CONTRIBUTORS.md
index 865a0c6..a265e24 100644
--- a/gitlab-bridge/CONTRIBUTORS.md
+++ b/gitlab-bridge/CONTRIBUTORS.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Contributors
 
 Thank you to everyone who has contributed to Claude GitLab Bridge!
diff --git a/gitlab-bridge/GOVERNANCE.adoc b/gitlab-bridge/GOVERNANCE.adoc
index ce9545a..e484725 100644
--- a/gitlab-bridge/GOVERNANCE.adoc
+++ b/gitlab-bridge/GOVERNANCE.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Governance
 :toc:
 :toclevels: 3
diff --git a/gitlab-bridge/HANDOVER.md b/gitlab-bridge/HANDOVER.md
index 4ee4565..bff7d77 100644
--- a/gitlab-bridge/HANDOVER.md
+++ b/gitlab-bridge/HANDOVER.md
@@ -1,8 +1,7 @@
 <!--
-SPDX-License-Identifier: CC-BY-SA-4.0
-SPDX-FileCopyrightText: 2025 Jonathan D.A. Jewell
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 -->
-
 # Claude-GitLab Bridge Project Handover Document
 
 ## Project Identity
diff --git a/gitlab-bridge/Justfile b/gitlab-bridge/Justfile
index 8f5f81f..702f5f6 100644
--- a/gitlab-bridge/Justfile
+++ b/gitlab-bridge/Justfile
@@ -216,3 +216,6 @@ ci: build lint check test
 # Run full CI pipeline.
 ci-full: ci test-coverage validate
     @echo "✓ Full CI pipeline passed"
+
+secret-scan-trufflehog:
+    @command -v trufflehog >/dev/null && trufflehog filesystem . --only-verified || true
diff --git a/gitlab-bridge/MAINTAINERS.adoc b/gitlab-bridge/MAINTAINERS.adoc
index 48d9781..becaa3e 100644
--- a/gitlab-bridge/MAINTAINERS.adoc
+++ b/gitlab-bridge/MAINTAINERS.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Maintainers
 :toc: preamble
 
diff --git a/gitlab-bridge/MIGRATION.adoc b/gitlab-bridge/MIGRATION.adoc
index 66c1d65..76f8fb3 100644
--- a/gitlab-bridge/MIGRATION.adoc
+++ b/gitlab-bridge/MIGRATION.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Migration Guide: TypeScript to ReScript
 :toc:
 :toclevels: 3
diff --git a/gitlab-bridge/PALIMPSEST.adoc b/gitlab-bridge/PALIMPSEST.adoc
index e9d2df3..895adf2 100644
--- a/gitlab-bridge/PALIMPSEST.adoc
+++ b/gitlab-bridge/PALIMPSEST.adoc
@@ -1,18 +1,20 @@
-= Palimpsest License
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+= MPL-2.0
 :toc:
 :toc-placement!:
 
-image:https://img.shields.io/badge/License-MPL--2.0-blue.svg[License: PMPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"]
+image:https://img.shields.io/badge/License-PMPL--1.0-blue.svg[License: MPL-2.0,link="https://github.com/hyperpolymath/palimpsest-license"]
 image:https://img.shields.io/badge/Philosophy-Palimpsest-indigo.svg[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
 
 toc::[]
 
 == Legal Status
 
-This project is licensed under the **Palimpsest-MPL License 1.0 (PMPL-1.0)**.
-For SPDX and tooling, use **PMPL-1.0-or-later**.
+This project is licensed under the **MPL-2.0 License 1.0 (MPL-2.0)**.
+For SPDX and tooling, use **MPL-2.0-or-later**.
 
-PMPL-1.0 incorporates the Mozilla Public License 2.0 by reference and adds
+MPL-2.0 incorporates the Mozilla Public License 2.0 by reference and adds
 ethical-use, provenance, and lineage requirements.
 
 == What PMPL Adds
@@ -24,15 +26,15 @@ ethical-use, provenance, and lineage requirements.
 
 == How to Adopt
 
-1. Include the PMPL-1.0 license text in `LICENSE`.
+1. Include the MPL-2.0 license text in `LICENSE`.
 2. Add SPDX headers to source files:
-   `SPDX-License-Identifier: CC-BY-SA-4.0`
+   `SPDX-License-Identifier: MPL-2.0-or-later`
 3. Add a Palimpsest badge to your README (see `assets/badges/` and `embed/license-blocks/`).
 
 == Versioning
 
 See `VERSIONING.adoc` for the release process and the "-or-later" model.
-The current legal text is PMPL-1.0.
+The current legal text is MPL-2.0.
 
 == References
 
diff --git a/gitlab-bridge/README.adoc b/gitlab-bridge/README.adoc
index 8d7f072..03c4c78 100644
--- a/gitlab-bridge/README.adoc
+++ b/gitlab-bridge/README.adoc
@@ -1,8 +1,9 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Claude GitLab Bridge
 
 image:https://img.shields.io/badge/license-PMPL--1.0-blue.svg[License,link="https://github.com/hyperpolymath/palimpsest-license"]
 
-// SPDX-License-Identifier: CC-BY-SA-4.0
 
 [![RSR Compliance](https://img.shields.io/badge/RSR-GOLD-gold?style=flat-square)](RSR.md)
 [![TPCF](https://img.shields.io/badge/TPCF-Perimeter%203-blue?style=flat-square)](GOVERNANCE.adoc)
@@ -312,10 +313,10 @@ We welcome contributions! Please see:
 
 == License
 
-This project is licensed under the [Palimpsest-MPL-1.0 License](LICENSE.txt).
+This project is licensed under the [MPL-2.0-1.0 License](LICENSE.txt).
 
 ```
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0
 ```
 
 == Acknowledgments
diff --git a/gitlab-bridge/REVERSIBILITY.md b/gitlab-bridge/REVERSIBILITY.md
index 0747ffe..29bf947 100644
--- a/gitlab-bridge/REVERSIBILITY.md
+++ b/gitlab-bridge/REVERSIBILITY.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Reversibility: Safe Experimentation Philosophy
 
 ## Core Principle
diff --git a/gitlab-bridge/ROADMAP.adoc b/gitlab-bridge/ROADMAP.adoc
index 8182dfb..eae0899 100644
--- a/gitlab-bridge/ROADMAP.adoc
+++ b/gitlab-bridge/ROADMAP.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Claude Gitlab Bridge Roadmap
 
 == Current Status
diff --git a/gitlab-bridge/RSR.md b/gitlab-bridge/RSR.md
index 31210b2..19a62c5 100644
--- a/gitlab-bridge/RSR.md
+++ b/gitlab-bridge/RSR.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # RSR Compliance Documentation
 
 **Project**: Claude GitLab Bridge
@@ -57,7 +61,7 @@ All required files are present and properly formatted:
 All source files include proper SPDX headers:
 
 ```
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 SPDX-FileCopyrightText: 2024 hyperpolymath
 ```
 
@@ -298,7 +302,7 @@ Open to all contributors who follow the Code of Conduct.
 
 All source files include:
 ```
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 SPDX-FileCopyrightText: 2024 hyperpolymath
 ```
 
diff --git a/gitlab-bridge/RSR_OUTLINE.adoc b/gitlab-bridge/RSR_OUTLINE.adoc
index 8a22906..6baed3c 100644
--- a/gitlab-bridge/RSR_OUTLINE.adoc
+++ b/gitlab-bridge/RSR_OUTLINE.adoc
@@ -1,6 +1,8 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = RSR Template Repository
 
-image:[Palimpsest-MPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
+image:[MPL-2.0-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
 :toc:
 :sectnums:
 
@@ -209,7 +211,7 @@ This template is part of:
 
 == License
 
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 
 == Links
 
diff --git a/gitlab-bridge/SECURITY.md b/gitlab-bridge/SECURITY.md
index 86032b3..5eb8c91 100644
--- a/gitlab-bridge/SECURITY.md
+++ b/gitlab-bridge/SECURITY.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Security Policy
 
 ## Supported Versions
diff --git a/gitlab-bridge/WORK-SUMMARY.adoc b/gitlab-bridge/WORK-SUMMARY.adoc
index 3631803..524a028 100644
--- a/gitlab-bridge/WORK-SUMMARY.adoc
+++ b/gitlab-bridge/WORK-SUMMARY.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Claude GitLab Bridge - Work Summary
 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 :toc:
@@ -15,7 +17,7 @@ Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 - Lines 7-9: Converted `[![...]` Markdown badges to `image:` AsciiDoc syntax
 - Lines 349-351: Converted status badges to AsciiDoc format
 - Added new badges:
-  * PMPL-1.0-or-later license badge
+  * MPL-2.0-or-later license badge
   * ReScript language badge
   * Deno runtime badge
   * Idris-ready badge
@@ -96,7 +98,7 @@ Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 === License Updates
 
 **All files updated to:**
-- License: PMPL-1.0-or-later (Palimpsest License)
+- License: MPL-2.0-or-later (MPL-2.0)
 - Copyright: 2025 Jonathan D.A. Jewell <jonathan.jewell@open.ac.uk>
 - SPDX headers on all source files
 
@@ -272,7 +274,7 @@ claude-gitlab-bridge/
 * All code follows hyperpolymath language policy
 * ReScript provides superior type safety over TypeScript
 * Deno eliminates need for node_modules and npm
-* Palimpsest License (PMPL-1.0-or-later) applied throughout
+* MPL-2.0 (MPL-2.0-or-later) applied throughout
 * Ready for Idris integration when needed
 
 == Contact
diff --git a/gitlab-bridge/ai-cli-crash-capture/README.adoc b/gitlab-bridge/ai-cli-crash-capture/README.adoc
index 2fcda87..689b158 100644
--- a/gitlab-bridge/ai-cli-crash-capture/README.adoc
+++ b/gitlab-bridge/ai-cli-crash-capture/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = AI CLI Crash Capture
 :revdate: 2026-01-17
 
diff --git a/gitlab-bridge/contractiles/README.adoc b/gitlab-bridge/contractiles/README.adoc
index d19a387..70ad712 100644
--- a/gitlab-bridge/contractiles/README.adoc
+++ b/gitlab-bridge/contractiles/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Contractiles Template Set
 :toc:
 :sectnums:
diff --git a/gitlab-bridge/docs/CITATIONS.adoc b/gitlab-bridge/docs/CITATIONS.adoc
index 25a9304..4f812e8 100644
--- a/gitlab-bridge/docs/CITATIONS.adoc
+++ b/gitlab-bridge/docs/CITATIONS.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = claude-gitlab-bridge - Citation Guide
 :toc:
 
@@ -10,7 +12,7 @@
   title = {claude-gitlab-bridge},
   year = {2025},
   url = {https://github.com/hyperpolymath/claude-gitlab-bridge},
-  license = {AGPL-3.0-or-later}
+  license = {MPL-2.0}
 }
 ----
 
diff --git a/gitlab-bridge/manifest.scm b/gitlab-bridge/manifest.scm
new file mode 100644
index 0000000..dd942c7
--- /dev/null
+++ b/gitlab-bridge/manifest.scm
@@ -0,0 +1,24 @@
+;;; SPDX-License-Identifier: MPL-2.0
+;;; manifest.scm — Generic Guix manifest for RSR-compliant projects
+;;;
+;;; Usage:
+;;;   guix shell -m manifest.scm
+;;;
+
+(specifications->manifest
+  '(;; Core development tools
+    "git"
+    "just"
+    "nickel"
+    "curl"
+    "bash"
+    "coreutils"
+
+    ;; Documentation
+    "asciidoctor"
+    "pandoc"
+
+    ;; Common build dependencies
+    "openssl"
+    "zlib"
+    "pkg-config"))
diff --git a/gitlab-bridge/vitest.config.js b/gitlab-bridge/vitest.config.js
index 5018001..85f2786 100644
--- a/gitlab-bridge/vitest.config.js
+++ b/gitlab-bridge/vitest.config.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell
 
 import { defineConfig } from "vitest/config";
diff --git a/manifest.scm b/manifest.scm
new file mode 100644
index 0000000..dd942c7
--- /dev/null
+++ b/manifest.scm
@@ -0,0 +1,24 @@
+;;; SPDX-License-Identifier: MPL-2.0
+;;; manifest.scm — Generic Guix manifest for RSR-compliant projects
+;;;
+;;; Usage:
+;;;   guix shell -m manifest.scm
+;;;
+
+(specifications->manifest
+  '(;; Core development tools
+    "git"
+    "just"
+    "nickel"
+    "curl"
+    "bash"
+    "coreutils"
+
+    ;; Documentation
+    "asciidoctor"
+    "pandoc"
+
+    ;; Common build dependencies
+    "openssl"
+    "zlib"
+    "pkg-config"))
diff --git a/mozilla-extension/.github/workflows/casket-pages.yml b/mozilla-extension/.github/workflows/casket-pages.yml
index f6d4979..32c256f 100644
--- a/mozilla-extension/.github/workflows/casket-pages.yml
+++ b/mozilla-extension/.github/workflows/casket-pages.yml
@@ -1,39 +1,33 @@
 # SPDX-License-Identifier: MPL-2.0
 name: GitHub Pages
-
 on:
   push:
     branches: [main]
   workflow_dispatch:
-
 permissions:
   contents: read
   pages: write
   id-token: write
-
 concurrency:
   group: "pages"
   cancel-in-progress: false
-
 jobs:
   build:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     steps:
       - name: Checkout
         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
-
       - name: Checkout casket-ssg
         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
         with:
           repository: hyperpolymath/casket-ssg
           path: .casket-ssg
-
       - name: Setup GHCup
         uses: haskell-actions/setup@ec49483bfc012387b227434aba94f59a6ecd0900 # v2
         with:
           ghc-version: '9.8.2'
           cabal-version: '3.10'
-
       - name: Cache Cabal
         uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
         with:
@@ -42,11 +36,9 @@ jobs:
             ~/.cabal/store
             .casket-ssg/dist-newstyle
           key: ${{ runner.os }}-casket-${{ hashFiles('.casket-ssg/casket-ssg.cabal') }}
-
       - name: Build casket-ssg
         working-directory: .casket-ssg
         run: cabal build
-
       - name: Build site
         run: |
           mkdir -p site _site
@@ -77,20 +69,18 @@ jobs:
             fi
           fi
           cd .casket-ssg && cabal run casket-ssg -- build ../site ../_site
-
       - name: Setup Pages
         uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
-
       - name: Upload artifact
         uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
         with:
           path: '_site'
-
   deploy:
     environment:
       name: github-pages
       url: ${{ steps.deployment.outputs.page_url }}
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     needs: build
     steps:
       - name: Deploy to GitHub Pages
diff --git a/mozilla-extension/.github/workflows/codeql.yml b/mozilla-extension/.github/workflows/codeql.yml
index b317db1..c9b0575 100644
--- a/mozilla-extension/.github/workflows/codeql.yml
+++ b/mozilla-extension/.github/workflows/codeql.yml
@@ -1,6 +1,5 @@
-# SPDX-License-Identifier: MPL-2.0
+# SPDX-License-Identifier: MPL-2.0-or-later
 name: CodeQL Security Analysis
-
 on:
   push:
     branches: [main, master]
@@ -8,12 +7,11 @@ on:
     branches: [main, master]
   schedule:
     - cron: '0 6 * * 1'
-
 permissions: read-all
-
 jobs:
   analyze:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       contents: read
       security-events: write
@@ -23,17 +21,14 @@ jobs:
         include:
           - language: javascript-typescript
             build-mode: none
-
     steps:
       - name: Checkout
         uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
-
       - name: Initialize CodeQL
         uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.28.1
         with:
           languages: ${{ matrix.language }}
           build-mode: ${{ matrix.build-mode }}
-
       - name: Perform CodeQL Analysis
         uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.28.1
         with:
diff --git a/mozilla-extension/.github/workflows/governance.yml b/mozilla-extension/.github/workflows/governance.yml
index b0b1ed6..60e8e90 100644
--- a/mozilla-extension/.github/workflows/governance.yml
+++ b/mozilla-extension/.github/workflows/governance.yml
@@ -11,16 +11,14 @@
 # (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing).
 
 name: Governance
-
 on:
   push:
     branches: [main, master]
   pull_request:
   workflow_dispatch:
-
 permissions:
   contents: read
-
 jobs:
   governance:
-    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@main
+    uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613
+    timeout-minutes: 10
diff --git a/mozilla-extension/.github/workflows/hypatia-scan.yml b/mozilla-extension/.github/workflows/hypatia-scan.yml
index 5b59919..c3cb66b 100644
--- a/mozilla-extension/.github/workflows/hypatia-scan.yml
+++ b/mozilla-extension/.github/workflows/hypatia-scan.yml
@@ -1,41 +1,35 @@
 # SPDX-License-Identifier: MPL-2.0
 # Hypatia Neurosymbolic CI/CD Security Scan
 name: Hypatia Security Scan
-
 on:
   push:
-    branches: [ main, master, develop ]
+    branches: [main, master, develop]
   pull_request:
-    branches: [ main, master ]
+    branches: [main, master]
   schedule:
-    - cron: '0 0 * * 0'  # Weekly on Sunday
+    - cron: '0 0 * * 0' # Weekly on Sunday
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   scan:
     name: Hypatia Neurosymbolic Analysis
     runs-on: ubuntu-latest
-
+    timeout-minutes: 15
     steps:
       - name: Checkout repository
         uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
         with:
-          fetch-depth: 0  # Full history for better pattern analysis
-
+          fetch-depth: 0 # Full history for better pattern analysis
       - name: Setup Elixir for Hypatia scanner
         uses: erlef/setup-beam@2f0cc07b4b9bea248ae098aba9e1a8a1de5ec24c # v1.18.2
         with:
           elixir-version: '1.19.4'
           otp-version: '28.3'
-
       - name: Clone Hypatia
         run: |
           if [ ! -d "$HOME/hypatia" ]; then
             git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
           fi
-
       - name: Build Hypatia scanner (if needed)
         working-directory: ${{ env.HOME }}/hypatia
         run: |
@@ -46,7 +40,6 @@ jobs:
             mix escript.build
             mv hypatia ../hypatia-v2
           fi
-
       - name: Run Hypatia scan
         id: scan
         run: |
@@ -73,35 +66,19 @@ jobs:
           echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
           echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
           echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
-
       - name: Upload findings artifact
         uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
         with:
           name: hypatia-findings
           path: hypatia-findings.json
           retention-days: 90
-
       - name: Submit findings to gitbot-fleet (Phase 2)
         if: steps.scan.outputs.findings_count > 0
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           GITHUB_REPOSITORY: ${{ github.repository }}
           GITHUB_SHA: ${{ github.sha }}
-        run: |
-          echo "📤 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet..."
-
-          # Clone gitbot-fleet to temp directory
-          FLEET_DIR="/tmp/gitbot-fleet-$$"
-          git clone https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"
-
-          # Run submission script
-          bash "$FLEET_DIR/scripts/submit-finding.sh" hypatia-findings.json
-
-          # Cleanup
-          rm -rf "$FLEET_DIR"
-
-          echo "✅ Finding submission complete"
-
+        run: "echo \"\U0001F4E4 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet...\"\n\n# Clone gitbot-fleet to temp directory\nFLEET_DIR=\"/tmp/gitbot-fleet-$$\"\ngit clone https://github.com/hyperpolymath/gitbot-fleet.git \"$FLEET_DIR\"\n\n# Run submission script\nbash \"$FLEET_DIR/scripts/submit-finding.sh\" hypatia-findings.json\n\n# Cleanup\nrm -rf \"$FLEET_DIR\"\n\necho \"✅ Finding submission complete\"\n"
       - name: Check for critical issues
         if: steps.scan.outputs.critical > 0
         run: |
@@ -109,7 +86,6 @@ jobs:
           echo "Review hypatia-findings.json for details"
           # Don't fail the build yet - just warn
           # exit 1
-
       - name: Generate scan report
         run: |
           cat << EOF > hypatia-report.md
@@ -143,37 +119,8 @@ jobs:
           EOF
 
           cat hypatia-report.md >> $GITHUB_STEP_SUMMARY
-
       - name: Comment on PR with findings
         if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
         uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
         with:
-          script: |
-            const fs = require('fs');
-            const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));
-
-            const critical = findings.filter(f => f.severity === 'critical').length;
-            const high = findings.filter(f => f.severity === 'high').length;
-
-            let comment = `## 🔍 Hypatia Security Scan\n\n`;
-            comment += `**Findings:** ${findings.length} issues detected\n\n`;
-            comment += `| Severity | Count |\n|----------|-------|\n`;
-            comment += `| 🔴 Critical | ${critical} |\n`;
-            comment += `| 🟠 High | ${high} |\n`;
-            comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;
-
-            if (critical > 0) {
-              comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
-            }
-
-            comment += `<details><summary>View findings</summary>\n\n`;
-            comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
-            comment += `</details>\n\n`;
-            comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;
-
-            github.rest.issues.createComment({
-              owner: context.repo.owner,
-              repo: context.repo.repo,
-              issue_number: context.issue.number,
-              body: comment
-            });
+          script: "const fs = require('fs');\nconst findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));\n\nconst critical = findings.filter(f => f.severity === 'critical').length;\nconst high = findings.filter(f => f.severity === 'high').length;\n\nlet comment = `## \U0001F50D Hypatia Security Scan\\n\\n`;\ncomment += `**Findings:** ${findings.length} issues detected\\n\\n`;\ncomment += `| Severity | Count |\\n|----------|-------|\\n`;\ncomment += `| \U0001F534 Critical | ${critical} |\\n`;\ncomment += `| \U0001F7E0 High | ${high} |\\n`;\ncomment += `| \U0001F7E1 Medium | ${findings.length - critical - high} |\\n\\n`;\n\nif (critical > 0) {\n  comment += `⚠️ **Action Required:** Critical security issues found!\\n\\n`;\n}\n\ncomment += `<details><summary>View findings</summary>\\n\\n`;\ncomment += `\\`\\`\\`json\\n${JSON.stringify(findings.slice(0, 10), null, 2)}\\n\\`\\`\\`\\n`;\ncomment += `</details>\\n\\n`;\ncomment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;\n\ngithub.rest.issues.createComment({\n  owner: context.repo.owner,\n  repo: context.repo.repo,\n  issue_number: context.issue.number,\n  body: comment\n});\n"
diff --git a/mozilla-extension/.github/workflows/scorecard.yml b/mozilla-extension/.github/workflows/scorecard.yml
index d50c271..4dd3b73 100644
--- a/mozilla-extension/.github/workflows/scorecard.yml
+++ b/mozilla-extension/.github/workflows/scorecard.yml
@@ -6,12 +6,11 @@ on:
   schedule:
     - cron: '0 4 * * *'
   workflow_dispatch:
-
 permissions: read-all
-
 jobs:
   analysis:
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       security-events: write
       id-token: write
@@ -19,13 +18,11 @@ jobs:
       - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
           persist-credentials: false
-
       - name: Run Scorecard
         uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.3.1
         with:
           results_file: results.sarif
           results_format: sarif
-
       - name: Upload results
         uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.31.8
         with:
diff --git a/mozilla-extension/ABI-FFI-README.md b/mozilla-extension/ABI-FFI-README.md
index 08d35da..cf73490 100644
--- a/mozilla-extension/ABI-FFI-README.md
+++ b/mozilla-extension/ABI-FFI-README.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 {{~ Aditionally delete this line and fill out the template below ~}}
 
 # {{PROJECT}} ABI/FFI Documentation
diff --git a/mozilla-extension/CODE_OF_CONDUCT.md b/mozilla-extension/CODE_OF_CONDUCT.md
index 2777a72..9142f2a 100644
--- a/mozilla-extension/CODE_OF_CONDUCT.md
+++ b/mozilla-extension/CODE_OF_CONDUCT.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Code of Conduct
 
 <!-- 
diff --git a/mozilla-extension/CONTRIBUTING.md b/mozilla-extension/CONTRIBUTING.md
index b39b3f7..455e511 100644
--- a/mozilla-extension/CONTRIBUTING.md
+++ b/mozilla-extension/CONTRIBUTING.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Clone the repository
 git clone https://{{FORGE}}/{{OWNER}}/{{REPO}}.git
 cd {{REPO}}
diff --git a/mozilla-extension/MAINTAINERS.adoc b/mozilla-extension/MAINTAINERS.adoc
index 48d9781..becaa3e 100644
--- a/mozilla-extension/MAINTAINERS.adoc
+++ b/mozilla-extension/MAINTAINERS.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Maintainers
 :toc: preamble
 
diff --git a/mozilla-extension/README.adoc b/mozilla-extension/README.adoc
index 5ee2d6e..1c4f28f 100644
--- a/mozilla-extension/README.adoc
+++ b/mozilla-extension/README.adoc
@@ -1,10 +1,10 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
-
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 == License & Philosophy
 
 This project must declare **MPL-2.0-or-later** for platform/tooling compatibility.
 
-Philosophy: **Palimpsest**. The Palimpsest-MPL (PMPL) text is provided in `license/PMPL-1.0.txt`, and the canonical source is the palimpsest-license repository.
+Philosophy: **Palimpsest**. The MPL-2.0 (PMPL) text is provided in `license/MPL-2.0.txt`, and the canonical source is the palimpsest-license repository.
 = Claude for Mozilla
 :toc:
 :icons: font
@@ -110,7 +110,7 @@ Access settings via the gear icon in the sidebar:
 
 == License
 
-PMPL-1.0-or-later
+MPL-2.0-or-later
 
 This is an independent project and is not affiliated with Anthropic.
 Claude is a trademark of Anthropic, PBC.
diff --git a/mozilla-extension/ROADMAP.adoc b/mozilla-extension/ROADMAP.adoc
index d8e1687..128ed39 100644
--- a/mozilla-extension/ROADMAP.adoc
+++ b/mozilla-extension/ROADMAP.adoc
@@ -1,4 +1,5 @@
-// SPDX-License-Identifier: CC-BY-SA-4.0
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = YOUR Template Repo Roadmap
 
 == Current Status
diff --git a/mozilla-extension/RSR_OUTLINE.adoc b/mozilla-extension/RSR_OUTLINE.adoc
index 8a22906..6baed3c 100644
--- a/mozilla-extension/RSR_OUTLINE.adoc
+++ b/mozilla-extension/RSR_OUTLINE.adoc
@@ -1,6 +1,8 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = RSR Template Repository
 
-image:[Palimpsest-MPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
+image:[MPL-2.0-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"]
 :toc:
 :sectnums:
 
@@ -209,7 +211,7 @@ This template is part of:
 
 == License
 
-SPDX-License-Identifier: CC-BY-SA-4.0
+SPDX-License-Identifier: MPL-2.0-or-later
 
 == Links
 
diff --git a/mozilla-extension/SECURITY.md b/mozilla-extension/SECURITY.md
index 7dd7b29..09fc7b8 100644
--- a/mozilla-extension/SECURITY.md
+++ b/mozilla-extension/SECURITY.md
@@ -1,3 +1,7 @@
+<!--
+SPDX-License-Identifier: MPL-2.0
+Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
+-->
 # Security Policy
 
 <!-- 
diff --git a/mozilla-extension/ai-cli-crash-capture/README.adoc b/mozilla-extension/ai-cli-crash-capture/README.adoc
index 2fcda87..689b158 100644
--- a/mozilla-extension/ai-cli-crash-capture/README.adoc
+++ b/mozilla-extension/ai-cli-crash-capture/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = AI CLI Crash Capture
 :revdate: 2026-01-17
 
diff --git a/mozilla-extension/contractiles/README.adoc b/mozilla-extension/contractiles/README.adoc
index d19a387..70ad712 100644
--- a/mozilla-extension/contractiles/README.adoc
+++ b/mozilla-extension/contractiles/README.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = Contractiles Template Set
 :toc:
 :sectnums:
diff --git a/mozilla-extension/docs/CITATIONS.adoc b/mozilla-extension/docs/CITATIONS.adoc
index 564f0ae..52ba528 100644
--- a/mozilla-extension/docs/CITATIONS.adoc
+++ b/mozilla-extension/docs/CITATIONS.adoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 = RSR-template-repo - Citation Guide
 :toc:
 
@@ -10,7 +12,7 @@
   title = {RSR-template-repo},
   year = {2025},
   url = {https://github.com/hyperpolymath/RSR-template-repo},
-  license = {AGPL-3.0-or-later}
+  license = {MPL-2.0}
 }
 ----
 
diff --git a/mozilla-extension/src/background/background.js b/mozilla-extension/src/background/background.js
index acec843..e8414d9 100644
--- a/mozilla-extension/src/background/background.js
+++ b/mozilla-extension/src/background/background.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Background script for Claude Mozilla Extension
 
 // Handle extension icon click - open sidebar
diff --git a/mozilla-extension/src/core/api.js b/mozilla-extension/src/core/api.js
index bbdc904..985aa47 100644
--- a/mozilla-extension/src/core/api.js
+++ b/mozilla-extension/src/core/api.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Claude API client for Mozilla extension
 
 const CLAUDE_API_URL = 'https://api.anthropic.com/v1/messages';
diff --git a/mozilla-extension/src/core/storage.js b/mozilla-extension/src/core/storage.js
index d445d2d..49d3172 100644
--- a/mozilla-extension/src/core/storage.js
+++ b/mozilla-extension/src/core/storage.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Storage utilities for Mozilla extension
 
 const STORAGE_KEYS = {
diff --git a/mozilla-extension/src/ui/sidebar.js b/mozilla-extension/src/ui/sidebar.js
index c8ee7ce..683eb04 100644
--- a/mozilla-extension/src/ui/sidebar.js
+++ b/mozilla-extension/src/ui/sidebar.js
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: MPL-2.0
+// Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
 // Sidebar UI logic for Claude Mozilla Extension
 
 document.addEventListener('DOMContentLoaded', init);
@@ -143,7 +144,10 @@ function startNewConversation() {
 
 function renderMessages() {
   const container = document.getElementById('messages');
-  container.innerHTML = '';
+  // Clear container safely
+  while (container.firstChild) {
+    container.removeChild(container.firstChild);
+  }
 
   for (const msg of messages) {
     const div = document.createElement('div');
@@ -172,7 +176,11 @@ function showTypingIndicator() {
   const indicator = document.createElement('div');
   indicator.className = 'message assistant typing-indicator';
   indicator.id = 'typing';
-  indicator.innerHTML = '<span></span><span></span><span></span>';
+  // Create typing indicator spans safely
+  for (let i = 0; i < 3; i++) {
+    const span = document.createElement('span');
+    indicator.appendChild(span);
+  }
   container.appendChild(indicator);
   container.scrollTop = container.scrollHeight;
 }
