# SPDX-License-Identifier: MPL-2.0
# Metadatastician Transfer Plan
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
#
# Purpose: move private hyperpolymath repos that can tolerate
#          enterprise-internal visibility into The-Metadatastician org,
#          where GitHub Advanced Security (GHAS) coverage is available
#          on the Enterprise plan. Repos remain non-public; they gain
#          code scanning, secret scanning, and dependency review.
#
# Current posture:
#   - The-Metadatastician (login: `The-Metadatastician`) is on Enterprise
#     plan (999999 private repos, 50 seats, 1 filled). Owns 1 private + 2 public.
#   - hyperpolymath org holds 10 private repos (1 archived, 9 active).
#   - User is owner of both orgs (transfer authorisation available).
#
# Irreversibility profile (per `git remote` redirect): GitHub keeps
# old URLs redirecting indefinitely, so SSH/HTTPS refs keep working. BUT:
# CI webhooks that point at the org-name path (rare), hard-coded owner
# references in workflow `uses:` (none for hyperpolymath-authored code),
# and mirror-sync targets may need URL updates.

@abstract:
Transfer plan for the 4 low-sensitivity private hyperpolymath repos that
are good candidates for Metadatastician-internal status (unlocks GHAS).
Four repos explicitly excluded as always-private (007, .git-private-farm,
hyperpolymath-sovereign-registry, blog-drafts). One archived (polystack),
one workspace-root (repos-monorepo) also excluded.
@end

## Inventory — 10 private hyperpolymath repos

[[inventory]]
name = "007"
exclude = true
reason = "always-private per memory: Claude-only language repo, agent meta-language"
last_push = "2026-04-17"

[[inventory]]
name = ".git-private-farm"
exclude = true
reason = "always-private per memory: hookset-sync hub with sensitive manifest data"
last_push = "2026-04-16"

[[inventory]]
name = "hyperpolymath-sovereign-registry"
exclude = true
reason = "always-private per memory: sovereign registry; decisional/governance content"
last_push = "2026-04-17"

[[inventory]]
name = "blog-drafts"
exclude = true
reason = "always-private per memory: unpublished blog drafts; premature disclosure risk"
last_push = "2026-04-17"

[[inventory]]
name = "polystack"
exclude = true
reason = "archived; superseded by boj-server. No ongoing security-signal value from transfer."
last_push = "2026-04-04"

[[inventory]]
name = "repos-monorepo"
exclude = true
reason = "Eclipse-drive workspace-root wrapper; submodule pointer tracker. Transferring changes origin for every submodule consumer. Too high-blast for this pass."
last_push = "2026-04-17"
review_next_pass = true

[[inventory]]
name = "ipv6-only"
exclude = false
candidate = true
size_kb = 45138
description = "IPv6-only network profile tool (aerie/network). Dual-use with ambientops subset."
last_push = "2026-04-17"
rationale = "Already positioned as dual-use with a public subset downstream. Low-sensitivity code. Size ~45MB suggests real content worth scanning."

[[inventory]]
name = "katagoria"
exclude = false
candidate = true
size_kb = 373
description = "(empty)"
last_push = "2026-04-17"
rationale = "Very small (373KB). Low disclosure risk. Empty description — recommend user confirm content before transfer."
pre_transfer_check = "skim README + file listing to confirm no sensitive content hides under the size."

[[inventory]]
name = "network-ambulance"
exclude = false
candidate = true
size_kb = 413
description = "Platform-independent complete internet repair tool — cross-platform successor to Windows Complete Internet Repair. Canonical in aerie; subset in ambientops."
last_push = "2026-04-17"
rationale = "Described as cross-platform successor to an existing public tool. Subset already extracted downstream. Low-sensitivity operational tool."

[[inventory]]
name = "nextgen-typing"
exclude = false
candidate = true
size_kb = 373
description = "(empty)"
last_push = "2026-04-17"
rationale = "Very small (373KB). Low disclosure risk. Empty description — recommend user confirm content before transfer."
pre_transfer_check = "skim README + file listing to confirm no sensitive content hides under the size."

## Proposed sequencing (dry-run first, then batched)

