Skip to content

Commit 3036e19

Browse files
committed
Integrate CP89 and upstream CLI fixes
1 parent 73f4826 commit 3036e19

24 files changed

Lines changed: 1393 additions & 138 deletions

‎.github/workflows/promote-qualified-release.yml‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ jobs:
1818
contents: read
1919
steps:
2020
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21+
with:
22+
ref: ${{ inputs.version }}
2123
- name: Validate version input
2224
env:
2325
VERSION: ${{ inputs.version }}
@@ -39,12 +41,14 @@ jobs:
3941
env:
4042
VERSION: ${{ inputs.version }}
4143
run: |
44+
SOURCE_COMMIT="$(git rev-parse HEAD)"
4245
python3 scripts/ci/verify-external-qualification.py \
4346
--manifest release/qualification-manifest.json \
4447
--summary release/qualification-summary.md \
4548
--archive release/codebase-memory-cli-windows-amd64.zip \
4649
--checksums release/checksums.txt \
47-
--expected-tag "$VERSION"
50+
--expected-tag "$VERSION" \
51+
--expected-source-commit "$SOURCE_COMMIT"
4852
4953
publish-registries:
5054
needs: [verify-external-qualification]
@@ -54,6 +58,8 @@ jobs:
5458
id-token: write
5559
steps:
5660
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
61+
with:
62+
ref: ${{ inputs.version }}
5763
- name: Sync packaging versions
5864
env:
5965
RELEASE_VERSION: ${{ inputs.version }}

‎BACKLOG.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,25 @@
1010

1111
## Open
1212

13+
- [ ] Selectively evaluate remaining upstream fixes from
14+
`../codebase-memory-mcp` before merging into the CLI fork. Do not
15+
cherry-pick MCP-only changes or overwrite CP89/release-tooling work; apply
16+
compatible patches into a temporary worktree, run focused suites, then
17+
review the resulting diff before integration.
18+
- `77a0c7d9` pipeline empty-graph function-sort guard.
19+
- `04ba2fa3` Cypher variable-limit validation; `98899ba5` is the related
20+
unnamed-head-node follow-up.
21+
- `9846c3f1` and `c1b9c451` Windows daemon/session-root separator
22+
handling; port daemon-only hunks and omit MCP hunks.
23+
- `92725a5e` Windows stdio parent-death cleanup; verify relevance to the
24+
CLI-only process model before porting.
25+
- `e5c17de6` and `b04f5450` coverage correctness/performance; manually
26+
reconcile against the fork's changed coverage implementation.
27+
- `1770d68a` Razor Pages/MVC extraction and `24f54c0e` inline
28+
Svelte/HTML/Astro extraction; assess grammar and fixture scope separately.
29+
- MCP-only output/search/pagination/compact-output commits are intentionally
30+
excluded from this backlog item.
31+
1332
- [ ] Retire or migrate legacy MCP-dependent test sources. The production
1433
Makefile now leaves `MCP_SRCS` empty, but the monolithic test runner still
1534
compiles MCP tests and repro harnesses; focused daemon tests therefore stop

‎docs/CLI_MIGRATION_STATUS.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,13 @@ Status: **IMPLEMENTED / REQUIRES EXTERNAL RERUN**
416416
- **FIXED (evidence isolation):** corpus initialization writes the frozen manifest into the qualification evidence tree rather than dirtying the exact RC source checkout.
417417
- **RECONCILED:** the last two known Claude-hook tests now enforce exact current CLI command ownership while preserving MCP-era hook identities as foreign, matching the CP78 side-by-side contract.
418418
- **PENDING EXTERNAL EVIDENCE:** run the external CLI/full suite after CP88 and then execute the Windows RC orchestrator on `luigi.home.arpa` against the immutable draft artifact. No compile or test execution was performed locally for CP88.
419+
420+
### CP89 — Windows RC qualification provenance closeout
421+
422+
Static/source audit only; no local compilation or test execution was performed.
423+
424+
- external Windows qualification evidence now binds the exact release tag to its immutable source commit in addition to the Windows archive/executable SHA-256 values;
425+
- `run-windows-rc-qualification.ps1` requires PowerShell 7+ for deterministic BOM-free UTF-8 JSON evidence and refuses cross-checkout `SourceRoot` execution;
426+
- `run-windows-benchmark-corpus.ps1` resolves moving initialization branches from `origin/<branch>` and freezes the resulting commit before benchmarking;
427+
- the promotion workflow checks out the exact qualified tag both when verifying evidence and when publishing npm/PyPI wrappers, preventing registry publication from a later default-branch revision;
428+
- the Windows benchmark runbook now accurately describes the external frozen-manifest evidence flow and the deliberate post-qualification commit that establishes the durable corpus generation for later releases.

