feat: relicense AGPL-3.0 → MIT (v2.7.0)

Clear the 3 Unsloth-Studio-derived AGPL files and flip LICENSE + 5
package.json from AGPL-3.0-only to MIT.

- html-to-md.ts → MIT node-html-markdown (parse5 dropped)
- llama-args-validator.ts → clean-room (flag denylist = facts)
- tool-call-parser.ts → delete dead Unsloth-ported code; keep
  extractToolCallBlocks/stripToolMarkup byte-identical (no behavior change)
- LICENSE → MIT (Copyright (c) 2026 indifferentketchup); 5 package.json → MIT;
  AGPL SPDX headers removed; README License section; license-mit guard test
- roadmap License-debt batch marked shipped; openspec/changes/license-debt-mit

Decouples the relicense from the native-parsing retirement (the ported parser
was dead code). Server suite 519 passing; build + coder typecheck clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-01 08:16:03 +00:00
parent 9c1ddcaa7c
commit a8bfde8f8d
18 changed files with 499 additions and 1566 deletions

View File

@@ -447,24 +447,22 @@ All tags `vMAJOR.MINOR.PATCH-slug`, monotonic per minor, assigned at ship time (
-----
## License-debt — relicense AGPL-3.0 → MIT (planned)
## License-debt — relicense AGPL-3.0 → MIT (shipped 2026-06-01)
**Status: planned, not started.** Recorded 2026-05-31 from the v2 external review (`boocode_code_review_v2.md` §5k) + a direct tree audit. **Decision (Sam, 2026-05-31): relicense the project back to MIT.**
**Status: SHIPPED 2026-06-01** (openspec `license-debt-mit`). Recorded 2026-05-31 from the v2 external review (`boocode_code_review_v2.md` §5k) + a direct tree audit. **Decision (Sam, 2026-05-31): relicense the project back to MIT.**
**Current state (the problem):** the tree is **currently AGPL-3.0** — root `LICENSE` is GNU Affero GPL v3 and all five `package.json` declare `"license": "AGPL-3.0-only"`. Cause: the `v2.4.0`/`v2.4.1` Unsloth-Studio lifts pulled in AGPL-3.0-only code, which makes the whole network-served work AGPL-encumbered. This batch clears that so the MIT flip is valid; **nothing else AGPL remains once these files are gone.**
**What was the problem:** the tree was AGPL-3.0 — root `LICENSE` was GNU Affero GPL v3 and all five `package.json` declared `"license": "AGPL-3.0-only"`. Cause: the `v2.4.0`/`v2.4.1` Unsloth-Studio lifts pulled in three AGPL-3.0-only files, making the whole network-served work AGPL-encumbered (AGPL §13 network-copyleft). Clearing those three files made the MIT flip valid.
**The three AGPL-3.0-only files to clear** (each `SPDX-License-Identifier: AGPL-3.0-only`, ported from Unsloth Studio):
1. `apps/server/src/services/inference/tool-call-parser.ts` (← `tool_call_parser.py`) — remove by routing tool-call parsing to **native llama-server** template parsing + a **clean-room `<invoke>`-only fallback** (no Unsloth provenance).
2. `apps/server/src/services/web/html-to-md.ts` (← `_html_to_md.py`, used by `web_fetch`) — replace with a permissively-licensed library (`turndown` / `node-html-markdown`) or a clean-room walker.
3. `apps/server/src/services/inference/llama-args-validator.ts` (← `llama_server_args.py`, the v2.4.1 sidecar flag-denylist) — clean-room rewrite from the llama-server README flag list (the denylist is facts, not copyrightable).
**The three AGPL-3.0-only files (cleared):**
1. `apps/server/src/services/inference/tool-call-parser.ts` (← `tool_call_parser.py`) — the Unsloth-ported algorithm (`parseToolCallsFromText`/`scanBalancedBraces` + unused nudge constants) was **dead code** (no production import; only the file + its test referenced it). Deleted it. The load-bearing parser (`extractToolCallBlocks` + the BooCode-authored streaming helpers) and `stripToolMarkup` were kept byte-identical and the AGPL header dropped. **No behavior change to the live tool-call path.**
2. `apps/server/src/services/web/html-to-md.ts` (← `_html_to_md.py`, used by `web_fetch`) — **swapped** to the MIT `node-html-markdown` library (a distinct third-party lib, not a rewrite-from-memory); `parse5` dropped. `htmlToMarkdown(html): string` signature preserved.
3. `apps/server/src/services/inference/llama-args-validator.ts` (← `llama_server_args.py`) — **clean-room rewrite** with independent structure; the managed-flag denylist re-derived from the public llama-server flag list (facts, not copyrightable).
**Steps:**
1. Confirm native llama-server tool-parsing on **live qwen3.6** (jinja gate already green — `--jinja` + qwen3.x template live; llama.cpp server-side template parser, v2 review §4a).
2. Run native parsing **behind a flag for one release** (qwen3.6 was historically unreliable — validate before deleting).
3. **Delete** the ~250 Unsloth-derived parser lines + clean-room the `<invoke>` fallback; replace `html-to-md.ts`; clean-room `llama-args-validator.ts`.
4. **Flip the license:** root `LICENSE` AGPL→MIT, the five `package.json` `license` fields `AGPL-3.0-only``MIT`, remove the per-file AGPL SPDX headers, and update roadmap/README prose. After this, **no AGPL remains in the tree** and the "BooCode is MIT" claim becomes true.
**Key correction to the original plan:** the native-llama-server-parsing retirement (which would have needed a live qwen3.6 validation window "behind a flag for one release") was **decoupled** from the relicense and proved unnecessary — the ported parser code was already dead, so the relicense stripped *provenance, not capability*. The native-parsing retirement remains a separate, optional future optimization.
**Source:** `boocode_code_review_v2.md` §1 #1, §5k. **Prerequisite for the license flip — this batch is the blocker, not optional.**
**License flip:** root `LICENSE` AGPL→MIT (`Copyright (c) 2026 indifferentketchup`); the five `package.json` `license` fields → `MIT`; AGPL SPDX headers removed from all three files; a `## License` section added to `README.md`; a guard test asserts no AGPL header / SPDX-AGPL survives. The `boocode_code_review*.md` point-in-time snapshots were left as-is. **No AGPL remains in the tree.**
**Source:** `boocode_code_review_v2.md` §1 #1, §5k; openspec `license-debt-mit`.
-----
@@ -708,7 +706,6 @@ Full per-tag detail in the **Shipped (v2.2.2v2.6.6)** section above and in `C
### In flight
- **License-debt → relicense AGPL-3.0 → MIT** — see the planned batch above; the tree is currently AGPL-3.0 and three Unsloth-derived files must be cleared before the MIT flip. Prerequisite, blocker-status.
- **v2.6 persistent agent sessions — Phase 2/3** — warm ACP backend for goose/qwen (persistent process reused across turns) + lifecycle hardening (idle eviction, crash recovery, worktree cleanup/reaper, post-apply re-baseline) + the Phase-1 UX attribution work (DiffPanel agent badges, resumed/new-session chip). See openspec `v2-6-persistent-agent-sessions/tasks.md`.
### Numbering and scope-revision discipline during v1.13.x (2026-05-23)