[[batch]]
id = "batch-0-dry-run"
description = "Dry-run inspection — no transfers executed. For each candidate, cat README + list top-level files + verify no secrets."
commands = [
  "for r in ipv6-only katagoria network-ambulance nextgen-typing; do echo === $r ===; gh api repos/hyperpolymath/$r/contents/ -q '.[].name'; done",
  "for r in katagoria nextgen-typing; do gh api repos/hyperpolymath/$r/readme --jq '.content' | base64 -d || echo NO-README; done",
]
executes_transfer = false

[[batch]]
id = "batch-1-tiny-repos"
description = "Transfer the two tiny empty-description repos first, as the lowest-blast-radius test of the transfer mechanics."
repos = ["katagoria", "nextgen-typing"]
rationale = "If the mechanics break, failure is contained to 2×373KB repos with no stars/forks and no CI dependency."
executes_transfer = true
commands = [
  "gh api -X POST repos/hyperpolymath/katagoria/transfer -f new_owner=The-Metadatastician",
  "gh api -X POST repos/hyperpolymath/nextgen-typing/transfer -f new_owner=The-Metadatastician",
]
post_action = "verify redirect works: `git ls-remote git@github.com:hyperpolymath/katagoria.git` should resolve."

[[batch]]
id = "batch-2-operational-tools"
description = "Transfer the operational tool repos after batch-1 succeeds."
repos = ["network-ambulance", "ipv6-only"]
rationale = "Real content with public downstream subsets. Transfer unblocks GHAS code-scanning on the full internal version while the aerie/ambientops public subsets continue to ship normally."
executes_transfer = true
commands = [
  "gh api -X POST repos/hyperpolymath/network-ambulance/transfer -f new_owner=The-Metadatastician",
  "gh api -X POST repos/hyperpolymath/ipv6-only/transfer -f new_owner=The-Metadatastician",
]
post_action = "verify mirror-sync references still resolve; check CI webhook targets (if any) still fire."

[[batch]]
id = "batch-3-deferred"
description = "Repos-monorepo transfer deferred pending review."
repos = ["repos-monorepo"]
rationale = "Submodule-pointer workspace root. Moving it changes origin URL for every downstream submodule reference. Worth doing only if GHAS on the wrapper repo provides meaningful signal — probably not."
executes_transfer = false
decision_pending = "JONATHAN — is there value in scanning the wrapper monorepo, or is the signal entirely on the member repos?"

## Post-transfer checks (each transferred repo)

[[post_check]]
id = "redirect-works"
command = "git ls-remote git@github.com:hyperpolymath/<repo>.git 2>&1 | head -1"
expect = "non-error output (GitHub redirects old-owner URLs)"

[[post_check]]
id = "ghas-features-enabled"
command = "gh api repos/The-Metadatastician/<repo> -q '.security_and_analysis'"
expect = "secret_scanning + code_scanning = enabled (may need explicit enablement POST-transfer)"
next_action_if_missing = "gh api -X PATCH repos/The-Metadatastician/<repo> -f 'security_and_analysis[secret_scanning][status]=enabled' -f 'security_and_analysis[code_scanning][status]=enabled'"

[[post_check]]
id = "internal-visibility"
command = "gh api repos/The-Metadatastician/<repo> -q '.visibility'"
expect = "private (default on transfer) — must be changed to 'internal' via gh api -X PATCH -f visibility=internal if Enterprise tier supports it for this repo"

[[post_check]]
id = "mirror-chain-updated"
description = "Verify hub-and-spoke mirror system still points at the new upstream. Per memory: GitHub is single source of truth; mirror-sync is automated. Transfers change the canonical URL from github.com/hyperpolymath/X to github.com/The-Metadatastician/X — confirm the mirror system follows."
owner = "JONATHAN or mirror-sync tooling"

## Open questions for Jonathan

[[question]]
id = "q1-katagoria-content"
text = "What is katagoria? Empty description, 373KB, 1 star. Confirm content is not sensitive before batch-1 executes."

[[question]]
id = "q2-nextgen-typing-content"
text = "What is nextgen-typing? Empty description, 373KB, 1 star. Same check as katagoria."

[[question]]
id = "q3-repos-monorepo"
text = "Transfer repos-monorepo to Metadatastician, or keep it at hyperpolymath as the workspace root?"

[[question]]
id = "q4-ghas-features-post-transfer"
text = "Post-transfer, should code_scanning + secret_scanning be auto-enabled via PATCH, or left to the default enterprise policy?"

[[question]]
id = "q5-greenlight-batch-1"
text = "GREENLIGHT batch-1 (katagoria + nextgen-typing)? This is the first destructive-ish action — everything prior is reversible via `gh api -X POST repos/The-Metadatastician/X/transfer -f new_owner=hyperpolymath`."

