feat: absorb phase13 templates rules clauses
This commit is contained in:
@@ -184,6 +184,8 @@ with engine.connect() as conn:
|
||||
"contract_template_versions",
|
||||
"review_rules",
|
||||
"review_rule_versions",
|
||||
"standard_clauses",
|
||||
"standard_clause_versions",
|
||||
"prompt_assets",
|
||||
"prompt_asset_versions",
|
||||
"prompt_asset_run_links",
|
||||
@@ -212,6 +214,14 @@ with engine.connect() as conn:
|
||||
),
|
||||
"review_rules_published": published_count(conn, "review_rules"),
|
||||
"review_rule_versions": count_table(conn, "review_rule_versions"),
|
||||
"standard_clauses": count_table(conn, "standard_clauses"),
|
||||
"standard_clauses_active": (
|
||||
count_table(conn, "standard_clauses", "is_active = true")
|
||||
if has_column("standard_clauses", "is_active")
|
||||
else 0
|
||||
),
|
||||
"standard_clauses_published": published_count(conn, "standard_clauses"),
|
||||
"standard_clause_versions": count_table(conn, "standard_clause_versions"),
|
||||
"prompt_assets": count_table(conn, "prompt_assets"),
|
||||
"prompts_published": published_count(conn, "prompt_assets"),
|
||||
"prompt_asset_versions": count_table(conn, "prompt_asset_versions"),
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
param(
|
||||
[string]$RemoteHost = "192.168.3.90",
|
||||
[string]$RemoteUser = "root",
|
||||
[string]$BackendContainer = "ai-contract-backend-restore",
|
||||
[string]$SshKeyPath = "$HOME\.ssh\id_rsa",
|
||||
[switch]$UseSshpass,
|
||||
[string]$TenantId = "tenant-demo-001",
|
||||
[string]$UserId = "codex-autonomous-approval",
|
||||
[string]$DisplayName = "CodexAutonomousApprovalMode",
|
||||
[ValidateSet("none", "sqlite_phase13_assets")]
|
||||
[string]$BootstrapMode = "none",
|
||||
[switch]$DryRun,
|
||||
[switch]$NoPublish,
|
||||
[string]$ArtifactRoot = ""
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Resolve-SshpassPath {
|
||||
$command = Get-Command sshpass.exe -ErrorAction SilentlyContinue
|
||||
if ($null -ne $command) {
|
||||
return $command.Source
|
||||
}
|
||||
|
||||
$candidates = @(
|
||||
(Join-Path $env:LOCALAPPDATA "Microsoft\WinGet\Packages\xhcoding.sshpass-win32_Microsoft.Winget.Source_8wekyb3d8bbwe\sshpass.exe")
|
||||
)
|
||||
foreach ($candidate in $candidates) {
|
||||
if (Test-Path $candidate) {
|
||||
return $candidate
|
||||
}
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
function ConvertTo-ShellSingleQuote {
|
||||
param([string]$Value)
|
||||
return "'" + ($Value -replace "'", "'`"`"`'") + "'"
|
||||
}
|
||||
|
||||
function Invoke-LoggedCommand {
|
||||
param(
|
||||
[string]$Name,
|
||||
[string]$FilePath,
|
||||
[string[]]$Arguments,
|
||||
[string]$LogDir
|
||||
)
|
||||
|
||||
$logPath = Join-Path $LogDir "$Name.log"
|
||||
$previousErrorActionPreference = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
try {
|
||||
$output = & $FilePath @Arguments 2>&1
|
||||
$exitCode = if ($LASTEXITCODE -is [int]) { $LASTEXITCODE } else { 0 }
|
||||
} finally {
|
||||
$ErrorActionPreference = $previousErrorActionPreference
|
||||
}
|
||||
|
||||
$outputText = ($output -join [Environment]::NewLine)
|
||||
$outputText | Set-Content -Encoding UTF8 -Path $logPath
|
||||
if ($exitCode -ne 0) {
|
||||
throw "$Name failed with exit code $exitCode. See $logPath"
|
||||
}
|
||||
return $outputText
|
||||
}
|
||||
|
||||
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
||||
if (-not (Test-Path "$HOME\.Codex\skills\gstack\bin")) {
|
||||
throw "GSTACK_MISSING: gstack is required for AI-assisted work in this repo."
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($ArtifactRoot)) {
|
||||
$ArtifactRoot = Join-Path $repoRoot "project-docs\qa-artifacts\phase13-template-rule-clause-absorption"
|
||||
}
|
||||
$timestamp = Get-Date -Format "yyyy-MM-ddTHH-mm-ss"
|
||||
$artifactDir = Join-Path $ArtifactRoot $timestamp
|
||||
New-Item -ItemType Directory -Force -Path $artifactDir | Out-Null
|
||||
|
||||
$seedToolPath = Join-Path $repoRoot "backend\tools\seed_phase13_template_rule_clause_assets.py"
|
||||
$phase13LibraryPath = Join-Path $repoRoot "project-docs\phase13-legal-knowledge-template-library"
|
||||
foreach ($requiredPath in @($seedToolPath, $phase13LibraryPath)) {
|
||||
if (-not (Test-Path -LiteralPath $requiredPath -PathType Leaf)) {
|
||||
if (-not (Test-Path -LiteralPath $requiredPath -PathType Container)) {
|
||||
throw "Required input path does not exist: $requiredPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$authMode = ""
|
||||
$sshpassPath = $null
|
||||
if ($UseSshpass -or -not [string]::IsNullOrWhiteSpace($env:SSHPASS)) {
|
||||
$sshpassPath = Resolve-SshpassPath
|
||||
if ([string]::IsNullOrWhiteSpace($sshpassPath)) {
|
||||
throw "sshpass.exe not found. Install sshpass or use SSH key auth."
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($env:SSHPASS)) {
|
||||
throw "SSHPASS environment variable is empty."
|
||||
}
|
||||
$authMode = "sshpass"
|
||||
} elseif (Test-Path $SshKeyPath) {
|
||||
$authMode = "key"
|
||||
} else {
|
||||
throw "SSH key not found and SSHPASS is not configured."
|
||||
}
|
||||
|
||||
$target = "${RemoteUser}@${RemoteHost}"
|
||||
$remoteWorkDir = "/tmp/ai-contract-phase13-absorption-$timestamp"
|
||||
$containerScript = "$remoteWorkDir/seed_phase13_template_rule_clause_assets.py"
|
||||
$containerRepoRoot = "$remoteWorkDir/repo"
|
||||
$containerLibraryRoot = "$containerRepoRoot/project-docs/phase13-legal-knowledge-template-library"
|
||||
$containerOutput = "$remoteWorkDir/output"
|
||||
|
||||
if ($authMode -eq "sshpass") {
|
||||
$sshFile = $sshpassPath
|
||||
$sshPrefix = @("-e", "ssh")
|
||||
$scpPrefix = @("-e", "scp")
|
||||
} else {
|
||||
$sshFile = "ssh"
|
||||
$sshPrefix = @("-i", $SshKeyPath)
|
||||
$scpPrefix = @("-i", $SshKeyPath)
|
||||
}
|
||||
|
||||
$sshCommon = @("-o", "StrictHostKeyChecking=accept-new", "-o", "ConnectTimeout=10")
|
||||
$scpCommon = @("-o", "StrictHostKeyChecking=accept-new", "-o", "ConnectTimeout=10")
|
||||
if ($authMode -eq "key") {
|
||||
$sshCommon = @("-o", "BatchMode=yes") + $sshCommon
|
||||
$scpCommon = @("-o", "BatchMode=yes") + $scpCommon
|
||||
}
|
||||
|
||||
Invoke-LoggedCommand -Name "remote-mkdir" -FilePath $sshFile -Arguments ($sshPrefix + $sshCommon + @($target, "mkdir -p $(ConvertTo-ShellSingleQuote $remoteWorkDir) $(ConvertTo-ShellSingleQuote "$remoteWorkDir/project-docs")")) -LogDir $artifactDir | Out-Null
|
||||
|
||||
Invoke-LoggedCommand -Name "scp-seed-tool" -FilePath $(if ($authMode -eq "sshpass") { $sshpassPath } else { "scp" }) -Arguments ($scpPrefix + $scpCommon + @($seedToolPath, "${target}:$remoteWorkDir/seed_phase13_template_rule_clause_assets.py")) -LogDir $artifactDir | Out-Null
|
||||
|
||||
Invoke-LoggedCommand -Name "scp-phase13-library" -FilePath $(if ($authMode -eq "sshpass") { $sshpassPath } else { "scp" }) -Arguments ($scpPrefix + $scpCommon + @("-r", $phase13LibraryPath, "${target}:$remoteWorkDir/project-docs/")) -LogDir $artifactDir | Out-Null
|
||||
|
||||
$remoteCommandParts = @(
|
||||
"docker exec $BackendContainer sh -lc $(ConvertTo-ShellSingleQuote "rm -rf $remoteWorkDir && mkdir -p $remoteWorkDir $containerRepoRoot $containerRepoRoot/project-docs")",
|
||||
"docker cp $remoteWorkDir/seed_phase13_template_rule_clause_assets.py ${BackendContainer}:$containerScript",
|
||||
"docker cp $remoteWorkDir/project-docs/phase13-legal-knowledge-template-library ${BackendContainer}:$containerRepoRoot/project-docs/phase13-legal-knowledge-template-library"
|
||||
)
|
||||
$seedArgs = @(
|
||||
"PYTHONPATH=/app python $(ConvertTo-ShellSingleQuote $containerScript)",
|
||||
"--repo-root $(ConvertTo-ShellSingleQuote $containerRepoRoot)",
|
||||
"--library-root $(ConvertTo-ShellSingleQuote $containerLibraryRoot)",
|
||||
"--output-dir $(ConvertTo-ShellSingleQuote $containerOutput)",
|
||||
"--tenant-id $(ConvertTo-ShellSingleQuote $TenantId)",
|
||||
"--user-id $(ConvertTo-ShellSingleQuote $UserId)",
|
||||
"--display-name $(ConvertTo-ShellSingleQuote $DisplayName)",
|
||||
"--bootstrap-mode $(ConvertTo-ShellSingleQuote $BootstrapMode)"
|
||||
)
|
||||
if ($DryRun) {
|
||||
$seedArgs += "--dry-run"
|
||||
}
|
||||
if ($NoPublish) {
|
||||
$seedArgs += "--no-publish"
|
||||
}
|
||||
$seedCommand = "cd /app && " + ($seedArgs -join " ")
|
||||
$remoteCommandParts += "docker exec $BackendContainer sh -lc $(ConvertTo-ShellSingleQuote $seedCommand)"
|
||||
$remoteCommandParts += "docker cp ${BackendContainer}:$containerOutput $remoteWorkDir/output"
|
||||
|
||||
$remoteCommand = $remoteCommandParts -join " && "
|
||||
Invoke-LoggedCommand -Name "remote-seed-phase13-assets" -FilePath $sshFile -Arguments ($sshPrefix + $sshCommon + @($target, $remoteCommand)) -LogDir $artifactDir | Out-Null
|
||||
|
||||
Invoke-LoggedCommand -Name "scp-seed-output" -FilePath $(if ($authMode -eq "sshpass") { $sshpassPath } else { "scp" }) -Arguments ($scpPrefix + $scpCommon + @("-r", "${target}:$remoteWorkDir/output/.", $artifactDir)) -LogDir $artifactDir | Out-Null
|
||||
|
||||
Write-Output "PHASE13_TEMPLATE_RULE_CLAUSE_ABSORPTION_PASS $artifactDir"
|
||||
Reference in New Issue
Block a user