‎docs/RELEASE_QUALIFICATION_PLAN.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,8 @@ If qualification finds a defect and the candidate changes:
199199
RC dispatch is now a distinct evidence-bearing step. Use `scripts/ci/prepare-rc-dispatch.py` and `docs/agents/GITHUB_RC_DISPATCH_AGENT.md` rather than hand-assembling workflow inputs.
200200

201201
The dispatch record binds the clean source commit, explicit RC tag, release workflow hash, corpus-generation manifest hash, and external-qualification hold. The first CLI-first candidate should normally use the next deliberate prerelease in the current release line (recommended `v0.11.0-rc.1` after public `v0.10.8`), but the operator must select the tag explicitly and verify it is unused before dispatch. Because `v0.10.8` predates the comparable CLI-first workflow surface, the first qualified CLI release must explicitly use `BASELINE_ZERO`; the next release uses that qualified CLI release as its immutable comparative baseline.
202+
203+
204+
### Qualified source identity
205+
206+
External qualification evidence must bind the exact release tag to its immutable source commit (`release.source_commit`) in addition to the Windows archive and executable SHA-256 values. The promotion workflow checks out the exact tag and rejects evidence whose source commit differs.

‎docs/WINDOWS_BENCHMARK_RUNBOOK.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The two moving `master` references above are **initialization references only**.
1818

1919
## Prerequisites on Luigi
2020

21-
Use native 64-bit PowerShell 7 if available. Required commands: `git`, `python`, and the candidate `codebase-memory-cli.exe`. Use a local SSD directory, not a network share. Keep AC power connected, disable sleep for the run, close large background workloads, and keep the same Windows power mode for all trials.
21+
Use native 64-bit **PowerShell 7 or newer**. The qualification orchestrator intentionally rejects Windows PowerShell 5.1 so JSON/evidence UTF-8 encoding is deterministic. Required commands: `git`, `python`, and the candidate `codebase-memory-cli.exe`. Use a local SSD directory, not a network share. Keep AC power connected, disable sleep for the run, close large background workloads, and keep the same Windows power mode for all trials.
2222

2323
Suggested layout:
2424

@@ -89,15 +89,15 @@ Run the corpus orchestrator in initialization mode. `-CodebaseMemoryRef` must be
8989
2. fetches tags/refs;
9090
3. checks out each declared initialization ref (and the supplied exact RC ref for self-hosting);
9191
4. hard-resets/cleans each benchmark checkout;
92-
5. writes each local path and exact `HEAD` SHA into `docs/qualification/BENCHMARK_CORPUS.json`;
93-
6. runs `scripts/qualification/validate-corpus-checkouts.py` against the frozen manifest;
92+
5. writes each local path and exact `HEAD` SHA into a separate frozen manifest (`BENCHMARK_CORPUS.frozen.json`);
93+
6. runs `scripts/qualification/validate-corpus-checkouts.py` against that frozen manifest;
9494
7. executes the benchmark corpus using the exact candidate executable.
9595