## Status

[[status]]
as_of = "2026-04-17 (post-execution)"
plan_prepared = true
dry_run_executed = true
batch_1_executed = true
batch_2_executed = true
batch_3_executed = false
awaiting = "batch-3 (repos-monorepo) decision — kept deferred, no action taken"

## Execution log — 2026-04-17

[[execution]]
step = "dry-run content inspection"
result = "katagoria confirmed: Type Theory Research Origination (Idris2/Lean prototypes). nextgen-typing confirmed: coordination monorepo for type theory pipeline. Both benign, no sensitive content."
status = "passed"

[[execution]]
step = "batch-1 transfers"
repos = ["katagoria", "nextgen-typing"]
command_used = "gh api -X POST repos/hyperpolymath/<repo>/transfer -f new_owner=The-Metadatastician"
result = "both transferred successfully; GitHub URL redirect verified via git ls-remote on old URL"
visibility_post_transfer = "private (default on transfer)"
status = "complete"

[[execution]]
step = "batch-2 transfers"
repos = ["network-ambulance", "ipv6-only"]
command_used = "gh api -X POST repos/hyperpolymath/<repo>/transfer -f new_owner=The-Metadatastician"
result = "both transferred successfully; GitHub URL redirect verified"
visibility_post_transfer = "private (default)"
status = "complete"

[[execution]]
step = "flip visibility to internal"
repos = ["katagoria", "nextgen-typing", "network-ambulance", "ipv6-only"]
command_used = "gh api -X PATCH repos/The-Metadatastician/<repo> -f visibility=internal"
result = "all 4 now visibility=internal (Enterprise plan supports)"
status = "complete"

[[execution]]
step = "enable GHAS features"
repos = ["katagoria", "nextgen-typing", "network-ambulance", "ipv6-only"]
command_used = "gh api -X PATCH repos/The-Metadatastician/<repo> -f 'security_and_analysis[secret_scanning][status]=enabled' -f 'security_and_analysis[secret_scanning_push_protection][status]=enabled' -f 'security_and_analysis[code_security][status]=enabled'"
result = "code_security=enabled, secret_scanning=enabled, secret_scanning_push_protection=enabled on all 4. dependabot_security_updates was enabled by default."
status = "complete"

[[execution]]
step = "update local origin URLs"
paths = [
  "/var/mnt/eclipse/repos/developer-ecosystem/katagoria",
  "/var/mnt/eclipse/repos/developer-ecosystem/nextgen-typing",
  "/var/mnt/eclipse/repos/aerie/network/network-ambulance",
  "/var/mnt/eclipse/repos/aerie/network/ipv6-only",
]
command_used = "git remote set-url origin git@github.com:The-Metadatastician/<repo>.git"
result = "all 4 origins updated; ls-remote against new URL returns HEAD correctly. Downstream mirror remotes (gitlab/bitbucket/codeberg/sourcehut) intentionally left at hyperpolymath/ paths — mirror propagation is hub-and-spoke from GitHub per user rule."
status = "complete"

[[execution]]
step = "star transferred repos"
repos = ["katagoria", "nextgen-typing", "network-ambulance", "ipv6-only"]
command_used = "gh api -X PUT user/starred/The-Metadatastician/<repo>"
result = "all 4 starred on the new org"
status = "complete"

## Follow-up — mirror system reconciliation

[[followup]]
id = "mirror-propagation-verify"
description = "Verify the hub-and-spoke mirror system still recognises the new upstream URL. The four transferred repos' gitlab/bitbucket/codeberg/sourcehut mirrors still point at hyperpolymath/* paths downstream. GitHub's URL redirect should allow the mirror system's `git fetch` to follow, but the mirror-sync tooling may need a repo-owner update in its config."
owner = "mirror system"
priority = "low — redirects mean no immediate breakage"

[[followup]]
id = "gitbot-directives-owner-refresh"
description = "Any bot_directives referencing 'hyperpolymath/<repo>' as a hard-coded owner for the 4 transferred repos should point at 'The-Metadatastician/<repo>'. Grep pending."
owner = "CLAUDE — next session"
priority = "medium"

## Batch 3 — 007 (appended 2026-04-17, post-hoc scope expansion)

