mixdog 0.9.9 → 0.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/bench/lead-review-tasks-r3.json +1 -1
- package/scripts/bench/r4-mixed-tasks.json +1 -1
- package/scripts/bench/review-tasks.json +1 -1
- package/scripts/build-runtime-windows.ps1 +242 -242
- package/scripts/recall-usecase-cases.json +1 -1
- package/scripts/smoke-runtime-negative.ps1 +106 -106
- package/src/rules/agent/30-explorer.md +18 -20
- package/src/rules/lead/02-channels.md +3 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +9 -0
- package/src/standalone/explore-tool.mjs +2 -2
package/package.json
CHANGED
|
@@ -17,4 +17,4 @@
|
|
|
17
17
|
"cwd": "C:/Project/mixdog-bench",
|
|
18
18
|
"prompt": "READ-ONLY review task: you and any delegated agents must NOT modify, create, or delete any files - report findings only. Review the folder src/runtime/agent/orchestrator/session/compact/ for correctness, regression, and security risks. Delegate exploration/reading to your workflow agents where useful and synthesize their findings. Focus on real actionable bugs: schema validation gaps, data corruption on summarize, lossy round-trips, error swallowing. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
|
|
19
19
|
}
|
|
20
|
-
]
|
|
20
|
+
]
|
|
@@ -17,4 +17,4 @@
|
|
|
17
17
|
"cwd": "C:/Project/mixdog-bench",
|
|
18
18
|
"prompt": "Map the compaction subsystem: starting from src/runtime/agent/orchestrator/session/compact/engine.mjs, produce a concise architecture brief - entry points and callers, the decision flow for when compaction fires, how the preserved tail is chosen, where redaction hooks in, and the failure/fallback paths. Anchor every claim with file:line. Keep it under 40 lines."
|
|
19
19
|
}
|
|
20
|
-
]
|
|
20
|
+
]
|
|
@@ -17,4 +17,4 @@
|
|
|
17
17
|
"cwd": "C:/Project/mixdog",
|
|
18
18
|
"prompt": "Review the folder src/runtime/agent/orchestrator/session/compact/ for correctness, regression, and security risks. Focus on real actionable bugs: schema validation gaps, data corruption on summarize, lossy round-trips, error swallowing. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
|
|
19
19
|
}
|
|
20
|
-
]
|
|
20
|
+
]
|
|
@@ -1,242 +1,242 @@
|
|
|
1
|
-
# build-runtime-windows.ps1 — Build PostgreSQL 16 + pgvector runtime on Windows.
|
|
2
|
-
# Uses windows-2022 GHA runner's preinstalled PostgreSQL 16 (consistent
|
|
3
|
-
# pg_config + postgres.exe from same package) — avoids EDB zip's split-version
|
|
4
|
-
# packaging bug that linked pgvector against PG 14 ABI.
|
|
5
|
-
# Builds pgvector from source via MSVC/nmake, then assembles a self-contained
|
|
6
|
-
# runtime tree (bin + lib + share at root). Final smoke: initdb + CREATE
|
|
7
|
-
# EXTENSION vector + distance query.
|
|
8
|
-
# Produces: dist\mixdog-runtime-win32-x64-pg{pgver}-pgvector{vecver}.tar.gz
|
|
9
|
-
|
|
10
|
-
$ErrorActionPreference = 'Stop'
|
|
11
|
-
|
|
12
|
-
$PG_VERSION = '16.4'
|
|
13
|
-
$PGVECTOR_VERSION = '0.8.2'
|
|
14
|
-
$TARGET_OS = $env:TARGET_OS ?? 'win32'
|
|
15
|
-
$TARGET_ARCH = $env:TARGET_ARCH ?? 'x64'
|
|
16
|
-
|
|
17
|
-
# Auto-detect highest preinstalled PG ≥ 16 OR install via chocolatey.
|
|
18
|
-
$PgInstallRoot = 'C:\Program Files\PostgreSQL'
|
|
19
|
-
|
|
20
|
-
function Find-PgRoot {
|
|
21
|
-
if (-not (Test-Path $PgInstallRoot)) { return $null }
|
|
22
|
-
$cands = Get-ChildItem $PgInstallRoot -Directory -ErrorAction SilentlyContinue |
|
|
23
|
-
Where-Object { $_.Name -match '^(\d+)' } |
|
|
24
|
-
Sort-Object { [int]([regex]::Match($_.Name, '^(\d+)').Groups[1].Value) } -Descending
|
|
25
|
-
foreach ($c in $cands) {
|
|
26
|
-
$major = [int]([regex]::Match($c.Name, '^(\d+)').Groups[1].Value)
|
|
27
|
-
if ($major -ge 16 -and (Test-Path "$($c.FullName)\bin\pg_config.exe")) {
|
|
28
|
-
return $c.FullName
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return $null
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
$PgRoot = Find-PgRoot
|
|
35
|
-
if (-not $PgRoot) {
|
|
36
|
-
Write-Host "==> No preinstalled PG ≥ 16 found. Installing via chocolatey..."
|
|
37
|
-
if (Test-Path $PgInstallRoot) {
|
|
38
|
-
Write-Host "Existing PG dirs (none usable):"
|
|
39
|
-
Get-ChildItem $PgInstallRoot -Directory -ErrorAction SilentlyContinue | Select-Object Name
|
|
40
|
-
}
|
|
41
|
-
choco install postgresql16 --version=16.4.0 --params '/Password:postgres' -y --no-progress 2>&1 | Out-Host
|
|
42
|
-
if ($LASTEXITCODE -ne 0) { Write-Error "choco install postgresql16 failed (exit $LASTEXITCODE)"; exit 1 }
|
|
43
|
-
$PgRoot = Find-PgRoot
|
|
44
|
-
if (-not $PgRoot) {
|
|
45
|
-
Write-Error "ASSERT FAILED: chocolatey install completed but PG ≥ 16 still not found under $PgInstallRoot"
|
|
46
|
-
Get-ChildItem $PgInstallRoot -Directory -ErrorAction SilentlyContinue | Select-Object Name
|
|
47
|
-
exit 1
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
52
|
-
$RootDir = (Resolve-Path "$ScriptDir\..").Path
|
|
53
|
-
$BuildDir = "$RootDir\build\runtime-win32-$TARGET_ARCH"
|
|
54
|
-
$DistDir = "$RootDir\dist"
|
|
55
|
-
$RuntimeDir = "$BuildDir\runtime"
|
|
56
|
-
|
|
57
|
-
$PgBin = "$PgRoot\bin"
|
|
58
|
-
$PgConfig = "$PgBin\pg_config.exe"
|
|
59
|
-
|
|
60
|
-
$OutputName = "mixdog-runtime-${TARGET_OS}-${TARGET_ARCH}-pg${PG_VERSION}-pgvector${PGVECTOR_VERSION}.tar.gz"
|
|
61
|
-
|
|
62
|
-
Write-Host "==> Using preinstalled PG: $PgRoot"
|
|
63
|
-
& $PgConfig --version
|
|
64
|
-
$RealVersion = (& $PgConfig --version) -replace 'PostgreSQL ', ''
|
|
65
|
-
Write-Host " pg_config reports version: $RealVersion"
|
|
66
|
-
|
|
67
|
-
if (Test-Path $RuntimeDir) { Remove-Item -Recurse -Force $RuntimeDir }
|
|
68
|
-
New-Item -ItemType Directory -Force -Path $BuildDir, $DistDir,
|
|
69
|
-
"$RuntimeDir\bin", "$RuntimeDir\lib", "$RuntimeDir\share" | Out-Null
|
|
70
|
-
|
|
71
|
-
Write-Host "==> Cloning pgvector $PGVECTOR_VERSION"
|
|
72
|
-
$PgVectorDir = "$BuildDir\pgvector"
|
|
73
|
-
$VectorDllBuilt = "$PgVectorDir\vector.dll"
|
|
74
|
-
|
|
75
|
-
if (Test-Path $VectorDllBuilt) {
|
|
76
|
-
Write-Host " Cache hit: vector.dll already built at $VectorDllBuilt"
|
|
77
|
-
} else {
|
|
78
|
-
if (Test-Path $PgVectorDir) { Remove-Item -Recurse -Force $PgVectorDir }
|
|
79
|
-
git clone --branch "v$PGVECTOR_VERSION" --depth 1 `
|
|
80
|
-
https://github.com/pgvector/pgvector.git $PgVectorDir
|
|
81
|
-
|
|
82
|
-
Write-Host "==> Building pgvector (MSVC/nmake against system PG 16)"
|
|
83
|
-
Push-Location $PgVectorDir
|
|
84
|
-
try {
|
|
85
|
-
$VsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
|
86
|
-
$VcVarsAll = & $VsWhere -latest -find 'VC\Auxiliary\Build\vcvarsall.bat' 2>$null | Select-Object -First 1
|
|
87
|
-
if (-not $VcVarsAll) {
|
|
88
|
-
Write-Error "vswhere could not locate vcvarsall.bat — Visual Studio Build Tools required."
|
|
89
|
-
exit 1
|
|
90
|
-
}
|
|
91
|
-
# CRITICAL: prepend $PgRoot\bin to PATH so any bare `pg_config` call
|
|
92
|
-
# inside Makefile.win resolves to PG 16 — runner has PG 14/15
|
|
93
|
-
# preinstalled and would otherwise win the PATH lookup, producing
|
|
94
|
-
# PG14-ABI vector.dll that fails to load in our PG 16 postgres.exe.
|
|
95
|
-
# Set in PowerShell so cmd /c inherits; setting inside the cmd batch
|
|
96
|
-
# via %PATH% loses vcvarsall's additions due to parse-time expansion.
|
|
97
|
-
$env:PATH = "$PgRoot\bin;$env:PATH"
|
|
98
|
-
$env:PGROOT = $PgRoot
|
|
99
|
-
$BuildCmd = "`"$VcVarsAll`" amd64 && nmake /F Makefile.win PG_CONFIG=`"$PgConfig`""
|
|
100
|
-
cmd /c $BuildCmd
|
|
101
|
-
if ($LASTEXITCODE -ne 0) {
|
|
102
|
-
Write-Error "pgvector nmake build failed (exit $LASTEXITCODE)"
|
|
103
|
-
exit 1
|
|
104
|
-
}
|
|
105
|
-
} finally {
|
|
106
|
-
Pop-Location
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
Write-Host "==> Assembling runtime layout — copy bin (.exe + .dll), lib, share from $PgRoot"
|
|
111
|
-
# Copy ALL .exe + .dll from PG bin so postgres.exe + libpq.dll + libcrypto/libssl/
|
|
112
|
-
# libintl/libiconv/icu*/libxml2/libxslt/libwinpthread/libecpg/libpgtypes etc. all
|
|
113
|
-
# ship together. PG 16 install layout puts these all in bin\.
|
|
114
|
-
Copy-Item "$PgBin\*.exe","$PgBin\*.dll" "$RuntimeDir\bin\" -Force
|
|
115
|
-
|
|
116
|
-
# lib\: PG extension modules (incl. contrib like pgcrypto.dll). vector.dll
|
|
117
|
-
# placed here below — PG looks for $libdir/<ext>.dll which resolves to lib\.
|
|
118
|
-
Copy-Item -Recurse -Force "$PgRoot\lib\*" "$RuntimeDir\lib\" -ErrorAction SilentlyContinue
|
|
119
|
-
# share\: extension SQL/control, locale, timezone data, conf samples.
|
|
120
|
-
Copy-Item -Recurse -Force "$PgRoot\share\*" "$RuntimeDir\share\" -ErrorAction SilentlyContinue
|
|
121
|
-
|
|
122
|
-
Write-Host "==> Manually staging pgvector artifacts (avoid pg_config-derived install paths)"
|
|
123
|
-
$RuntimeExtDir = "$RuntimeDir\share\extension"
|
|
124
|
-
New-Item -ItemType Directory -Force -Path $RuntimeExtDir | Out-Null
|
|
125
|
-
Copy-Item "$PgVectorDir\vector.dll" "$RuntimeDir\lib\" -Force
|
|
126
|
-
Copy-Item "$PgVectorDir\vector.control" $RuntimeExtDir -Force
|
|
127
|
-
Copy-Item "$PgVectorDir\sql\vector--*.sql" $RuntimeExtDir -Force
|
|
128
|
-
|
|
129
|
-
Write-Host "==> Asserting runtime layout"
|
|
130
|
-
$VectorControl = "$RuntimeDir\share\extension\vector.control"
|
|
131
|
-
if (-not (Test-Path $VectorControl)) { Write-Error "ASSERT FAILED: $VectorControl not found"; exit 1 }
|
|
132
|
-
$VectorSql = "$RuntimeDir\share\extension\vector--$PGVECTOR_VERSION.sql"
|
|
133
|
-
if (-not (Test-Path $VectorSql)) { Write-Error "ASSERT FAILED: $VectorSql not found"; exit 1 }
|
|
134
|
-
if (-not (Test-Path "$RuntimeDir\lib\vector.dll")) {
|
|
135
|
-
Write-Error "ASSERT FAILED: vector.dll not found in lib\"
|
|
136
|
-
exit 1
|
|
137
|
-
}
|
|
138
|
-
Write-Host " PASS runtime layout"
|
|
139
|
-
|
|
140
|
-
# Licenses
|
|
141
|
-
if (Test-Path "$PgRoot\doc\postgresql\COPYRIGHT") {
|
|
142
|
-
Copy-Item "$PgRoot\doc\postgresql\COPYRIGHT" "$RuntimeDir\LICENSE.postgresql" -Force
|
|
143
|
-
} elseif (Test-Path "$PgRoot\doc\COPYRIGHT") {
|
|
144
|
-
Copy-Item "$PgRoot\doc\COPYRIGHT" "$RuntimeDir\LICENSE.postgresql" -Force
|
|
145
|
-
}
|
|
146
|
-
if (Test-Path "$PgVectorDir\LICENSE") {
|
|
147
|
-
Copy-Item "$PgVectorDir\LICENSE" "$RuntimeDir\LICENSE.pgvector" -Force
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
Write-Host "==> Self-contained smoke test (initdb + CREATE EXTENSION vector + distance query)"
|
|
151
|
-
& "$RuntimeDir\bin\postgres.exe" --version
|
|
152
|
-
if ($LASTEXITCODE -ne 0) { Write-Error "FAIL: postgres.exe --version exit $LASTEXITCODE"; exit 1 }
|
|
153
|
-
|
|
154
|
-
$SmokeData = "$BuildDir\smoke-pgdata"
|
|
155
|
-
$SmokeLog = "$BuildDir\smoke-pg.log"
|
|
156
|
-
$SmokePort = 55899
|
|
157
|
-
if (Test-Path $SmokeData) { Remove-Item -Recurse -Force $SmokeData }
|
|
158
|
-
|
|
159
|
-
& "$RuntimeDir\bin\initdb.exe" -D $SmokeData --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
|
|
160
|
-
if ($LASTEXITCODE -ne 0) { Write-Error "FAIL: initdb"; exit 1 }
|
|
161
|
-
|
|
162
|
-
& "$RuntimeDir\bin\pg_ctl.exe" -D $SmokeData -o "-p $SmokePort -h 127.0.0.1" -l $SmokeLog -w start
|
|
163
|
-
if ($LASTEXITCODE -ne 0) { Write-Error "FAIL: pg_ctl start (see $SmokeLog)"; Get-Content $SmokeLog | Select-Object -Last 30; exit 1 }
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
& "$RuntimeDir\bin\psql.exe" -h 127.0.0.1 -p $SmokePort -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
|
|
167
|
-
if ($LASTEXITCODE -ne 0) { throw "CREATE EXTENSION vector failed" }
|
|
168
|
-
$ExtV = & "$RuntimeDir\bin\psql.exe" -h 127.0.0.1 -p $SmokePort -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
|
|
169
|
-
$Dist = & "$RuntimeDir\bin\psql.exe" -h 127.0.0.1 -p $SmokePort -U postgres -d postgres -tAc "SELECT '[1,2,3]'::vector <-> '[1,2,4]'::vector;"
|
|
170
|
-
Write-Host " vector extension version: $ExtV"
|
|
171
|
-
Write-Host " distance query result: $Dist"
|
|
172
|
-
if ($ExtV.Trim() -ne $PGVECTOR_VERSION) {
|
|
173
|
-
Write-Error "FAIL: extversion='$ExtV' expected='$PGVECTOR_VERSION'"
|
|
174
|
-
exit 1
|
|
175
|
-
}
|
|
176
|
-
Write-Host " PASS smoke (extension load + vector distance)"
|
|
177
|
-
}
|
|
178
|
-
finally {
|
|
179
|
-
& "$RuntimeDir\bin\pg_ctl.exe" -D $SmokeData -m fast stop 2>$null | Out-Null
|
|
180
|
-
Remove-Item -Recurse -Force $SmokeData -ErrorAction SilentlyContinue
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
Write-Host "==> Creating tarball: $OutputName"
|
|
184
|
-
$DistDirFwd = $DistDir.Replace('\', '/')
|
|
185
|
-
$RuntimeDirFwd = $RuntimeDir.Replace('\', '/')
|
|
186
|
-
& tar -czf "$DistDirFwd/$OutputName" -C "$RuntimeDirFwd" .
|
|
187
|
-
if ($LASTEXITCODE -ne 0) { Write-Error "tar failed (exit $LASTEXITCODE)"; exit 1 }
|
|
188
|
-
|
|
189
|
-
Write-Host "==> Generating sha256 sidecar"
|
|
190
|
-
Push-Location $DistDir
|
|
191
|
-
$Hash = (Get-FileHash -Algorithm SHA256 $OutputName).Hash.ToLower()
|
|
192
|
-
"$Hash $OutputName" | Out-File -Encoding ascii "${OutputName}.sha256"
|
|
193
|
-
Pop-Location
|
|
194
|
-
|
|
195
|
-
# ---------------------------------------------------------------------------
|
|
196
|
-
# Phase A: Re-smoke from EXTRACTED tarball with hostile env (cleared PATH,
|
|
197
|
-
# only system32). Catches false-pass where the build host has VC redist /
|
|
198
|
-
# preinstalled DLLs that the tarball might be missing.
|
|
199
|
-
# ---------------------------------------------------------------------------
|
|
200
|
-
Write-Host "==> Re-smoke from extracted tarball (hostile env)"
|
|
201
|
-
$ExtractDir = "$BuildDir\extract-smoke"
|
|
202
|
-
if (Test-Path $ExtractDir) { Remove-Item -Recurse -Force $ExtractDir }
|
|
203
|
-
New-Item -ItemType Directory -Force -Path $ExtractDir | Out-Null
|
|
204
|
-
& tar -xzf "$DistDirFwd/$OutputName" -C ($ExtractDir.Replace('\','/'))
|
|
205
|
-
if ($LASTEXITCODE -ne 0) { Write-Error "extract failed"; exit 1 }
|
|
206
|
-
|
|
207
|
-
$ExtractData = "$ExtractDir\extract-pgdata"
|
|
208
|
-
$ExtractLog = "$ExtractDir\extract-pg.log"
|
|
209
|
-
$ExtractPort = 55898
|
|
210
|
-
|
|
211
|
-
# Snapshot current env, then strip to minimal Windows PATH (no PG14/15/16
|
|
212
|
-
# preinstalled bin, no chocolatey, no MSVC tools).
|
|
213
|
-
$SavedPath = $env:PATH
|
|
214
|
-
$SavedPgRoot = $env:PGROOT
|
|
215
|
-
$env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
|
|
216
|
-
$env:PGROOT = $null
|
|
217
|
-
$env:PGDATA = $null
|
|
218
|
-
|
|
219
|
-
try {
|
|
220
|
-
& "$ExtractDir\bin\postgres.exe" --version
|
|
221
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: postgres --version under hostile env" }
|
|
222
|
-
& "$ExtractDir\bin\initdb.exe" -D $ExtractData --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
|
|
223
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: initdb under hostile env" }
|
|
224
|
-
& "$ExtractDir\bin\pg_ctl.exe" -D $ExtractData -o "-p $ExtractPort -h 127.0.0.1" -l $ExtractLog -w start
|
|
225
|
-
if ($LASTEXITCODE -ne 0) { Get-Content $ExtractLog | Select-Object -Last 30; throw "FAIL: pg_ctl start under hostile env" }
|
|
226
|
-
try {
|
|
227
|
-
& "$ExtractDir\bin\psql.exe" -h 127.0.0.1 -p $ExtractPort -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
|
|
228
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: CREATE EXTENSION vector under hostile env" }
|
|
229
|
-
$ExtV2 = & "$ExtractDir\bin\psql.exe" -h 127.0.0.1 -p $ExtractPort -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
|
|
230
|
-
if ($ExtV2.Trim() -ne $PGVECTOR_VERSION) { throw "FAIL: extracted-smoke extversion='$ExtV2'" }
|
|
231
|
-
Write-Host " PASS extracted-tarball smoke (hostile env)"
|
|
232
|
-
} finally {
|
|
233
|
-
& "$ExtractDir\bin\pg_ctl.exe" -D $ExtractData -m fast stop 2>$null | Out-Null
|
|
234
|
-
}
|
|
235
|
-
} finally {
|
|
236
|
-
$env:PATH = $SavedPath
|
|
237
|
-
$env:PGROOT = $SavedPgRoot
|
|
238
|
-
Remove-Item -Recurse -Force $ExtractDir -ErrorAction SilentlyContinue
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
Write-Host "==> Done: $DistDir\$OutputName"
|
|
242
|
-
Get-Item "$DistDir\$OutputName" | Select-Object Name, Length
|
|
1
|
+
# build-runtime-windows.ps1 — Build PostgreSQL 16 + pgvector runtime on Windows.
|
|
2
|
+
# Uses windows-2022 GHA runner's preinstalled PostgreSQL 16 (consistent
|
|
3
|
+
# pg_config + postgres.exe from same package) — avoids EDB zip's split-version
|
|
4
|
+
# packaging bug that linked pgvector against PG 14 ABI.
|
|
5
|
+
# Builds pgvector from source via MSVC/nmake, then assembles a self-contained
|
|
6
|
+
# runtime tree (bin + lib + share at root). Final smoke: initdb + CREATE
|
|
7
|
+
# EXTENSION vector + distance query.
|
|
8
|
+
# Produces: dist\mixdog-runtime-win32-x64-pg{pgver}-pgvector{vecver}.tar.gz
|
|
9
|
+
|
|
10
|
+
$ErrorActionPreference = 'Stop'
|
|
11
|
+
|
|
12
|
+
$PG_VERSION = '16.4'
|
|
13
|
+
$PGVECTOR_VERSION = '0.8.2'
|
|
14
|
+
$TARGET_OS = $env:TARGET_OS ?? 'win32'
|
|
15
|
+
$TARGET_ARCH = $env:TARGET_ARCH ?? 'x64'
|
|
16
|
+
|
|
17
|
+
# Auto-detect highest preinstalled PG ≥ 16 OR install via chocolatey.
|
|
18
|
+
$PgInstallRoot = 'C:\Program Files\PostgreSQL'
|
|
19
|
+
|
|
20
|
+
function Find-PgRoot {
|
|
21
|
+
if (-not (Test-Path $PgInstallRoot)) { return $null }
|
|
22
|
+
$cands = Get-ChildItem $PgInstallRoot -Directory -ErrorAction SilentlyContinue |
|
|
23
|
+
Where-Object { $_.Name -match '^(\d+)' } |
|
|
24
|
+
Sort-Object { [int]([regex]::Match($_.Name, '^(\d+)').Groups[1].Value) } -Descending
|
|
25
|
+
foreach ($c in $cands) {
|
|
26
|
+
$major = [int]([regex]::Match($c.Name, '^(\d+)').Groups[1].Value)
|
|
27
|
+
if ($major -ge 16 -and (Test-Path "$($c.FullName)\bin\pg_config.exe")) {
|
|
28
|
+
return $c.FullName
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return $null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
$PgRoot = Find-PgRoot
|
|
35
|
+
if (-not $PgRoot) {
|
|
36
|
+
Write-Host "==> No preinstalled PG ≥ 16 found. Installing via chocolatey..."
|
|
37
|
+
if (Test-Path $PgInstallRoot) {
|
|
38
|
+
Write-Host "Existing PG dirs (none usable):"
|
|
39
|
+
Get-ChildItem $PgInstallRoot -Directory -ErrorAction SilentlyContinue | Select-Object Name
|
|
40
|
+
}
|
|
41
|
+
choco install postgresql16 --version=16.4.0 --params '/Password:postgres' -y --no-progress 2>&1 | Out-Host
|
|
42
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "choco install postgresql16 failed (exit $LASTEXITCODE)"; exit 1 }
|
|
43
|
+
$PgRoot = Find-PgRoot
|
|
44
|
+
if (-not $PgRoot) {
|
|
45
|
+
Write-Error "ASSERT FAILED: chocolatey install completed but PG ≥ 16 still not found under $PgInstallRoot"
|
|
46
|
+
Get-ChildItem $PgInstallRoot -Directory -ErrorAction SilentlyContinue | Select-Object Name
|
|
47
|
+
exit 1
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
52
|
+
$RootDir = (Resolve-Path "$ScriptDir\..").Path
|
|
53
|
+
$BuildDir = "$RootDir\build\runtime-win32-$TARGET_ARCH"
|
|
54
|
+
$DistDir = "$RootDir\dist"
|
|
55
|
+
$RuntimeDir = "$BuildDir\runtime"
|
|
56
|
+
|
|
57
|
+
$PgBin = "$PgRoot\bin"
|
|
58
|
+
$PgConfig = "$PgBin\pg_config.exe"
|
|
59
|
+
|
|
60
|
+
$OutputName = "mixdog-runtime-${TARGET_OS}-${TARGET_ARCH}-pg${PG_VERSION}-pgvector${PGVECTOR_VERSION}.tar.gz"
|
|
61
|
+
|
|
62
|
+
Write-Host "==> Using preinstalled PG: $PgRoot"
|
|
63
|
+
& $PgConfig --version
|
|
64
|
+
$RealVersion = (& $PgConfig --version) -replace 'PostgreSQL ', ''
|
|
65
|
+
Write-Host " pg_config reports version: $RealVersion"
|
|
66
|
+
|
|
67
|
+
if (Test-Path $RuntimeDir) { Remove-Item -Recurse -Force $RuntimeDir }
|
|
68
|
+
New-Item -ItemType Directory -Force -Path $BuildDir, $DistDir,
|
|
69
|
+
"$RuntimeDir\bin", "$RuntimeDir\lib", "$RuntimeDir\share" | Out-Null
|
|
70
|
+
|
|
71
|
+
Write-Host "==> Cloning pgvector $PGVECTOR_VERSION"
|
|
72
|
+
$PgVectorDir = "$BuildDir\pgvector"
|
|
73
|
+
$VectorDllBuilt = "$PgVectorDir\vector.dll"
|
|
74
|
+
|
|
75
|
+
if (Test-Path $VectorDllBuilt) {
|
|
76
|
+
Write-Host " Cache hit: vector.dll already built at $VectorDllBuilt"
|
|
77
|
+
} else {
|
|
78
|
+
if (Test-Path $PgVectorDir) { Remove-Item -Recurse -Force $PgVectorDir }
|
|
79
|
+
git clone --branch "v$PGVECTOR_VERSION" --depth 1 `
|
|
80
|
+
https://github.com/pgvector/pgvector.git $PgVectorDir
|
|
81
|
+
|
|
82
|
+
Write-Host "==> Building pgvector (MSVC/nmake against system PG 16)"
|
|
83
|
+
Push-Location $PgVectorDir
|
|
84
|
+
try {
|
|
85
|
+
$VsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
|
86
|
+
$VcVarsAll = & $VsWhere -latest -find 'VC\Auxiliary\Build\vcvarsall.bat' 2>$null | Select-Object -First 1
|
|
87
|
+
if (-not $VcVarsAll) {
|
|
88
|
+
Write-Error "vswhere could not locate vcvarsall.bat — Visual Studio Build Tools required."
|
|
89
|
+
exit 1
|
|
90
|
+
}
|
|
91
|
+
# CRITICAL: prepend $PgRoot\bin to PATH so any bare `pg_config` call
|
|
92
|
+
# inside Makefile.win resolves to PG 16 — runner has PG 14/15
|
|
93
|
+
# preinstalled and would otherwise win the PATH lookup, producing
|
|
94
|
+
# PG14-ABI vector.dll that fails to load in our PG 16 postgres.exe.
|
|
95
|
+
# Set in PowerShell so cmd /c inherits; setting inside the cmd batch
|
|
96
|
+
# via %PATH% loses vcvarsall's additions due to parse-time expansion.
|
|
97
|
+
$env:PATH = "$PgRoot\bin;$env:PATH"
|
|
98
|
+
$env:PGROOT = $PgRoot
|
|
99
|
+
$BuildCmd = "`"$VcVarsAll`" amd64 && nmake /F Makefile.win PG_CONFIG=`"$PgConfig`""
|
|
100
|
+
cmd /c $BuildCmd
|
|
101
|
+
if ($LASTEXITCODE -ne 0) {
|
|
102
|
+
Write-Error "pgvector nmake build failed (exit $LASTEXITCODE)"
|
|
103
|
+
exit 1
|
|
104
|
+
}
|
|
105
|
+
} finally {
|
|
106
|
+
Pop-Location
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
Write-Host "==> Assembling runtime layout — copy bin (.exe + .dll), lib, share from $PgRoot"
|
|
111
|
+
# Copy ALL .exe + .dll from PG bin so postgres.exe + libpq.dll + libcrypto/libssl/
|
|
112
|
+
# libintl/libiconv/icu*/libxml2/libxslt/libwinpthread/libecpg/libpgtypes etc. all
|
|
113
|
+
# ship together. PG 16 install layout puts these all in bin\.
|
|
114
|
+
Copy-Item "$PgBin\*.exe","$PgBin\*.dll" "$RuntimeDir\bin\" -Force
|
|
115
|
+
|
|
116
|
+
# lib\: PG extension modules (incl. contrib like pgcrypto.dll). vector.dll
|
|
117
|
+
# placed here below — PG looks for $libdir/<ext>.dll which resolves to lib\.
|
|
118
|
+
Copy-Item -Recurse -Force "$PgRoot\lib\*" "$RuntimeDir\lib\" -ErrorAction SilentlyContinue
|
|
119
|
+
# share\: extension SQL/control, locale, timezone data, conf samples.
|
|
120
|
+
Copy-Item -Recurse -Force "$PgRoot\share\*" "$RuntimeDir\share\" -ErrorAction SilentlyContinue
|
|
121
|
+
|
|
122
|
+
Write-Host "==> Manually staging pgvector artifacts (avoid pg_config-derived install paths)"
|
|
123
|
+
$RuntimeExtDir = "$RuntimeDir\share\extension"
|
|
124
|
+
New-Item -ItemType Directory -Force -Path $RuntimeExtDir | Out-Null
|
|
125
|
+
Copy-Item "$PgVectorDir\vector.dll" "$RuntimeDir\lib\" -Force
|
|
126
|
+
Copy-Item "$PgVectorDir\vector.control" $RuntimeExtDir -Force
|
|
127
|
+
Copy-Item "$PgVectorDir\sql\vector--*.sql" $RuntimeExtDir -Force
|
|
128
|
+
|
|
129
|
+
Write-Host "==> Asserting runtime layout"
|
|
130
|
+
$VectorControl = "$RuntimeDir\share\extension\vector.control"
|
|
131
|
+
if (-not (Test-Path $VectorControl)) { Write-Error "ASSERT FAILED: $VectorControl not found"; exit 1 }
|
|
132
|
+
$VectorSql = "$RuntimeDir\share\extension\vector--$PGVECTOR_VERSION.sql"
|
|
133
|
+
if (-not (Test-Path $VectorSql)) { Write-Error "ASSERT FAILED: $VectorSql not found"; exit 1 }
|
|
134
|
+
if (-not (Test-Path "$RuntimeDir\lib\vector.dll")) {
|
|
135
|
+
Write-Error "ASSERT FAILED: vector.dll not found in lib\"
|
|
136
|
+
exit 1
|
|
137
|
+
}
|
|
138
|
+
Write-Host " PASS runtime layout"
|
|
139
|
+
|
|
140
|
+
# Licenses
|
|
141
|
+
if (Test-Path "$PgRoot\doc\postgresql\COPYRIGHT") {
|
|
142
|
+
Copy-Item "$PgRoot\doc\postgresql\COPYRIGHT" "$RuntimeDir\LICENSE.postgresql" -Force
|
|
143
|
+
} elseif (Test-Path "$PgRoot\doc\COPYRIGHT") {
|
|
144
|
+
Copy-Item "$PgRoot\doc\COPYRIGHT" "$RuntimeDir\LICENSE.postgresql" -Force
|
|
145
|
+
}
|
|
146
|
+
if (Test-Path "$PgVectorDir\LICENSE") {
|
|
147
|
+
Copy-Item "$PgVectorDir\LICENSE" "$RuntimeDir\LICENSE.pgvector" -Force
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
Write-Host "==> Self-contained smoke test (initdb + CREATE EXTENSION vector + distance query)"
|
|
151
|
+
& "$RuntimeDir\bin\postgres.exe" --version
|
|
152
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "FAIL: postgres.exe --version exit $LASTEXITCODE"; exit 1 }
|
|
153
|
+
|
|
154
|
+
$SmokeData = "$BuildDir\smoke-pgdata"
|
|
155
|
+
$SmokeLog = "$BuildDir\smoke-pg.log"
|
|
156
|
+
$SmokePort = 55899
|
|
157
|
+
if (Test-Path $SmokeData) { Remove-Item -Recurse -Force $SmokeData }
|
|
158
|
+
|
|
159
|
+
& "$RuntimeDir\bin\initdb.exe" -D $SmokeData --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
|
|
160
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "FAIL: initdb"; exit 1 }
|
|
161
|
+
|
|
162
|
+
& "$RuntimeDir\bin\pg_ctl.exe" -D $SmokeData -o "-p $SmokePort -h 127.0.0.1" -l $SmokeLog -w start
|
|
163
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "FAIL: pg_ctl start (see $SmokeLog)"; Get-Content $SmokeLog | Select-Object -Last 30; exit 1 }
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
& "$RuntimeDir\bin\psql.exe" -h 127.0.0.1 -p $SmokePort -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
|
|
167
|
+
if ($LASTEXITCODE -ne 0) { throw "CREATE EXTENSION vector failed" }
|
|
168
|
+
$ExtV = & "$RuntimeDir\bin\psql.exe" -h 127.0.0.1 -p $SmokePort -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
|
|
169
|
+
$Dist = & "$RuntimeDir\bin\psql.exe" -h 127.0.0.1 -p $SmokePort -U postgres -d postgres -tAc "SELECT '[1,2,3]'::vector <-> '[1,2,4]'::vector;"
|
|
170
|
+
Write-Host " vector extension version: $ExtV"
|
|
171
|
+
Write-Host " distance query result: $Dist"
|
|
172
|
+
if ($ExtV.Trim() -ne $PGVECTOR_VERSION) {
|
|
173
|
+
Write-Error "FAIL: extversion='$ExtV' expected='$PGVECTOR_VERSION'"
|
|
174
|
+
exit 1
|
|
175
|
+
}
|
|
176
|
+
Write-Host " PASS smoke (extension load + vector distance)"
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
& "$RuntimeDir\bin\pg_ctl.exe" -D $SmokeData -m fast stop 2>$null | Out-Null
|
|
180
|
+
Remove-Item -Recurse -Force $SmokeData -ErrorAction SilentlyContinue
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
Write-Host "==> Creating tarball: $OutputName"
|
|
184
|
+
$DistDirFwd = $DistDir.Replace('\', '/')
|
|
185
|
+
$RuntimeDirFwd = $RuntimeDir.Replace('\', '/')
|
|
186
|
+
& tar -czf "$DistDirFwd/$OutputName" -C "$RuntimeDirFwd" .
|
|
187
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "tar failed (exit $LASTEXITCODE)"; exit 1 }
|
|
188
|
+
|
|
189
|
+
Write-Host "==> Generating sha256 sidecar"
|
|
190
|
+
Push-Location $DistDir
|
|
191
|
+
$Hash = (Get-FileHash -Algorithm SHA256 $OutputName).Hash.ToLower()
|
|
192
|
+
"$Hash $OutputName" | Out-File -Encoding ascii "${OutputName}.sha256"
|
|
193
|
+
Pop-Location
|
|
194
|
+
|
|
195
|
+
# ---------------------------------------------------------------------------
|
|
196
|
+
# Phase A: Re-smoke from EXTRACTED tarball with hostile env (cleared PATH,
|
|
197
|
+
# only system32). Catches false-pass where the build host has VC redist /
|
|
198
|
+
# preinstalled DLLs that the tarball might be missing.
|
|
199
|
+
# ---------------------------------------------------------------------------
|
|
200
|
+
Write-Host "==> Re-smoke from extracted tarball (hostile env)"
|
|
201
|
+
$ExtractDir = "$BuildDir\extract-smoke"
|
|
202
|
+
if (Test-Path $ExtractDir) { Remove-Item -Recurse -Force $ExtractDir }
|
|
203
|
+
New-Item -ItemType Directory -Force -Path $ExtractDir | Out-Null
|
|
204
|
+
& tar -xzf "$DistDirFwd/$OutputName" -C ($ExtractDir.Replace('\','/'))
|
|
205
|
+
if ($LASTEXITCODE -ne 0) { Write-Error "extract failed"; exit 1 }
|
|
206
|
+
|
|
207
|
+
$ExtractData = "$ExtractDir\extract-pgdata"
|
|
208
|
+
$ExtractLog = "$ExtractDir\extract-pg.log"
|
|
209
|
+
$ExtractPort = 55898
|
|
210
|
+
|
|
211
|
+
# Snapshot current env, then strip to minimal Windows PATH (no PG14/15/16
|
|
212
|
+
# preinstalled bin, no chocolatey, no MSVC tools).
|
|
213
|
+
$SavedPath = $env:PATH
|
|
214
|
+
$SavedPgRoot = $env:PGROOT
|
|
215
|
+
$env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
|
|
216
|
+
$env:PGROOT = $null
|
|
217
|
+
$env:PGDATA = $null
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
& "$ExtractDir\bin\postgres.exe" --version
|
|
221
|
+
if ($LASTEXITCODE -ne 0) { throw "FAIL: postgres --version under hostile env" }
|
|
222
|
+
& "$ExtractDir\bin\initdb.exe" -D $ExtractData --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
|
|
223
|
+
if ($LASTEXITCODE -ne 0) { throw "FAIL: initdb under hostile env" }
|
|
224
|
+
& "$ExtractDir\bin\pg_ctl.exe" -D $ExtractData -o "-p $ExtractPort -h 127.0.0.1" -l $ExtractLog -w start
|
|
225
|
+
if ($LASTEXITCODE -ne 0) { Get-Content $ExtractLog | Select-Object -Last 30; throw "FAIL: pg_ctl start under hostile env" }
|
|
226
|
+
try {
|
|
227
|
+
& "$ExtractDir\bin\psql.exe" -h 127.0.0.1 -p $ExtractPort -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
|
|
228
|
+
if ($LASTEXITCODE -ne 0) { throw "FAIL: CREATE EXTENSION vector under hostile env" }
|
|
229
|
+
$ExtV2 = & "$ExtractDir\bin\psql.exe" -h 127.0.0.1 -p $ExtractPort -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
|
|
230
|
+
if ($ExtV2.Trim() -ne $PGVECTOR_VERSION) { throw "FAIL: extracted-smoke extversion='$ExtV2'" }
|
|
231
|
+
Write-Host " PASS extracted-tarball smoke (hostile env)"
|
|
232
|
+
} finally {
|
|
233
|
+
& "$ExtractDir\bin\pg_ctl.exe" -D $ExtractData -m fast stop 2>$null | Out-Null
|
|
234
|
+
}
|
|
235
|
+
} finally {
|
|
236
|
+
$env:PATH = $SavedPath
|
|
237
|
+
$env:PGROOT = $SavedPgRoot
|
|
238
|
+
Remove-Item -Recurse -Force $ExtractDir -ErrorAction SilentlyContinue
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
Write-Host "==> Done: $DistDir\$OutputName"
|
|
242
|
+
Get-Item "$DistDir\$OutputName" | Select-Object Name, Length
|
|
@@ -15,4 +15,4 @@
|
|
|
15
15
|
{ "id": "uc5-yesterday", "label": "UC5 calendar yesterday", "args": { "period": "yesterday", "limit": 10 }, "expect": "browse" },
|
|
16
16
|
{ "id": "uc5-thisweek", "label": "UC5 calendar this_week", "args": { "period": "this_week", "limit": 10 }, "expect": "browse" },
|
|
17
17
|
{ "id": "uc6-category", "label": "UC6 category decision 7d", "args": { "period": "7d", "category": "decision", "limit": 10 }, "expect": "browse" }
|
|
18
|
-
]
|
|
18
|
+
]
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
# smoke-runtime-negative.ps1 — Negative-path tests against released win32-x64
|
|
2
|
-
# runtime tarball. Validates: download, sha256, corrupt-tarball, fresh-extract
|
|
3
|
-
# boot, double-init refusal, hostile-env survival.
|
|
4
|
-
#
|
|
5
|
-
# Env: TAG / OS / ARCH / RUNTIME_RELEASE_REPOSITORY (default tribgames/mixdog)
|
|
6
|
-
|
|
7
|
-
$ErrorActionPreference = 'Stop'
|
|
8
|
-
|
|
9
|
-
$Tag = if ($env:TAG) { $env:TAG } else { 'runtime-v0.4.0' }
|
|
10
|
-
$Os = if ($env:OS) { $env:OS } else { 'win32' }
|
|
11
|
-
$Arch = if ($env:ARCH) { $env:ARCH } else { 'x64' }
|
|
12
|
-
$ReleaseRepo = if ($env:RUNTIME_RELEASE_REPOSITORY) { $env:RUNTIME_RELEASE_REPOSITORY } else { 'tribgames/mixdog' }
|
|
13
|
-
$PgVer = '16.4'
|
|
14
|
-
$PgvectorVer = '0.8.2'
|
|
15
|
-
|
|
16
|
-
$Asset = "mixdog-runtime-${Os}-${Arch}-pg${PgVer}-pgvector${PgvectorVer}.tar.gz"
|
|
17
|
-
$Url = "https://github.com/${ReleaseRepo}/releases/download/${Tag}/${Asset}"
|
|
18
|
-
|
|
19
|
-
$Work = New-Item -ItemType Directory -Force -Path "$env:TEMP\smoke-$([guid]::NewGuid().ToString('N'))" | Select-Object -ExpandProperty FullName
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
Write-Host "==> Negative-path smoke for ${Os}-${Arch} from $Url"
|
|
23
|
-
|
|
24
|
-
Write-Host "==> Test 1: HEAD reaches release asset"
|
|
25
|
-
$resp = Invoke-WebRequest -Uri $Url -Method Head -UseBasicParsing -ErrorAction Stop
|
|
26
|
-
Write-Host " HTTP $($resp.StatusCode)"
|
|
27
|
-
|
|
28
|
-
Write-Host "==> Test 2: full download + sha256"
|
|
29
|
-
$TarPath = Join-Path $Work $Asset
|
|
30
|
-
Invoke-WebRequest -Uri $Url -OutFile $TarPath -UseBasicParsing
|
|
31
|
-
$sha = (Get-FileHash -Algorithm SHA256 $TarPath).Hash.ToLower()
|
|
32
|
-
Write-Host " sha256=$sha"
|
|
33
|
-
|
|
34
|
-
Write-Host "==> Test 3: corrupt tarball — flip a byte and ensure tar errors"
|
|
35
|
-
$CorruptPath = "$Work\corrupt.tar.gz"
|
|
36
|
-
Copy-Item $TarPath $CorruptPath
|
|
37
|
-
$bytes = [byte[]]::new(1); $rand = [System.Random]::new(); $rand.NextBytes($bytes)
|
|
38
|
-
$stream = [System.IO.File]::OpenWrite($CorruptPath)
|
|
39
|
-
$stream.Position = 102400
|
|
40
|
-
$stream.Write($bytes, 0, 1)
|
|
41
|
-
$stream.Close()
|
|
42
|
-
$CorruptDir = "$Work\corrupt"
|
|
43
|
-
New-Item -ItemType Directory -Force -Path $CorruptDir | Out-Null
|
|
44
|
-
$TarProc = Start-Process -FilePath tar -ArgumentList @('-xzf', $CorruptPath, '-C', $CorruptDir.Replace('\','/')) -Wait:$false -PassThru -WindowStyle Hidden
|
|
45
|
-
if (-not $TarProc.WaitForExit(15000)) {
|
|
46
|
-
Stop-Process -Id $TarProc.Id -Force -ErrorAction SilentlyContinue
|
|
47
|
-
Write-Host " PASS: corrupted tarball extraction timed out and was stopped"
|
|
48
|
-
} elseif ($TarProc.ExitCode -eq 0) {
|
|
49
|
-
Write-Host " WARN: corrupted tarball extracted without error (tar gzip recovery)"
|
|
50
|
-
} else {
|
|
51
|
-
Write-Host " PASS: corrupted tarball rejected by tar (exit $($TarProc.ExitCode))"
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
Write-Host "==> Test 4: fresh-extract boot (extension load + distance query)"
|
|
55
|
-
$FreshDir = "$Work\fresh"
|
|
56
|
-
New-Item -ItemType Directory -Force -Path $FreshDir | Out-Null
|
|
57
|
-
& tar -xzf $TarPath -C ($FreshDir.Replace('\','/'))
|
|
58
|
-
if ($LASTEXITCODE -ne 0) { throw "fresh extract failed" }
|
|
59
|
-
|
|
60
|
-
$PgBin = "$FreshDir\bin"
|
|
61
|
-
$Data = "$FreshDir\pgdata"
|
|
62
|
-
$Log = "$FreshDir\pg.log"
|
|
63
|
-
$Port = 55897
|
|
64
|
-
|
|
65
|
-
# Hostile env: minimal PATH (System32 only), no PGROOT/PGDATA
|
|
66
|
-
$SavedPath = $env:PATH
|
|
67
|
-
$SavedPgRoot = $env:PGROOT
|
|
68
|
-
$env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
|
|
69
|
-
$env:PGROOT = $null
|
|
70
|
-
$env:PGDATA = $null
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
& "$PgBin\postgres.exe" --version
|
|
74
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: postgres --version" }
|
|
75
|
-
& "$PgBin\initdb.exe" -D $Data --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
|
|
76
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: initdb" }
|
|
77
|
-
& "$PgBin\pg_ctl.exe" -D $Data -o "-p $Port -h 127.0.0.1" -l $Log -w start
|
|
78
|
-
if ($LASTEXITCODE -ne 0) { Get-Content $Log | Select-Object -Last 30; throw "FAIL: pg_ctl start" }
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
& "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
|
|
82
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: CREATE EXTENSION" }
|
|
83
|
-
$ExtV = & "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
|
|
84
|
-
if ($ExtV.Trim() -ne $PgvectorVer) { throw "FAIL: extversion='$ExtV' expected='$PgvectorVer'" }
|
|
85
|
-
Write-Host " PASS: fresh-extract boot + vector extension"
|
|
86
|
-
} finally {
|
|
87
|
-
& "$PgBin\pg_ctl.exe" -D $Data -m fast stop 2>$null | Out-Null
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
Write-Host "==> Test 5: second initdb on initialized dir refused"
|
|
91
|
-
$rc = (Start-Process -FilePath "$PgBin\initdb.exe" -ArgumentList "-D",$Data,"-U","postgres" -Wait -PassThru -NoNewWindow).ExitCode
|
|
92
|
-
if ($rc -eq 0) {
|
|
93
|
-
Write-Host " WARN: second initdb succeeded (unexpected)"
|
|
94
|
-
} else {
|
|
95
|
-
Write-Host " PASS: second initdb refused (exit $rc)"
|
|
96
|
-
}
|
|
97
|
-
} finally {
|
|
98
|
-
$env:PATH = $SavedPath
|
|
99
|
-
$env:PGROOT = $SavedPgRoot
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
Write-Host "==> All negative-path smokes: PASS"
|
|
103
|
-
}
|
|
104
|
-
finally {
|
|
105
|
-
Remove-Item -Recurse -Force $Work -ErrorAction SilentlyContinue
|
|
106
|
-
}
|
|
1
|
+
# smoke-runtime-negative.ps1 — Negative-path tests against released win32-x64
|
|
2
|
+
# runtime tarball. Validates: download, sha256, corrupt-tarball, fresh-extract
|
|
3
|
+
# boot, double-init refusal, hostile-env survival.
|
|
4
|
+
#
|
|
5
|
+
# Env: TAG / OS / ARCH / RUNTIME_RELEASE_REPOSITORY (default tribgames/mixdog)
|
|
6
|
+
|
|
7
|
+
$ErrorActionPreference = 'Stop'
|
|
8
|
+
|
|
9
|
+
$Tag = if ($env:TAG) { $env:TAG } else { 'runtime-v0.4.0' }
|
|
10
|
+
$Os = if ($env:OS) { $env:OS } else { 'win32' }
|
|
11
|
+
$Arch = if ($env:ARCH) { $env:ARCH } else { 'x64' }
|
|
12
|
+
$ReleaseRepo = if ($env:RUNTIME_RELEASE_REPOSITORY) { $env:RUNTIME_RELEASE_REPOSITORY } else { 'tribgames/mixdog' }
|
|
13
|
+
$PgVer = '16.4'
|
|
14
|
+
$PgvectorVer = '0.8.2'
|
|
15
|
+
|
|
16
|
+
$Asset = "mixdog-runtime-${Os}-${Arch}-pg${PgVer}-pgvector${PgvectorVer}.tar.gz"
|
|
17
|
+
$Url = "https://github.com/${ReleaseRepo}/releases/download/${Tag}/${Asset}"
|
|
18
|
+
|
|
19
|
+
$Work = New-Item -ItemType Directory -Force -Path "$env:TEMP\smoke-$([guid]::NewGuid().ToString('N'))" | Select-Object -ExpandProperty FullName
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
Write-Host "==> Negative-path smoke for ${Os}-${Arch} from $Url"
|
|
23
|
+
|
|
24
|
+
Write-Host "==> Test 1: HEAD reaches release asset"
|
|
25
|
+
$resp = Invoke-WebRequest -Uri $Url -Method Head -UseBasicParsing -ErrorAction Stop
|
|
26
|
+
Write-Host " HTTP $($resp.StatusCode)"
|
|
27
|
+
|
|
28
|
+
Write-Host "==> Test 2: full download + sha256"
|
|
29
|
+
$TarPath = Join-Path $Work $Asset
|
|
30
|
+
Invoke-WebRequest -Uri $Url -OutFile $TarPath -UseBasicParsing
|
|
31
|
+
$sha = (Get-FileHash -Algorithm SHA256 $TarPath).Hash.ToLower()
|
|
32
|
+
Write-Host " sha256=$sha"
|
|
33
|
+
|
|
34
|
+
Write-Host "==> Test 3: corrupt tarball — flip a byte and ensure tar errors"
|
|
35
|
+
$CorruptPath = "$Work\corrupt.tar.gz"
|
|
36
|
+
Copy-Item $TarPath $CorruptPath
|
|
37
|
+
$bytes = [byte[]]::new(1); $rand = [System.Random]::new(); $rand.NextBytes($bytes)
|
|
38
|
+
$stream = [System.IO.File]::OpenWrite($CorruptPath)
|
|
39
|
+
$stream.Position = 102400
|
|
40
|
+
$stream.Write($bytes, 0, 1)
|
|
41
|
+
$stream.Close()
|
|
42
|
+
$CorruptDir = "$Work\corrupt"
|
|
43
|
+
New-Item -ItemType Directory -Force -Path $CorruptDir | Out-Null
|
|
44
|
+
$TarProc = Start-Process -FilePath tar -ArgumentList @('-xzf', $CorruptPath, '-C', $CorruptDir.Replace('\','/')) -Wait:$false -PassThru -WindowStyle Hidden
|
|
45
|
+
if (-not $TarProc.WaitForExit(15000)) {
|
|
46
|
+
Stop-Process -Id $TarProc.Id -Force -ErrorAction SilentlyContinue
|
|
47
|
+
Write-Host " PASS: corrupted tarball extraction timed out and was stopped"
|
|
48
|
+
} elseif ($TarProc.ExitCode -eq 0) {
|
|
49
|
+
Write-Host " WARN: corrupted tarball extracted without error (tar gzip recovery)"
|
|
50
|
+
} else {
|
|
51
|
+
Write-Host " PASS: corrupted tarball rejected by tar (exit $($TarProc.ExitCode))"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
Write-Host "==> Test 4: fresh-extract boot (extension load + distance query)"
|
|
55
|
+
$FreshDir = "$Work\fresh"
|
|
56
|
+
New-Item -ItemType Directory -Force -Path $FreshDir | Out-Null
|
|
57
|
+
& tar -xzf $TarPath -C ($FreshDir.Replace('\','/'))
|
|
58
|
+
if ($LASTEXITCODE -ne 0) { throw "fresh extract failed" }
|
|
59
|
+
|
|
60
|
+
$PgBin = "$FreshDir\bin"
|
|
61
|
+
$Data = "$FreshDir\pgdata"
|
|
62
|
+
$Log = "$FreshDir\pg.log"
|
|
63
|
+
$Port = 55897
|
|
64
|
+
|
|
65
|
+
# Hostile env: minimal PATH (System32 only), no PGROOT/PGDATA
|
|
66
|
+
$SavedPath = $env:PATH
|
|
67
|
+
$SavedPgRoot = $env:PGROOT
|
|
68
|
+
$env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
|
|
69
|
+
$env:PGROOT = $null
|
|
70
|
+
$env:PGDATA = $null
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
& "$PgBin\postgres.exe" --version
|
|
74
|
+
if ($LASTEXITCODE -ne 0) { throw "FAIL: postgres --version" }
|
|
75
|
+
& "$PgBin\initdb.exe" -D $Data --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
|
|
76
|
+
if ($LASTEXITCODE -ne 0) { throw "FAIL: initdb" }
|
|
77
|
+
& "$PgBin\pg_ctl.exe" -D $Data -o "-p $Port -h 127.0.0.1" -l $Log -w start
|
|
78
|
+
if ($LASTEXITCODE -ne 0) { Get-Content $Log | Select-Object -Last 30; throw "FAIL: pg_ctl start" }
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
& "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
|
|
82
|
+
if ($LASTEXITCODE -ne 0) { throw "FAIL: CREATE EXTENSION" }
|
|
83
|
+
$ExtV = & "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
|
|
84
|
+
if ($ExtV.Trim() -ne $PgvectorVer) { throw "FAIL: extversion='$ExtV' expected='$PgvectorVer'" }
|
|
85
|
+
Write-Host " PASS: fresh-extract boot + vector extension"
|
|
86
|
+
} finally {
|
|
87
|
+
& "$PgBin\pg_ctl.exe" -D $Data -m fast stop 2>$null | Out-Null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Write-Host "==> Test 5: second initdb on initialized dir refused"
|
|
91
|
+
$rc = (Start-Process -FilePath "$PgBin\initdb.exe" -ArgumentList "-D",$Data,"-U","postgres" -Wait -PassThru -NoNewWindow).ExitCode
|
|
92
|
+
if ($rc -eq 0) {
|
|
93
|
+
Write-Host " WARN: second initdb succeeded (unexpected)"
|
|
94
|
+
} else {
|
|
95
|
+
Write-Host " PASS: second initdb refused (exit $rc)"
|
|
96
|
+
}
|
|
97
|
+
} finally {
|
|
98
|
+
$env:PATH = $SavedPath
|
|
99
|
+
$env:PGROOT = $SavedPgRoot
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
Write-Host "==> All negative-path smokes: PASS"
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
Remove-Item -Recurse -Force $Work -ErrorAction SilentlyContinue
|
|
106
|
+
}
|
|
@@ -6,29 +6,27 @@ kind: retrieval
|
|
|
6
6
|
|
|
7
7
|
# Role: explorer
|
|
8
8
|
|
|
9
|
-
You are a one-shot locator, not a researcher. You find WHERE, never WHY
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
You are a one-shot locator, not a researcher. You find WHERE, never WHY —
|
|
10
|
+
no understanding code, explaining behaviour, or tracing logic. Coordinates
|
|
11
|
+
are the entire deliverable.
|
|
12
12
|
|
|
13
|
-
Default shape: ONE
|
|
14
|
-
a single `grep`
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
turn means turn 1 under-batched.
|
|
13
|
+
Default shape: ONE maximal-batch turn, then the answer. Fire everything at
|
|
14
|
+
once: a single `grep` whose pattern[] carries ALL literal strings/errors/
|
|
15
|
+
identifier guesses — synonyms, casings, variants — plus `code_graph`/`find`/
|
|
16
|
+
`glob` in the SAME turn when useful. Width is free, turns are not.
|
|
18
17
|
|
|
19
|
-
Answer straight from search output:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
`dist`/generated hits are leads, not answers: trace them back to source.
|
|
18
|
+
Answer straight from search output: hits already carry `path:line` — never
|
|
19
|
+
spend a turn on `read` to confirm or polish an anchor. `dist`/generated
|
|
20
|
+
hits are leads, not answers: trace them to source.
|
|
23
21
|
|
|
24
|
-
Budget: 5
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
best-so-far
|
|
22
|
+
Budget: 5 turns of maximal batches. Credible `path:line` on screen means the
|
|
23
|
+
search is OVER — answer in that turn; no verifying or collecting extras;
|
|
24
|
+
mark weak anchors `?`. Turns 2-5 exist ONLY for a zero-anchor turn 1: derive
|
|
25
|
+
new tokens from returned paths/names or widen scope, packing ALL candidates
|
|
26
|
+
into the next batch. Concept queries: grep implementation vocabulary
|
|
27
|
+
(file/dir names, symbol fragments, config keys). `EXPLORATION_FAILED` only
|
|
28
|
+
after all 5 turns found zero anchors — giving up early is as wrong as
|
|
29
|
+
over-searching; at turn 5 answer best-so-far.
|
|
32
30
|
|
|
33
31
|
Answer format, nothing else:
|
|
34
32
|
- up to 5 lines: `path:line — symbol/name — short reason` (append `?` if weak)
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
# Channels
|
|
2
|
-
|
|
3
|
-
- Channel features are handled by the runtime.
|
|
1
|
+
# Channels
|
|
2
|
+
|
|
3
|
+
- Channel features are handled by the runtime.
|
|
@@ -254,6 +254,15 @@ function _codexMetadataBase(entry, { poolKey, cacheKey, sendOpts } = {}) {
|
|
|
254
254
|
turn_id: turnId,
|
|
255
255
|
window_id: windowId,
|
|
256
256
|
request_kind: requestKind,
|
|
257
|
+
// Richer codex turn-metadata fields (responses_metadata.rs:264-280:
|
|
258
|
+
// thread_source "user" per protocol.rs:2751-2765, sandbox label).
|
|
259
|
+
// A/B 2026-07-04 (rvA/rvB interleaved, 24 sessions/arm): no effect
|
|
260
|
+
// (it2 full 3 vs 2, miss 2 vs 3 — noise). Default OFF; keep the knob
|
|
261
|
+
// for future probes if the backend starts gating on payload richness.
|
|
262
|
+
...(process.env.MIXDOG_OAI_TURN_METADATA_RICH === '1' ? {
|
|
263
|
+
thread_source: 'user',
|
|
264
|
+
sandbox: 'read-only',
|
|
265
|
+
} : {}),
|
|
257
266
|
turn_started_at_unix_ms: startedAt,
|
|
258
267
|
};
|
|
259
268
|
const metadata = {
|
|
@@ -15,7 +15,7 @@ export const EXPLORE_TOOL = {
|
|
|
15
15
|
name: 'explore',
|
|
16
16
|
title: 'Explore',
|
|
17
17
|
annotations: { title: 'Explore', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
18
|
-
description: 'Repo anchor locator
|
|
18
|
+
description: 'Repo anchor locator: broad/uncertain targets, no known path. Array = independent targets.',
|
|
19
19
|
inputSchema: {
|
|
20
20
|
type: 'object',
|
|
21
21
|
properties: {
|
|
@@ -70,7 +70,7 @@ function escapeXml(str) {
|
|
|
70
70
|
// reminder. The full no-verdict contract lives at system level
|
|
71
71
|
// (rules/agent/30-explorer.md).
|
|
72
72
|
export function buildExplorerPrompt(query) {
|
|
73
|
-
return `<query>${escapeXml(query)}</query>\nReminder: coordinates only — WHERE, never WHY.
|
|
73
|
+
return `<query>${escapeXml(query)}</query>\nReminder: coordinates only — WHERE, never WHY. Budget: 5 turns of maximal batches, ideally 1. Turn 1 fires everything at once: one grep whose pattern[] packs ALL token variants, plus code_graph/find/glob in the SAME turn when useful — width is free, turns are not. Answer straight from search output — hits already carry path:line; never read to confirm, polish, or understand. Before every call ask: is a credible anchor already on screen? If yes STOP and answer now, marking weak anchors with ?. EXPLORATION_FAILED only after all 5 turns found zero anchors; at turn 5 answer with best-so-far. Output only anchor lines formatted as path:line — symbol/name — short reason, or EXPLORATION_FAILED. No preamble, bullets, numbering, headings, summary, code quotes, analysis, verdicts, ratings, or recommendations.`;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export function normalizeExploreQueries(rawQuery) {
|