96-
After this first successful freeze, **commit the populated corpus manifest**. Any later repository SHA change requires a new corpus generation rather than silently editing `windows-corpus-1`.
96+
The top-level RC orchestrator stores the frozen manifest under its `evidence` directory so the exact RC source checkout remains clean throughout qualification. After the first successful BASELINE_ZERO run, review that evidence manifest and deliberately copy its frozen repository entries into `docs/qualification/BENCHMARK_CORPUS.json` on the development branch for subsequent releases, then commit that change. Do not modify the already-qualified RC tag. Any later repository SHA change requires a new corpus generation rather than silently editing `windows-corpus-1`.
9797

9898
## Subsequent runs
9999

100-
Once the manifest is pinned, omit `-Initialize` and do not supply a moving branch as a substitute for a pinned commit:
100+
Once a later source revision contains the committed frozen manifest, omit `-Initialize` and do not supply a moving branch as a substitute for a pinned commit:
101101

102102
```powershell
103103
.\scripts\qualification\run-windows-benchmark-corpus.ps1 `

‎docs/WINDOWS_RELEASE_VALIDATION.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,8 @@ Native Windows qualification is complete only when:
189189
- recovery/lifecycle checks complete;
190190
- evidence bundle is complete;
191191
- all non-pass results have explicit disposition.
192+
193+
194+
### Qualified source identity
195+
196+
External qualification evidence must bind the exact release tag to its immutable source commit (`release.source_commit`) in addition to the Windows archive and executable SHA-256 values. The promotion workflow checks out the exact tag and rejects evidence whose source commit differs.

