# Covers Phase 2 of sync_repos.ps1 -- the registry reconciliation that decides whether a # directory found on the Codex side gets ingested, collapsed, or reported. Runs against a # throwaway primary + registries + bare origin under TEMP; the real machine is never touched. $ErrorActionPreference = "Stop" $scriptUnderTest = Join-Path (Split-Path $PSScriptRoot -Parent) "scripts\sync_repos.ps1" $root = Join-Path ([IO.Path]::GetTempPath()) ("tools-sync-repos-test-" + [guid]::NewGuid().ToString("N")) function New-Skill([string]$Path, [string]$Body) { New-Item -ItemType Directory -Force -Path $Path | Out-Null Set-Content -LiteralPath (Join-Path $Path "SKILL.md") -Value $Body -Encoding utf8 } try { $primary = Join-Path $root "primary" $codex = Join-Path $root "codex" $agents = Join-Path $root "agents" New-Item -ItemType Directory -Force -Path $primary, $codex, $agents | Out-Null # One skill of each shape the reconciler must tell apart. New-Skill (Join-Path $primary "shared") "shared body" New-Skill (Join-Path $primary "forked") "primary body" New-Skill (Join-Path $agents "shared") "shared body" # identical duplicate -> collapse New-Skill (Join-Path $agents "forked") "registry body" # divergent -> conflict New-Skill (Join-Path $agents "codexborn") "born on the codex side" # registry-only -> ingest New-Item -ItemType Directory -Force -Path (Join-Path $agents "notaskill") | Out-Null # no SKILL.md # A link into the other registry rather than the primary: the drift case. New-Item -ItemType Junction -Path (Join-Path $codex "shared") -Target (Join-Path $agents "shared") | Out-Null # Host-installed shape: the real directory lives in a registry and the PRIMARY is the link # (Orca installs this way). Collapsing the registry copy here would make the link point at # itself and delete the only copy - the reconciler must recognise it and keep its hands off. New-Skill (Join-Path $agents "hostowned") "installed by the host" New-Item -ItemType Junction -Path (Join-Path $primary "hostowned") -Target (Join-Path $agents "hostowned") | Out-Null # A local bare repo stands in for origin so Phase 1 completes and Phase 2 actually runs. $origin = Join-Path $root "origin.git" & git init --quiet --bare $origin & git init --quiet --initial-branch=main $primary & git -C $primary remote add origin $origin & git -C $primary -c user.email=t@t -c user.name=t commit --quiet --allow-empty -m init & git -C $primary push --quiet -u origin main # Invoked via -Command, not -File: -File stringifies every argument, so a [string[]] # parameter silently takes only its first element and the rest slide into later positions. $ErrorActionPreference = "Continue" $invocation = "& '$scriptUnderTest' -RepoUrl '$origin' -ClaudeSkills '$primary' " + "-Registry @('$codex','$agents') -MirrorRegistry '$codex'" $output = & powershell -NoProfile -ExecutionPolicy Bypass -Command $invocation 2>&1 | Out-String $ErrorActionPreference = "Stop" if ($output -notmatch 'INGEST registry-only skill:\s*codexborn') { throw "codex-side skill was not ingested`n$output" } if (-not (Test-Path (Join-Path $primary "codexborn\SKILL.md"))) { throw "ingested skill is not in the primary`n$output" } if ((Get-Item (Join-Path $agents "codexborn")).LinkType -ne "Junction") { throw "ingested skill was not linked back`n$output" } if ($output -notmatch 'MISDIRECTED link:\s*shared') { throw "link into another registry not detected`n$output" } $sharedTarget = (Get-Item (Join-Path $codex "shared")).Target | Select-Object -First 1 if ($sharedTarget -ne (Join-Path $primary "shared")) { throw "misdirected link not repointed at the primary, got $sharedTarget`n$output" } if ((Get-Item (Join-Path $agents "shared")).LinkType -ne "Junction") { throw "identical duplicate did not collapse`n$output" } if ($output -notmatch 'CONFLICT:\s*forked') { throw "divergent duplicate not reported`n$output" } if ((Get-Item (Join-Path $agents "forked")).LinkType -eq "Junction") { throw "divergent duplicate must be left untouched`n$output" } if ((Get-Content -Raw (Join-Path $primary "forked\SKILL.md")) -notmatch 'primary body') { throw "primary was overwritten by a conflict`n$output" } if ($output -notmatch 'not a skill dir') { throw "directory without SKILL.md not reported`n$output" } # The host-installed skill must survive intact, with the primary still a link at the registry. $hostReal = Get-Item -Force (Join-Path $agents "hostowned") if ($hostReal.LinkType -eq "Junction") { throw "host-installed skill's real dir was collapsed into a link`n$output" } if ((Get-Content -Raw (Join-Path $agents "hostowned\SKILL.md")) -notmatch 'installed by the host') { throw "host-installed skill's content was lost`n$output" } $hostPrimary = Get-Item -Force (Join-Path $primary "hostowned") if (($hostPrimary.Target | Select-Object -First 1) -ne (Join-Path $agents "hostowned")) { throw "primary link to the host-installed skill was repointed`n$output" } # Mirroring it into the registry Codex scans would register the same skill twice. if (Test-Path (Join-Path $codex "hostowned")) { throw "host-installed skill was mirrored, double-registering it`n$output" } # Mirror registry must expose every primary skill, including the freshly ingested one. foreach ($name in @("shared", "forked", "codexborn")) { if (-not (Test-Path (Join-Path $codex "$name\SKILL.md"))) { throw "mirror missing $name`n$output" } } # Phase 1's success line is the ls-remote gate's verdict (upstream wording). if ($output -notmatch 'verified: origin/main =') { throw "Phase 1 did not complete`n$output" } Write-Host "PASS: registry ingest / repair / conflict fixtures" } finally { Remove-Item -LiteralPath $root -Recurse -Force -ErrorAction SilentlyContinue }