# Scope note: the original plan above explicitly excluded 007 as "always-private".
# User decided later the same day to move 007 anyway to unlock GHAS on Enterprise.
# Memory rule `always-private-repos.md` says "NEVER make public" — internal (which
# this transfer uses) is not public, so the rule is honoured.

[[execution]]
step = "transfer 007"
repos = ["007"]
command_used = "gh api -X POST repos/hyperpolymath/007/transfer -f new_owner=The-Metadatastician"
result = "transfer accepted; The-Metadatastician/007 now resolves, hyperpolymath/007 redirects."
status = "complete"

[[execution]]
step = "set visibility + enable GHAS on 007"
repos = ["007"]
command_used = "gh api -X PATCH repos/The-Metadatastician/007 -f visibility=internal; gh api -X PATCH repos/The-Metadatastician/007 -F 'security_and_analysis[code_security][status]=enabled' -F 'security_and_analysis[secret_scanning][status]=enabled' -F 'security_and_analysis[secret_scanning_push_protection][status]=enabled'"
result = "visibility=internal, code_security=enabled, secret_scanning=enabled, secret_scanning_push_protection=enabled, dependabot_security_updates=enabled (default). Matches batch-1/2 GHAS posture exactly."
status = "complete"
# Note: initial attempt used legacy field name `advanced_security` which returned 422
# ('not available, nor a pre-requisite for security features'); corrected to
# `code_security` on retry — field-name drift worth capturing for next batch.

[[execution]]
step = "update local origin for 007-lang"
paths = ["/var/mnt/eclipse/repos/007-lang"]
command_used = "git remote set-url origin git@github.com:The-Metadatastician/007.git"
result = "origin updated; git fetch origin succeeded against new URL."
status = "complete"

[[execution]]
step = "estate reference sweep for 007"
scope = "all live (non-historical) hyperpolymath/007 references across the estate"
result = "5 commits across 4 repos: 007-lang commit 2a37aab (26 files, package metadata + .github meta + .machine_readable configs + .well-known + spec + QUICKSTART), repos-monorepo commit 80c034a5 (4 files: gitbot-fleet exclusion_registry + registry_guard in both shared-context and robot-repo-automaton), hypatia commit 1630a79 (scorecard-target-manifest.json — dispatch target), nextgen-languages commit 5931198 (languages/007.md catalogue entry). All pushed."
status = "complete"

[[execution]]
step = "preserved historical refs deliberately"
scope = "4 files left pointing at hyperpolymath/007 to preserve honest record"
paths = [
  "/var/mnt/eclipse/repos/007-lang/audits/SESSION-CLOSE-2026-04-17-unbounded-allocation-fully-closed.adoc",
  "/var/mnt/eclipse/repos/007-lang/audits/SESSION-CLOSE-2026-04-17-inline-test-mod-strip.adoc",
  "/var/mnt/eclipse/repos/007-lang/audits/SESSION-CLOSE-2026-04-17-unbounded-allocation-triage.adoc",
  "/var/mnt/eclipse/repos/007-lang/docs/internal/DESIGN-JOURNAL.adoc",
]
rationale = "Audit session-closes and the design journal record facts as they were at the time of writing; rewriting the owner would misrepresent the point-in-time record."
status = "deliberate"

# Launch-scaffolder's branch-protection-remediation-2026-04-10.md (two locations:
# /var/mnt/eclipse/repos/launch-scaffolder/docs/ and
# /var/mnt/eclipse/repos/developer-ecosystem/launch-scaffolder/docs/) also left as-is
# — it is a historical remediation doc from 2026-04-10 and rewriting would misrepresent
# the state of the estate at that date.

[[execution]]
step = "secret + workflow ref re-scope check for 007"
repos = ["007"]
result = "no actions secrets, no Dependabot secrets (`gh secret list` + `gh api dependabot/secrets` both empty). No workflow refs to `hyperpolymath/007` in 007-lang workflows (they use `${{ github.repository }}`). Nothing to re-scope."
status = "complete"

[[execution]]
step = "star transferred 007"
command_used = "pending — estate-rule: always star after significant work"
status = "pending"

## Abstract update note (2026-04-17)

# The @abstract block at the top of this file described the original 4-repo batch
# with 007 explicitly excluded. 007 has since been transferred (batch-3 above) but
# the abstract is retained in its original form rather than rewritten — the batch-3
# section documents the post-hoc scope expansion cleanly without rewriting history.