‎docs/agents/WINDOWS_RELEASE_QUALIFICATION_AGENT.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,8 @@ Required manifest shape:
230230
```
231231

232232
If any required gate is not releasable, do not upload a PASS manifest. Keep the evidence bundle locally and report the blocker.
233+
234+
235+
### Qualified source identity
236+
237+
External qualification evidence must bind the exact release tag to its immutable source commit (`release.source_commit`) in addition to the Windows archive and executable SHA-256 values. The promotion workflow checks out the exact tag and rejects evidence whose source commit differs.

‎scripts/ci/verify-external-qualification.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def main() -> None:
2424
ap.add_argument('--archive', required=True, type=pathlib.Path)
2525
ap.add_argument('--checksums', required=True, type=pathlib.Path)
2626
ap.add_argument('--expected-tag', required=True)
27+
ap.add_argument('--expected-source-commit', required=True)
2728
ap.add_argument('--expected-host', default='luigi.home.arpa')
2829
ap.add_argument('--expected-corpus', default='windows-corpus-1')
2930
args = ap.parse_args()
@@ -35,6 +36,8 @@ def main() -> None:
3536
if data.get('corpus_generation') != args.expected_corpus: fail('corpus generation mismatch')
3637
rel = data.get('release') or {}
3738
if rel.get('tag') != args.expected_tag: fail('release tag mismatch')
39+
if rel.get('source_commit') != args.expected_source_commit:
40+
fail('release source commit mismatch')
3841

3942
for key in ('portable_result','installed_result','windows_guards_result','recovery_result'):
4043
if data.get(key) != 'PASS': fail(f'{key} is not PASS')
@@ -63,7 +66,7 @@ def main() -> None:
6366
if rel.get('windows_executable_sha256','').lower() != h:
6467
fail('Windows executable SHA-256 mismatch')
6568

66-
print(f'External qualification verified: {args.expected_tag} on {args.expected_host} ({args.expected_corpus})')
69+
print(f'External qualification verified: {args.expected_tag} @ {args.expected_source_commit} on {args.expected_host} ({args.expected_corpus})')
6770

6871
if __name__ == '__main__':
6972
main()

‎scripts/qualification/run-windows-benchmark-corpus.ps1‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,14 @@ foreach($r in $doc.repositories){
3131
elseif($r.initialization_ref){$ref=[string]$r.initialization_ref}
3232
else { throw "No initialization ref for $($r.id)" }
3333
}
34-
git -C $path checkout --detach $ref; if($LASTEXITCODE){throw "checkout failed: $($r.id) ref=$ref"}
35-
git -C $path reset --hard HEAD | Out-Null
34+
# Freeze moving branch refs from origin, not from a potentially stale local branch.
35+
$checkoutRef=$ref
36+
& git -C $path show-ref --verify --quiet "refs/remotes/origin/$ref"
37+
if($LASTEXITCODE -eq 0){$checkoutRef="refs/remotes/origin/$ref"}
38+
$resolvedCommit=(& git -C $path rev-parse "$checkoutRef^{commit}" 2>$null).Trim()
39+
if($LASTEXITCODE -ne 0 -or -not $resolvedCommit){throw "cannot resolve checkout ref: $($r.id) ref=$checkoutRef"}
40+
git -C $path checkout --detach $resolvedCommit; if($LASTEXITCODE){throw "checkout failed: $($r.id) ref=$checkoutRef commit=$resolvedCommit"}
41+
git -C $path reset --hard $resolvedCommit | Out-Null
3642
git -C $path clean -ffd | Out-Null
3743
$dirty=@(& git -C $path status --porcelain)
3844
if($dirty.Count -ne 0){throw "checkout is dirty after reset/clean: $($r.id)"}

‎scripts/qualification/run-windows-rc-qualification.ps1‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ param(
1616
[string]$ExpectedHost = 'luigi.home.arpa'
1717
)
1818
$ErrorActionPreference='Stop'
19+
if($PSVersionTable.PSVersion.Major -lt 7){throw 'Windows RC qualification requires PowerShell 7 or newer for deterministic UTF-8 evidence output'}
1920
$repoRoot=(Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
2021
if(-not $SourceRoot){$SourceRoot=$repoRoot}else{$SourceRoot=(Resolve-Path -LiteralPath $SourceRoot).Path}
22+
if([IO.Path]::GetFullPath($SourceRoot).TrimEnd('\') -ne [IO.Path]::GetFullPath($repoRoot).TrimEnd('\')){
23+
throw 'SourceRoot must be the same exact checkout that contains this qualification script; cross-checkout qualification is not allowed'
24+
}
2125
$stamp=[DateTime]::UtcNow.ToString('yyyyMMddTHHmmssZ')
2226
$runRoot=Join-Path $QualificationRoot (($ReleaseTag -replace '[^A-Za-z0-9._-]','_') + '-' + $stamp)
2327
$artifactDir=Join-Path $runRoot 'artifact'
@@ -224,11 +228,11 @@ $manifestPath=Join-Path $evidenceDir 'qualification-manifest.json'
224228
recovery_result=$recoveryResult
225229
benchmark_result=$BenchmarkResult
226230
summary_sha256=$summaryHash
227-
release=[ordered]@{tag=$ReleaseTag;windows_archive_sha256=$archiveHash;windows_executable_sha256=$exeHash}
231+
release=[ordered]@{tag=$ReleaseTag;source_commit=$ExpectedSourceCommit;windows_archive_sha256=$archiveHash;windows_executable_sha256=$exeHash}
228232
} | ConvertTo-Json -Depth 5 | Set-Content -Encoding utf8 -LiteralPath $manifestPath
229233

230234
# Verify the evidence with the same verifier used by promotion before optional upload.
231-
& python (Join-Path $repoRoot 'scripts\ci\verify-external-qualification.py') --manifest $manifestPath --summary $summary --archive $CandidateArchive --checksums $Checksums --expected-tag $ReleaseTag --expected-host $ExpectedHost --expected-corpus 'windows-corpus-1'
235+
& python (Join-Path $repoRoot 'scripts\ci\verify-external-qualification.py') --manifest $manifestPath --summary $summary --archive $CandidateArchive --checksums $Checksums --expected-tag $ReleaseTag --expected-source-commit $ExpectedSourceCommit --expected-host $ExpectedHost --expected-corpus 'windows-corpus-1'
232236
Require-Exit $LASTEXITCODE 'external qualification evidence verification'
233237
if($UploadEvidence){
234238
$gh=(Get-Command gh -ErrorAction SilentlyContinue); if(-not $gh){throw 'gh is required for -UploadEvidence'}

0 commit comments

Comments
 (0)