feat(manifest): add fork-identity fields for Phase C / P4 (no forks yet)
Merged
TO
3mo ago+285+285+012345678901234567890123456789-9-9-0123456789
Summary
Tooling-only groundwork for the selective fork policy (P4). Does not fork anything β see numan-registry PR (companion to this one) and docs/adr/0001-... in numan for why real forks are explicitly out of scope here.
validate_manifest.py: optionalupstream_repofield (owner/nameof the original upstream). Requiresowner == "numan-maintained"on any entry that sets it β a fork manifest entry can't claim the original author's identity.gen_spec.py: whenupstream_repois present, emitssource.upstreamin the generated spec (consumed bynuman-registry'sadd-package.py, which now requires it forowner: "numan-maintained") and appends a fork-attribution note to the description.manifest.json:schema_notes.upstream_repodocuments the field and points at ADR 0001 for the eligibility/stewardship requirements this field doesn't itself enforce.
Test plan
-
python -m pytest scripts/β 47 passed -
python scripts/validate_manifest.py --manifest manifest.jsonβ OK, 22 active plugins, unaffected - New tests:
upstream_reporequiresnuman-maintainedowner / accepted with it / rejects blank,gen_spec.pyemitssource.upstream+ description note for fork entries, omits both for normal entries
Ref: numan/docs/plans/2026-08-09-intake-process-reform.md (P4), numan PR #113.
π€ Generated with Claude Code
Summary by cubic
Adds fork identity support for P4 selective forks and hardens manifest/spec validation, including source.upstream and a fork note for valid numan-maintained forks. Tooling-only; no forks created.
-
New Features
- validate_manifest.py: require
upstream_repofor ownernuman-maintained; enforce non-emptyowner/name; reject values equal torepo. - gen_spec.py: for fork entries, emit
source.upstreamand append a fork-attribution note; omit both for non-forks (needed bynuman-registry). - manifest.json: add
schema_notes.upstream_repowith ADR link.
- validate_manifest.py: require
-
Bug Fixes
- gen_spec.py:
build_specvalidatesupstream_repovia the shared helper, rejecting blank, malformed, wrong-owner, or self-referential values before emitting provenance.
- gen_spec.py: