Completes the For-Claude-Web bundle licence migration. All 16 in-scope
files (Maintenance_Guide done in 5c386d0d + 15 here) now reference
EUPL-1.2. CLAUDE_WEB_BRIEF.md:250 "MIT or Apache license" preserved per
plan — historical project context, not an active claim.
31 token swaps applied via throwaway script + 2 full-block rewrites:
Token swaps (longest-first pattern order for atomicity):
#1. Full Apache preamble paragraph (3 paragraphs, header + URL + AS-IS
body) -> EUPL-1.2 equivalent. Normalises "License" -> "Licence"
across the body in one pass so the paragraph is internally
consistent (British spelling per EUPL official style). Applied to
12 files.
#2. "Apache License, Version 2.0, January 2004" -> "European Union
Public Licence, Version 1.2" (2 files).
#3. "Apache License, Version 2.0 (the \"License\")" variant -> EUPL
variant (covered by #1; fallback for non-preamble contexts).
#4. "Apache License, Version 2.0" -> "European Union Public Licence,
Version 1.2 (EUPL-1.2)" (non-preamble fallback).
#5. "Apache License 2.0" -> "European Union Public Licence, v. 1.2
(EUPL-1.2)" (1 file, 27027-incident "**License:** Apache License
2.0").
#6. "Apache 2.0 license" -> "EUPL-1.2 licence" (7 files x 2 each =
14 hits; all in "Additional Terms" boilerplate).
#7. "Apache 2.0 License" -> "EUPL-1.2 License" (1 file, roadmap
"**Apache 2.0 License**").
#8. "http://www.apache.org/licenses/LICENSE-2.0" -> EUPL URL
(covered by #1).
#9. "Apache 2.0" bare -> "EUPL-1.2" (1 file,
claude-code-framework-enforcement "**License**: Apache 2.0").
Full-block rewrites (technical-architecture.md, implementation-guide.md):
Both files embedded the ~55-line Apache TERMS AND CONDITIONS text
verbatim (lines 648-703 / 893-948 pre-rewrite). Simple token-swap
would have produced mislabelled "EUPL-1.2" header with Apache-specific
TERMS body below. Replaced entire block with:
**Full Licence Text:**
For the full EUPL-1.2 licence text, see:
https://interoperable-europe.ec.europa.eu/collection/eupl/eupl-text-eupl-12
The EUPL-1.2 is available in 23 official EU-language versions at
the same source.
Matches Phase A precedent (root LICENSE file c85f310f references the
canonical EUPL source rather than embedding verbatim).
Vendor-policy note (intentionally DEFERRED per plan):
"**GitHub:** https://github.com/AgenticGovernance/tractatus-framework"
references in technical-architecture L719 and similar elsewhere
are GitHub->Codeberg cleanup, tracked as a separate broader sweep.
Not bundled into this licence commit.
Commit 4/5 in the revised sequence. Plan: community repo
docs/plans/PLAN_TRACTATUS_OUT_OF_SCOPE_HYGIENE_LICENCE_20260420.md
Phase A precedent: c85f310f (root LICENSE + README + source headers)
Phase B precedent: d600f6ed (source-file header sweep)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prepares 13 of 15 plan-scope bundle files for the upcoming Apache -> EUPL-1.2
licence swap. Pre-commit hooks scan whole file content, so prohibited-terms
AND attack-surface exposures must be cleared on every file touched by the
licence edit. Bundles both hygiene concerns into one atomic commit per the
same precedent as db788548 (Maintenance_Guide consolidation for the same
whole-file-scan reason). The other 2 plan-scope files
(business-case-tractatus-framework.md, implementation-guide.md) were already
clean on both checks and will only be touched in the licence-swap commit.
inst_016/017/018 (prohibited terms) — 21 rewrites across 9 files:
- 12 rewrites for "guarantee(s|d)" / "eliminate all" (inst_017), with
context-appropriate substitutes: "enforcement" / "properties" /
"enforces" / "inevitable" / "approaches certainty" / "constrain" /
"establish"
- 4 rewrites for "production-ready" (inst_018): "code under active
maintenance" / "API Stability" / "active component" / "maturity"
- 5 "[NEEDS VERIFICATION]" markers added to uncited stats (inst_016)
per the check script's recommended convention
inst_084 (attack surface) — ~48 redactions across 9 files:
- 42 port swaps via throwaway token-replace script (code-block and
inline-code aware, so shell commands and code samples stay intact):
"port 27017" / "Port 27017" -> "MongoDB default port"
"port 27027" / "Port 27027" -> "non-default project port" /
"Non-default project port"
"on port 27017" -> "on the MongoDB default port"
"on port 27027" -> "on a non-default project port"
- 6 API-endpoint redactions on roadmap-2025.md: backticked and plain
"/docs/api/..." paths replaced with generic descriptors
("the OpenAPI 3.0 specification", "JavaScript examples documentation",
etc.)
Same pedagogical-preservation approach as Phase A commit c85f310f (README
redactions): generic descriptors preserve narrative intent; bare "27027"
and "27017" digits survive where they appear outside the "port \d" token
pattern (section titles, narrative references to the incident number,
incident metrics).
Preserved intentionally (per plan scope):
CLAUDE_WEB_BRIEF.md:250 "MIT or Apache license" — historical context.
All code-block port references (exempted by the attack-surface
validator's removeExemptedSections).
Bare digits outside the "port \d" token pattern.
Commit 3/5 in the revised sequence for the out-of-scope hygiene + licence
sweep. Plan: community repo
docs/plans/PLAN_TRACTATUS_OUT_OF_SCOPE_HYGIENE_LICENCE_20260420.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Flips the "how to add a License section" template block from Apache 2.0
wording to the project's current EUPL-1.2 licence. Now that hygiene commit
db788548 cleared inst_069/070 and inst_084 on both Maintenance_Guide
copies, this licence swap lands atomically on a clean base.
Applied identically to both CLAUDE_Tractatus_Maintenance_Guide.md copies
(root + For Claude Web bundle); 4 edits per file:
L788 prose: "Complete Apache 2.0 license section at end:"
-> "Complete EUPL-1.2 licence section at end:"
L790 heading: "## License" -> "## Licence"
(British spelling matches EUPL official style)
L794 template: "Licensed under the Apache License, Version 2.0
(the \"License\")..."
-> "Licensed under the European Union Public Licence,
Version 1.2 (the \"Licence\")..."
L795 template: "[Full Apache 2.0 text with additional terms]"
-> "[Full EUPL-1.2 text with additional terms]"
Commit 2/5 in the revised sequence for the out-of-scope hygiene + licence
sweep. Plan: community repo
docs/plans/PLAN_TRACTATUS_OUT_OF_SCOPE_HYGIENE_LICENCE_20260420.md
Phase A precedent: c85f310f (LICENSE + README relicense)
Phase B precedent: d600f6ed (source-file header flips)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bundles the plan's commits 1 + 2 into one atomic commit. Pre-commit hook
scans whole file content, so a credential-only commit cannot pass inst_084
while port exposures remain unflipped on the same file. Sibling-concern
bundling matches precedent 4ddc54a0 (README hygiene follow-on to c85f310f).
Applied identically to both CLAUDE_Tractatus_Maintenance_Guide.md copies
(root + For Claude Web bundle):
inst_069/070 — credential-scan false-positive:
L1101 "Password location" -> "Credential reference"
(describes WHERE creds live, not any credential value)
inst_084 — port redactions, 9 distinct line positions per file, using
generic descriptors so the "port \d{4,5}" regex no longer matches:
L40, L63 Port 27017 (MongoDB) -> default MongoDB port / default port
L64 on port 9000 -> on the project HTTP port
L65 Port 9001 (WebSocket) -> the project WebSocket port
L103 "Check port 27027" -> verify a non-default MongoDB port
L104 Used port 27017 -> used the standard default MongoDB port
L1324/1260, L1325/1261 -> (default port) / (project HTTP port)
L1437/1373 summary line -> default port / HTTP port descriptors
Intentionally preserved (non-triggering):
L99 section title "What is a '27027 Failure?'" (bare digits, no "port"
prefix, regex doesn't match)
L41 "Separate application port: 9000" (colon breaks "port\s+\d" regex)
All code-block port refs (exempted by removeExemptedSections())
Revised sequence: commit 1/5 (plan originally 1/6, merged 1+2).
Plan: community repo docs/plans/PLAN_TRACTATUS_OUT_OF_SCOPE_HYGIENE_LICENCE_20260420.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Create Economist SubmissionTracking package correctly:
* mainArticle = full blog post content
* coverLetter = 216-word SIR— letter
* Links to blog post via blogPostId
- Archive 'Letter to The Economist' from blog posts (it's the cover letter)
- Fix date display on article cards (use published_at)
- Target publication already displaying via blue badge
Database changes:
- Make blogPostId optional in SubmissionTracking model
- Economist package ID: 68fa85ae49d4900e7f2ecd83
- Le Monde package ID: 68fa2abd2e6acd5691932150
Next: Enhanced modal with tabs, validation, export
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>