Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5cd964e51 | ||
|
|
959c89d47b | ||
|
|
760f671077 |
@@ -4,6 +4,7 @@ services:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/images/postgres.Dockerfile
|
||||
args: { SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" }
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-assistant}
|
||||
@@ -31,7 +32,7 @@ services:
|
||||
volumes: ["assistant_nats:/data"]
|
||||
|
||||
notification-receiver:
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: notification-receiver } }
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: notification-receiver, SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" } }
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
LISTEN_ADDR: ":8085"
|
||||
@@ -50,7 +51,7 @@ services:
|
||||
retries: 10
|
||||
|
||||
core-runtime:
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: core-runtime } }
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: core-runtime, SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" } }
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
LISTEN_ADDR: ":8080"
|
||||
@@ -74,7 +75,7 @@ services:
|
||||
- assistant_core_secrets:/run/secrets:ro
|
||||
|
||||
continuity-runtime:
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: continuity-runtime } }
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: continuity-runtime, SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" } }
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
LISTEN_ADDR: ":8081"
|
||||
@@ -87,7 +88,7 @@ services:
|
||||
COMMIT_EXECUTOR_TOKEN: ${COMMIT_EXECUTOR_TOKEN}
|
||||
|
||||
commit-runtime:
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: commit-runtime } }
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: commit-runtime, SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" } }
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
LISTEN_ADDR: ":8082"
|
||||
@@ -109,12 +110,12 @@ services:
|
||||
- assistant_notification_writer_secret:/run/notification-writer:ro
|
||||
|
||||
cognitive-worker:
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: cognitive-worker } }
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: cognitive-worker, SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" } }
|
||||
restart: unless-stopped
|
||||
environment: { LISTEN_ADDR: ":8083" }
|
||||
|
||||
creator-web:
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: creator-web } }
|
||||
build: { context: .., dockerfile: deploy/images/runtime.Dockerfile, args: { TARGET: creator-web, SOURCE_REVISION: "${ASSISTANT_SOURCE_REVISION:-unknown}" } }
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
LISTEN_ADDR: ":8084"
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
FROM postgres:18.6-alpine
|
||||
ARG SOURCE_REVISION=unknown
|
||||
LABEL org.opencontainers.image.revision=$SOURCE_REVISION \
|
||||
org.opencontainers.image.source="https://git.cin.su/m/Assistant.git"
|
||||
|
||||
COPY database/bootstrap/001_roles_and_schemas.sql /docker-entrypoint-initdb.d/001_roles_and_schemas.sql
|
||||
COPY deploy/images/002_owner_passwords.sh /docker-entrypoint-initdb.d/002_owner_passwords.sh
|
||||
|
||||
@@ -7,6 +7,9 @@ ARG TARGET
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -o /out/runtime ./cmd/${TARGET}
|
||||
|
||||
FROM alpine:3.23
|
||||
ARG SOURCE_REVISION=unknown
|
||||
LABEL org.opencontainers.image.revision=$SOURCE_REVISION \
|
||||
org.opencontainers.image.source="https://git.cin.su/m/Assistant.git"
|
||||
RUN addgroup -S assistant && adduser -S -G assistant assistant
|
||||
USER assistant
|
||||
COPY --from=build /out/runtime /usr/local/bin/assistant-runtime
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidatePattern('^[0-9a-f]{40}$')]
|
||||
[string]$Revision,
|
||||
[string]$DockerContext = 'docker-prod',
|
||||
[string]$LocalManifestPath = "$env:LOCALAPPDATA\Domovoy\monitoring\deployment-manifest.json",
|
||||
[string]$NasManifestPath = '\\nas\MST\codex\_monitoring\domovoy\deployment-manifest.json',
|
||||
[string[]]$ExpectedContainers = @(
|
||||
'assistant-postgres-1',
|
||||
'assistant-notification-receiver-1',
|
||||
'assistant-core-runtime-1',
|
||||
'assistant-continuity-runtime-1',
|
||||
'assistant-commit-runtime-1',
|
||||
'assistant-cognitive-worker-1',
|
||||
'assistant-creator-web-1'
|
||||
)
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Set-StrictMode -Version Latest
|
||||
|
||||
function Write-AtomicJson([string]$Path, [string]$Json) {
|
||||
$directory = Split-Path -Parent $Path
|
||||
New-Item -ItemType Directory -Force -Path $directory | Out-Null
|
||||
$partial = Join-Path $directory ('.' + [IO.Path]::GetFileName($Path) + ".${PID}.partial")
|
||||
try {
|
||||
[IO.File]::WriteAllText($partial, $Json + "`n", [Text.UTF8Encoding]::new($false))
|
||||
Move-Item -LiteralPath $partial -Destination $Path -Force
|
||||
}
|
||||
finally {
|
||||
if (Test-Path -LiteralPath $partial) { Remove-Item -LiteralPath $partial -Force }
|
||||
}
|
||||
}
|
||||
|
||||
$artifacts = foreach ($container in $ExpectedContainers) {
|
||||
$raw = ((& docker.exe --context $DockerContext inspect $container --format '{{json .}}') -join '').Trim()
|
||||
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($raw)) { throw "Cannot inspect $container" }
|
||||
$inspect = $raw | ConvertFrom-Json
|
||||
$actual = [string]$inspect.Config.Labels.'org.opencontainers.image.revision'
|
||||
if ($actual -ne $Revision) { throw "$container revision mismatch: expected=$Revision actual=$actual" }
|
||||
if ($inspect.State.Status -ne 'running') { throw "$container is not running" }
|
||||
[ordered]@{ container = $container; image_id = [string]$inspect.Image; revision = $actual }
|
||||
}
|
||||
|
||||
$manifest = [ordered]@{
|
||||
version = 1
|
||||
project = 'domovoy'
|
||||
revision = $Revision
|
||||
promoted_at_utc = [DateTime]::UtcNow.ToString('o')
|
||||
artifacts = @($artifacts)
|
||||
}
|
||||
$json = $manifest | ConvertTo-Json -Depth 5
|
||||
Write-AtomicJson $LocalManifestPath $json
|
||||
Write-AtomicJson $NasManifestPath $json
|
||||
Write-Output "Production artifact confirmed: revision=$Revision containers=$($artifacts.Count)"
|
||||
@@ -7,6 +7,7 @@ param(
|
||||
[string]$NasBackupRoot = '\\nas\MST\codex\_backups\domovoy\postgres',
|
||||
[string]$NasStatusPath = '\\nas\MST\codex\_monitoring\domovoy\status.json',
|
||||
[string]$LocalStatusPath = "$env:LOCALAPPDATA\Domovoy\monitoring\status.json",
|
||||
[string]$DeploymentManifestPath = "$env:LOCALAPPDATA\Domovoy\monitoring\deployment-manifest.json",
|
||||
[double]$MaxProductionBackupAgeHours = 30,
|
||||
[double]$MaxNasBackupAgeHours = 36,
|
||||
[int]$MinimumCertificateDays = 21,
|
||||
@@ -60,6 +61,21 @@ foreach ($container in $ExpectedContainers) {
|
||||
catch { Add-Check "container:$container" $false $_.Exception.Message }
|
||||
}
|
||||
|
||||
try {
|
||||
$manifest = Get-Content -LiteralPath $DeploymentManifestPath -Raw | ConvertFrom-Json
|
||||
if ($manifest.version -ne 1 -or $manifest.revision -notmatch '^[0-9a-f]{40}$') { throw 'invalid deployment manifest' }
|
||||
if (@($manifest.artifacts).Count -ne 7) { throw 'deployment manifest artifact count mismatch' }
|
||||
foreach ($artifact in $manifest.artifacts) {
|
||||
$raw = ((& docker.exe --context $DockerContext inspect $artifact.container --format '{{json .}}') -join '').Trim()
|
||||
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($raw)) { throw "cannot inspect $($artifact.container)" }
|
||||
$inspect = $raw | ConvertFrom-Json
|
||||
$label = [string]$inspect.Config.Labels.'org.opencontainers.image.revision'
|
||||
if ($label -ne $manifest.revision -or [string]$inspect.Image -ne [string]$artifact.image_id) { throw "artifact drift: $($artifact.container)" }
|
||||
}
|
||||
Add-Check 'deployment-artifact' $true "revision=$($manifest.revision) containers=$(@($manifest.artifacts).Count)"
|
||||
}
|
||||
catch { Add-Check 'deployment-artifact' $false $_.Exception.Message }
|
||||
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri $Endpoint -TimeoutSec 15
|
||||
$ok = $response.status -eq 'ok'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"task_file": "dev/tasks/DEV-000043-production-notification-delivery.json",
|
||||
"task_id": "DEV-000043",
|
||||
"task_file": "dev/tasks/DEV-000045-production-artifact-provenance.json",
|
||||
"task_id": "DEV-000045",
|
||||
"task_revision": 1
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"task_id": "DEV-000044",
|
||||
"task_revision": 3,
|
||||
"architecture_revision": "ADR-0005",
|
||||
"base_repo_revision": "759328972a7ae583f27eec5b97a7a8dea9df2ce7",
|
||||
"risk_tier": "E",
|
||||
"intent": "Re-audit the exact merged Assistant artifact after the first production notification operation, update repository status evidence, and identify remaining work without inventing unapproved product or architecture scope; docker-test remains prohibited.",
|
||||
"requirement_ids": ["ADR-0005", "INV-AUTH-001", "INV-OWN-001", "INV-CONT-001", "INV-TOPO-001", "USER-DOCKER-PROD-ONLY"],
|
||||
"allowed_change_scope": {
|
||||
"modules": [],
|
||||
"paths": [
|
||||
"docs/FOUNDATION_EXIT_AUDIT.md",
|
||||
"docs/PROJECT_STATUS.md",
|
||||
"tests/creator_commit/verify-remote.ps1",
|
||||
"dev/ACTIVE_TASK.json",
|
||||
"dev/tasks/DEV-000044-post-notification-production-audit.json"
|
||||
]
|
||||
},
|
||||
"forbidden_change_scope": {"paths": ["architecture/**", "ci/**", ".gitea/**", "contracts/**", "modules/**", "adapters/**", "cmd/**", "database/**", "deploy/**", "security/**"]},
|
||||
"allowed_architecture_delta": {"new_cross_module_dependencies": 0, "new_canonical_owners": 0, "new_privileges": 0, "new_third_party_dependencies": 0},
|
||||
"contracts": {"consume": ["ADR-0005", "DEV-000041", "DEV-000042", "DEV-000043", "existing production verification scripts"], "may_change": []},
|
||||
"semantic_owner": "none-verification",
|
||||
"canonical_state": [],
|
||||
"state_transitions": [],
|
||||
"side_effects_and_privileges": ["read-only production verification", "authenticated smoke may create only its documented disposable test evidence through the existing Commit path"],
|
||||
"persistence_and_migrations": [],
|
||||
"failure_retry_restart": ["audit records failures as gaps and does not weaken checks", "no production mutation outside existing verification harness semantics"],
|
||||
"assumptions": ["origin/main is the deployed exact artifact", "docker.cin.su SSH alias docker remains the production host", "docker-test remains prohibited"],
|
||||
"acceptance_scenarios": ["local deterministic tests and architecture checks pass", "production stack and Windows tasks are healthy", "notification HTTPS authorization and durable receipt path pass", "Creator remote smoke passes through a Windows/Docker CLI-safe command invocation", "production artifact provenance is either proven or recorded as an explicit gap", "repository documents completed post-foundation work and remaining product decisions"],
|
||||
"required_tests": ["task schema", "architecture preflight", "exact diff scope", "go test", "go vet", "production health", "authenticated Creator notification smoke", "docker-test absence"],
|
||||
"terminal_gap_states": ["BLOCKED_BY_ARCHITECTURE_GAP", "BLOCKED_BY_SPEC_GAP", "BLOCKED_BY_CONFLICT", "BLOCKED_BY_MISSING_CAPABILITY"]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"task_id": "DEV-000045",
|
||||
"task_revision": 1,
|
||||
"architecture_revision": "ADR-0005",
|
||||
"base_repo_revision": "959c89d47bf231dbcfb7a05e7b63b0e8579e3f0c",
|
||||
"risk_tier": "E",
|
||||
"intent": "Stamp project-built production images with the immutable Git revision, record promoted image digests in an external deployment manifest, and make production health reject provenance drift without using docker-test.",
|
||||
"requirement_ids": ["INV-TOPO-001", "DEV-000044-FINDING-ARTIFACT-PROVENANCE", "USER-DOCKER-PROD-ONLY"],
|
||||
"allowed_change_scope": {"modules": [], "paths": ["deploy/docker-compose.prod.yml", "deploy/images/runtime.Dockerfile", "deploy/images/postgres.Dockerfile", "deploy/windows/Confirm-DomovoyProductionArtifact.ps1", "deploy/windows/Test-DomovoyProductionHealth.ps1", "docs/DEPLOYMENT.md", "docs/PROJECT_STATUS.md", "dev/ACTIVE_TASK.json", "dev/tasks/DEV-000045-production-artifact-provenance.json"]},
|
||||
"forbidden_change_scope": {"paths": ["architecture/**", "ci/**", ".gitea/**", "contracts/**", "modules/**", "adapters/**", "cmd/**", "database/**", "security/**", "tests/**"]},
|
||||
"allowed_architecture_delta": {"new_cross_module_dependencies": 0, "new_canonical_owners": 0, "new_privileges": 0, "new_third_party_dependencies": 0},
|
||||
"contracts": {"consume": ["existing production Compose topology", "Docker OCI image metadata"], "may_change": []},
|
||||
"semantic_owner": "none-operational-verification",
|
||||
"canonical_state": [],
|
||||
"state_transitions": [],
|
||||
"side_effects_and_privileges": ["rebuild and replace project-owned production containers with exact merged source", "write non-secret deployment manifest to local profile and private NAS monitoring directory"],
|
||||
"persistence_and_migrations": ["non-secret external deployment manifest only"],
|
||||
"failure_retry_restart": ["manifest is published atomically only after all expected labels and digests verify", "failed verification leaves previous manifest intact", "health becomes degraded on revision or digest drift"],
|
||||
"assumptions": ["docker context docker-prod is the production endpoint", "Git HEAD is merged origin/main before promotion", "docker-test remains prohibited"],
|
||||
"acceptance_scenarios": ["every project-built image has the merged Git revision OCI label", "manifest records revision and exact image digests", "health verifies running labels and digests against the manifest", "production remains healthy after exact-artifact promotion"],
|
||||
"required_tests": ["PowerShell parser", "task schema", "architecture preflight", "exact diff scope", "go test", "go vet", "Compose config", "production artifact confirmation", "production health", "CI", "docker-test absence"],
|
||||
"terminal_gap_states": ["BLOCKED_BY_CONFLICT", "BLOCKED_BY_MISSING_CAPABILITY"]
|
||||
}
|
||||
@@ -14,6 +14,15 @@ Temporal is intentionally **not** the canonical owner of future obligations. If/
|
||||
|
||||
The initial stack definition is `deploy/docker-compose.prod.yml`. Portainer may deploy it from Git after the repository has been pushed.
|
||||
|
||||
Project-built production images receive `org.opencontainers.image.revision` and `org.opencontainers.image.source` OCI labels. Promotion must set `ASSISTANT_SOURCE_REVISION` to the full merged `origin/main` SHA before `docker compose build/up`; the default `unknown` is intentionally rejected by artifact confirmation. After all project containers are running, execute:
|
||||
|
||||
```powershell
|
||||
$revision = git rev-parse origin/main
|
||||
powershell -ExecutionPolicy Bypass -File .\deploy\windows\Confirm-DomovoyProductionArtifact.ps1 -Revision $revision -DockerContext docker-prod
|
||||
```
|
||||
|
||||
The confirmation script accepts the promotion only when every project-built container has that revision label, then atomically records its exact Docker image ID in `%LOCALAPPDATA%\Domovoy\monitoring\deployment-manifest.json` and the private NAS monitoring directory. Production health compares every running label and image ID to this manifest and becomes degraded on drift. The manifest is non-secret operational evidence; it is not canonical Assistant state.
|
||||
|
||||
The first external operation adds `assistant-notification-receiver-1` on production host port `18081`. Caddy applies `deploy/caddy/assistent.caddy`, routing only `https://assistent.cin.su/delivery/*` to that port and all other paths to Creator Web on `18080`. The receiver has an isolated durable volume and no Assistant database access. Commit success means an immutable receiver receipt exists; Windows display and human reading are not Commit outcomes.
|
||||
|
||||
Migrations `010_capability_notification_binding.sql` and `011_commit_notification_envelope.sql` must be applied before the new runtimes start. The initial Capability binding is owner-local for `domovoy-creator-principal`, revision 1, capability `prospective-notification-delivery`, origin `https://assistent.cin.su`, delivery path `/delivery/v1/deliveries`, receipt path `/delivery/v1/receipts`, protocol `IDEMPOTENT_RECEIPT_V1`, and secret reference `domovoy-notification-write-v1`.
|
||||
|
||||
@@ -21,8 +21,10 @@ Status is based on executed repository tests and Docker-stack verification on 20
|
||||
|
||||
Foundation V1 is eligible for freeze. Creator session authentication was also completed as DEV-000019 and does not carry Authority.
|
||||
|
||||
Post-foundation product work is intentionally separate:
|
||||
The three original post-foundation gates are complete:
|
||||
|
||||
1. Choose and specify the first real external operation before adding a production Executor credential.
|
||||
2. Build Creator API/UI only through validated Identity, Authority and Commit boundaries.
|
||||
3. Add exact diff-to-task scope comparison to promotion CI when the first Git baseline exists.
|
||||
1. `ADR-0005` specifies the first real external operation, prospective notification delivery.
|
||||
2. DEV-000024 through DEV-000032 and DEV-000040 through DEV-000043 provide the authenticated Creator API/UI and external operation only through the validated Identity, Authority, Continuity, Capability and Commit boundaries.
|
||||
3. `ADR-0004` and ARCH-000004 implement exact diff-to-task scope comparison.
|
||||
|
||||
DEV-000044 re-ran local architecture/unit checks and the production Creator-to-receiver smoke on 2026-08-16. The deployed stack and Windows operational tasks were healthy. Current product status and explicitly uncommitted future scope are recorded in `docs/PROJECT_STATUS.md`.
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Assistant project status
|
||||
|
||||
Audit date: 2026-08-16. Active audit: DEV-000044 revision 3.
|
||||
|
||||
## Delivered
|
||||
|
||||
- Foundation V1 is frozen and all exit criteria pass.
|
||||
- The single Creator account authenticates at `https://assistent.cin.su`; authentication does not imply Authority.
|
||||
- Creator can inspect the bounded operational view, register and satisfy Continuity prospective items, inspect action history, and explicitly request the accepted notification operation.
|
||||
- `deliver-prospective-notification-v1` executes only through Capability binding, current Authority and Commit/Executor validation. Its success evidence is an immutable receiver receipt.
|
||||
- Production runs on `docker.cin.su`; the project does not use the shared test Docker host.
|
||||
- PostgreSQL backup/restore, encrypted off-host backup, production health monitoring and the current-user Windows notification projection are installed and healthy.
|
||||
|
||||
## Evidence from DEV-000044
|
||||
|
||||
- `go test ./...`, `go vet ./...`, architecture preflight/checks and PowerShell parsing pass.
|
||||
- `Test-DomovoyProductionHealth.ps1` reports `healthy` for the production stack, HTTPS/DNS/TLS, backups and registered Windows tasks.
|
||||
- `tests/creator_commit/verify-remote.ps1` passes the authenticated Creator → Commit → notification receiver receipt flow on `docker-prod`.
|
||||
- The smoke harness was corrected to preserve HTTP Authorization headers under Windows PowerShell 5.1 native-command argument handling.
|
||||
|
||||
## Remaining work requiring a new task decision
|
||||
|
||||
1. **Cognitive provider:** the cognitive worker intentionally remains the deterministic fake. Selecting a real model/provider, data policy and allowed proposal contract requires a separate capability/architecture decision; it must not gain canonical mutation authority.
|
||||
2. **Product breadth:** notification delivery is the only accepted real external operation. Any additional operation needs its own proposal, authority model, idempotency/reconciliation semantics and Capability binding.
|
||||
3. **Artifact and Epistemics product behavior:** their ownership boundaries exist, but no product task has yet specified durable user-facing workflows for them.
|
||||
|
||||
DEV-000045 closes the DEV-000044 artifact-provenance finding for new promotions by stamping the merged Git revision into OCI labels, recording exact promoted image IDs outside the repository, and making production monitoring reject label or digest drift. Images that predate DEV-000045 remain historically unverifiable from the image alone.
|
||||
|
||||
These are explicit scope decisions, not hidden incomplete steps in DEV-000043. No production secret is stored in the repository.
|
||||
@@ -29,7 +29,7 @@ function Creator-Post([string]$url, [object]$body, [string]$token) {
|
||||
try {
|
||||
[IO.File]::WriteAllText($local, $json, [Text.UTF8Encoding]::new($false))
|
||||
docker --context $DockerContext cp $local "${commitContainer}:$remote" | Out-Null
|
||||
$result = docker --context $DockerContext exec --env "CREATOR_TEST_SESSION=$token" $commitContainer sh -c 'wget -qO- --header="Content-Type: application/json" --header="Authorization: Bearer $CREATOR_TEST_SESSION" --post-file "$1" "$2"' sh $remote $url
|
||||
$result = docker --context $DockerContext exec --env "CREATOR_TEST_SESSION=$token" $commitContainer sh -c 'auth=Authorization:\ Bearer\ $CREATOR_TEST_SESSION; IFS=; wget -qO- --header=Content-Type:application/json --header=$auth --post-file=$1 $2' sh $remote $url
|
||||
if ($LASTEXITCODE -ne 0) { throw "Creator POST $url failed" }
|
||||
return ($result -join "`n")
|
||||
} finally {
|
||||
@@ -39,7 +39,7 @@ function Creator-Post([string]$url, [object]$body, [string]$token) {
|
||||
}
|
||||
|
||||
function Creator-Get([string]$url, [string]$token) {
|
||||
$result = docker --context $DockerContext exec --env "CREATOR_TEST_SESSION=$token" $commitContainer sh -c 'wget -qO- --header="Authorization: Bearer $CREATOR_TEST_SESSION" "$1"' sh $url
|
||||
$result = docker --context $DockerContext exec --env "CREATOR_TEST_SESSION=$token" $commitContainer sh -c 'auth=Authorization:\ Bearer\ $CREATOR_TEST_SESSION; IFS=; wget -qO- --header=$auth $1' sh $url
|
||||
if ($LASTEXITCODE -ne 0) { throw "Creator GET $url failed" }
|
||||
return ($result -join "`n")
|
||||
}
|
||||
@@ -53,7 +53,7 @@ function Expect-CreatorStatus([string]$url, [object]$body, [string]$token, [int]
|
||||
docker --context $DockerContext cp $local "${commitContainer}:$remote" | Out-Null
|
||||
$previous = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
$result = (docker --context $DockerContext exec --env "CREATOR_TEST_SESSION=$token" $commitContainer sh -c 'wget -S -O /dev/null --header="Content-Type: application/json" --header="Authorization: Bearer $CREATOR_TEST_SESSION" --post-file "$1" "$2"' sh $remote $url 2>&1) -join "`n"
|
||||
$result = (docker --context $DockerContext exec --env "CREATOR_TEST_SESSION=$token" $commitContainer sh -c 'auth=Authorization:\ Bearer\ $CREATOR_TEST_SESSION; IFS=; wget -S -O /dev/null --header=Content-Type:application/json --header=$auth --post-file=$1 $2' sh $remote $url 2>&1) -join "`n"
|
||||
$ErrorActionPreference = $previous
|
||||
if ($result -notmatch "HTTP/1\.[01] $status") { throw "Creator POST $url did not return $status" }
|
||||
} finally {
|
||||
@@ -62,12 +62,7 @@ function Expect-CreatorStatus([string]$url, [object]$body, [string]$token, [int]
|
||||
}
|
||||
}
|
||||
|
||||
$sessionResponse = docker --context $DockerContext exec $coreContainer sh -c '
|
||||
token="$CREATOR_BOOTSTRAP_TOKEN"
|
||||
if [ -n "$CREATOR_BOOTSTRAP_TOKEN_FILE" ]; then token=$(cat "$CREATOR_BOOTSTRAP_TOKEN_FILE"); fi
|
||||
if [ -z "$token" ]; then exit 7; fi
|
||||
wget -qO- --header="Authorization: Bearer $token" --post-data="" "$1/v1/creator/sessions"
|
||||
' sh http://localhost:8080
|
||||
$sessionResponse = docker --context $DockerContext exec $coreContainer sh -c 'token=$CREATOR_BOOTSTRAP_TOKEN; if test x$CREATOR_BOOTSTRAP_TOKEN_FILE != x; then token=$(cat $CREATOR_BOOTSTRAP_TOKEN_FILE); fi; if test x$token = x; then exit 7; fi; header=Authorization:\ Bearer\ $token; IFS=; wget -qO- --header=$header --post-data={} http://localhost:8080/v1/creator/sessions'
|
||||
if ($LASTEXITCODE -ne 0) { throw "Creator session issuance failed" }
|
||||
$creatorSession = ($sessionResponse | ConvertFrom-Json).Token
|
||||
|
||||
@@ -120,7 +115,7 @@ $notificationAction = Creator-Post http://localhost:8082/v1/creator/continuity/n
|
||||
if ($notificationAction.State -ne 'SUCCEEDED' -or -not $notificationAction.ActionIntentID) { throw 'Creator notification did not produce a successful receipt' }
|
||||
$notificationItem = docker --context $DockerContext exec $continuityContainer wget -qO- "http://localhost:8081/v1/prospective-items/$notificationProspective" | ConvertFrom-Json
|
||||
if ($notificationItem.State -ne 'DELIVERED' -or $notificationItem.Revision -ne 1) { throw 'Notification changed Continuity canonical state' }
|
||||
$receiptRaw = docker --context $DockerContext exec $receiverContainer sh -c 'token=$(tr -d "\r\n" < /run/notification-reader/token); wget -qO- --header="Authorization: Bearer $token" "$1"' sh "http://localhost:8085/delivery/v1/receipts/$($notificationAction.ActionIntentID)"
|
||||
$receiptRaw = docker --context $DockerContext exec $receiverContainer sh -c 'token=$(cat /run/notification-reader/token); auth=Authorization:\ Bearer\ $token; IFS=; wget -qO- --header=$auth $1' sh "http://localhost:8085/delivery/v1/receipts/$($notificationAction.ActionIntentID)"
|
||||
if ($LASTEXITCODE -ne 0) { throw 'Notification receipt lookup failed' }
|
||||
$receipt = ($receiptRaw -join "`n") | ConvertFrom-Json
|
||||
if ($receipt.action_intent_id -ne $notificationAction.ActionIntentID -or $receipt.request_digest -notmatch '^[0-9a-f]{64}$') { throw 'Notification receipt evidence mismatch' }
|
||||
|
||||
Reference in New Issue
Block a user