license-compliance-borrow-check
When to use
- Before adapting, porting, or otherwise consciously reusing an algorithm, a non-trivial structure, or more than roughly ten lines of logic shape from a source you can name (a repo, a gist, a Stack Overflow answer).
- The
code-provenancerule fired and its step 3 ("check license compatibility") needs a concrete answer. - A reviewer or the
origin: uncertainself-flag surfaces a borrow that was never checked.
Do NOT use when:
- No conscious borrow happened — a well-known, unpatentable algorithm shape (a for-loop, a hash map) implemented with no specific source in mind.
- The borrow is already ledgered with a valid entry — use
license-compliance-creditsto regenerate notices instead. - You want a broad similarity scan across the repo, not one source — use
license-compliance-audit.
A passing verdict is not a copying clearance
This skill answers ONE question: is the source's license compatible with
this repo's license, under the derived compatibility policy? An allow
verdict means the license permits the reuse — it says nothing about whether
the code-provenance discipline (read,
close the source, re-derive against house standards) was actually followed.
License-clean code that is still a verbatim copy is still a violation of
that rule. Run both checks; treat neither as a substitute for the other.
Procedure
- Identify the source — the URL or repo path being borrowed from, and
the exact commit or blob SHA the snippet was taken from (
git log -1 --format=%H -- <path>on the source repo, or the URL's own commit ref). - Detect the source's license. Check, in order: a
LICENSE/LICENSE.md/COPYINGfile at the source repo root; the source'spackage.json"license"field; itscomposer.json"license"field; an SPDX header comment in the file itself. If none resolve to a known SPDX id, the license isunknown— never guess permissive. - Detect this repo's target policy. Run:
Ifnpx tsx node_modules/@event4u/agent-config/src/scripts/detect_target_license.ts . --jsonlicense-policy.yamlexists at the repo root, read itspolicy.{allow,conditional,deny}buckets directly. If it does not (dry run only), derive the same buckets by hand from this repo's ownLICENSEfile and the compatibility matrix innode_modules/@event4u/agent-config/src/scripts/_lib/detect_target_license.ts(COMPATIBILITY_MATRIX/classifyBorrow). - Classify the borrow. Map the source's SPDX id to its source class
(permissive / weak-copyleft / gpl-2.0 / gpl-3.0 / agpl / sspl /
unknown), then read the verdict off the target's policy buckets:allow,conditional(escalate), ordeny. A source license ofunknownis alwaysdeny— no exception. - Act on the verdict:
allow→ continue to step 6 (draft the ledger entry).conditional→ STOP. Do not write the borrowed code yet. Escalate to the user with the exact matrix cell that triggered it (perask-when-uncertain) — never auto-clear a conditional verdict.deny→ refuse the borrow. Name the alternative: write it from scratch, find a permissively-licensed equivalent, or ask the maintainer for an explicit, recorded exception.
- Draft the ledger entry — one JSON object matching
node_modules/@event4u/agent-config/src/scripts/schemas/provenance-borrow.schema.json(source_url,license,source_sha,borrowed_at,files,transformation_note,cleared_by). Write atransformation_notethat names a real structural change — rename-only phrasing (e.g. "renamed variables", "cosmetic rename") is rejected bylint_provenance.tseven if the code has not landed yet, so draft it honestly against what will actually change. - Present the draft to the user before appending it. Once the
re-derived code lands, append the confirmed entry to
provenance/borrows.jsonland verify:
Exit 0 confirms the entry is schema-valid, license-compliant, and its transformation note passed the rename-only phrase check.npx tsx node_modules/@event4u/agent-config/src/scripts/lint_provenance.ts
Output format
- The classification verdict (
allow/conditional/deny) with the exact source class → target class cell that produced it, and the source license's SPDX id (orunknown). - The draft ledger entry as a fenced JSON block, ready to append verbatim once the user confirms it.
- For
conditionalordeny, the specific escalation question or refusal reason presented to the user — never a silently auto-resolved verdict.
Gotcha
allowis not a copying clearance — see the section above; runcode-provenance's read-close-re-derive discipline regardless of the license verdict.- No
LICENSEfile at the source is not "no license, so it's free" — an absent license file defaults to strictest (unknown→deny), not to permissive. - A
conditionalverdict is not a soft "probably fine" — it is a hard stop pending human escalation; treating it as advisory is the exact Q1 workspace-license failure mode the roadmap's council resolved against. license-policy.yamlmissing does not mean skip the check — derive the policy by hand from the matrix; a missing policy file is a detection gap, not a green light.
Do NOT
- NEVER append a ledger entry without presenting the draft to the user first.
- NEVER treat an undetectable license as permissive —
unknownfails the linter outright and must escalate. - NEVER let a
conditionalverdict proceed without the escalation actually happening this turn. - NEVER write a
transformation_notethat only describes a rename or formatting change — describe the real structural change, or don't borrow.
See also
code-provenance— the rule this skill answers step 3 of.license-compliance-credits— regeneratesdocs/THIRD-PARTY-NOTICES.mdonce the entry lands.license-compliance-audit— the on-demand similarity scan for suspicious diffs, not for a single known source.node_modules/@event4u/agent-config/src/scripts/detect_target_license.ts,node_modules/@event4u/agent-config/src/scripts/_lib/detect_target_license.ts— the license-policy derivation this skill consumes.node_modules/@event4u/agent-config/src/scripts/lint_provenance.ts,provenance/README.md,node_modules/@event4u/agent-config/src/scripts/schemas/provenance-borrow.schema.json— the ledger + its contract.ask-when-uncertain— the escalation shape forconditional/unknownverdicts.