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:
51
openspec/changes/license-debt-mit/proposal.md
Normal file
51
openspec/changes/license-debt-mit/proposal.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# License-debt — relicense AGPL-3.0 → MIT
|
||||
|
||||
**Status:** in progress (started 2026-06-01)
|
||||
**Decision:** Sam, 2026-05-31 — relicense BooCode back to MIT.
|
||||
**Source:** `boocode_code_review_v2.md` §1 #1, §5k; roadmap `## License-debt` batch.
|
||||
|
||||
## Why
|
||||
|
||||
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 three AGPL-3.0-only files. BooCode is network-served, so
|
||||
AGPL §13 network-copyleft is a live liability. Clearing the three files makes the MIT flip
|
||||
valid; nothing else AGPL remains once they are gone.
|
||||
|
||||
## Core insight (supersedes the roadmap's staged steps)
|
||||
|
||||
The roadmap entangled the relicense with retiring `tool-call-parser.ts` behind a live
|
||||
qwen3.6 validation window. That is **not necessary**: the Unsloth-ported algorithm
|
||||
(`parseToolCallsFromText` / `scanBalancedBraces` + unused constants) is **dead code** —
|
||||
no production consumer imports it (verified: only the file and its test reference it). The
|
||||
load-bearing parser (`extractToolCallBlocks`, under the file's own "BooCode streaming
|
||||
helpers" banner) and `stripToolMarkup` are BooCode-authored. So the relicense **strips
|
||||
provenance, not capability** — zero behavior change, no validation gate. The
|
||||
native-llama-server-parsing retirement remains a separate, optional future optimization.
|
||||
|
||||
## The three AGPL-3.0-only files to clear
|
||||
|
||||
1. `apps/server/src/services/web/html-to-md.ts` (← `_html_to_md.py`) — **swap** to
|
||||
`node-html-markdown` (MIT). A different third-party library, not a rewrite-from-memory
|
||||
(which would still be a derivative). Consumed by `web_fetch` via `web/index.ts`;
|
||||
`htmlToMarkdown(html): string` signature preserved.
|
||||
2. `apps/server/src/services/inference/llama-args-validator.ts` (← `llama_server_args.py`)
|
||||
— **clean-room** re-derive the flag denylist from the public llama-server README (CLI
|
||||
flag names are facts, not copyrightable); the shadowing logic is already BooCode's own.
|
||||
3. `apps/server/src/services/inference/tool-call-parser.ts` (← `tool_call_parser.py`) —
|
||||
**delete** the dead Unsloth-ported code; keep BooCode's streaming helpers +
|
||||
`stripToolMarkup` (re-derive its strip regexes from qwen's wire format); drop the header.
|
||||
No change to the live tool-call path.
|
||||
|
||||
## Decisions (Sam, 2026-06-01)
|
||||
|
||||
- html-to-md library: **node-html-markdown** (single MIT dep, GFM tables built-in).
|
||||
- tool-call-parser: **relicense-only** — defer native-parsing retirement.
|
||||
- MIT copyright line: **`Copyright (c) 2026 indifferentketchup`**.
|
||||
- Leave `boocode_code_review*.md` (point-in-time snapshots) untouched; update the roadmap
|
||||
batch (planned → shipped) and add a README License section.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Retiring `tool-call-parser` patterns 1 & 2 in favour of native llama-server parsing.
|
||||
- Bumping the stale README "Latest release" line / AGENTS.md pointer.
|
||||
51
openspec/changes/license-debt-mit/tasks.md
Normal file
51
openspec/changes/license-debt-mit/tasks.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Tasks — relicense AGPL-3.0 → MIT
|
||||
|
||||
Four units. A/B/C are disjoint files (parallelizable); D is the join (runs after A/B/C).
|
||||
The shared `node-html-markdown` dependency swap + `pnpm install` is done before A so the
|
||||
parallel agents don't race on `apps/server/package.json`.
|
||||
|
||||
## Pre: dependency swap (done by coordinator)
|
||||
- [ ] Add `node-html-markdown` to `apps/server/package.json` dependencies; remove `parse5`
|
||||
(only html-to-md consumed it).
|
||||
- [ ] `pnpm install`.
|
||||
|
||||
## A — html-to-md → node-html-markdown
|
||||
- [ ] Replace `apps/server/src/services/web/html-to-md.ts` with a thin MIT wrapper exporting
|
||||
`htmlToMarkdown(sourceHtml: string): string` over `NodeHtmlMarkdown.translate`.
|
||||
- [ ] Drop the AGPL/Unsloth SPDX header.
|
||||
- [ ] Update `html-to-md.test.ts` to the new library's output (structure-level `.toContain`
|
||||
where whitespace differs; output feeds an LLM so exact format is not load-bearing).
|
||||
- [ ] Keep `web/index.ts` re-export and `web_fetch.ts` untouched.
|
||||
|
||||
## B — llama-args-validator → clean-room
|
||||
- [ ] Rewrite `apps/server/src/services/inference/llama-args-validator.ts`: re-derive the
|
||||
managed-flag denylist from the public llama-server README; keep the BooCode
|
||||
shadowing-flag logic. Same exports (`validateExtraArgs`, `isManagedFlag`,
|
||||
`stripShadowingFlags`, `StripOptions`).
|
||||
- [ ] Drop the AGPL/Unsloth SPDX header.
|
||||
- [ ] Keep `llama-args-validator.test.ts` green (it pins the contract).
|
||||
|
||||
## C — tool-call-parser → minimal clean (relicense-only)
|
||||
- [ ] Delete dead Unsloth-ported exports: `parseToolCallsFromText`, `scanBalancedBraces`,
|
||||
`OpenAiToolCall`, `hasToolSignal`, and the unused nudge constants
|
||||
(`DUPLICATE_CALL_NUDGE`, `TOOL_ERROR_NUDGE`, `TOOL_ERROR_PREFIXES`,
|
||||
`BUDGET_EXHAUSTED_NUDGE`).
|
||||
- [ ] Keep `extractToolCallBlocks` + streaming helpers + `stripToolMarkup` (re-derive its
|
||||
strip regexes from qwen's wire format). Drop the AGPL/Unsloth SPDX header.
|
||||
- [ ] Remove the now-dead tests from `tool-call-parser.test.ts`; keep streaming/strip tests.
|
||||
- [ ] Verify `stream-phase.ts` (`extractToolCallBlocks`) + `tool-phase.ts` / `error-handler.ts`
|
||||
(`stripToolMarkup`) still compile.
|
||||
|
||||
## D — license flip (join)
|
||||
- [ ] `LICENSE`: replace AGPL-3.0 text with MIT, `Copyright (c) 2026 indifferentketchup`.
|
||||
- [ ] Flip `"license"` to `"MIT"` in all 5 `package.json` (root, server, web, coder, booterm).
|
||||
- [ ] Confirm no `SPDX-License-Identifier: AGPL` header survives in the 3 files.
|
||||
- [ ] Roadmap `License-debt` batch: planned → shipped (note the decoupled-from-parser-retirement
|
||||
approach). Add a `## License` section to `README.md` (MIT).
|
||||
- [ ] Optional guard test: assert no `AGPL` SPDX header in `apps/**` and all 5 `package.json`
|
||||
are MIT.
|
||||
|
||||
## Verify
|
||||
- [ ] `pnpm -C apps/server test`
|
||||
- [ ] `pnpm -C apps/server build`
|
||||
- [ ] root `npx tsc --noEmit`
|
||||
Reference in New Issue
Block a user