Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5cc5d225c7 | |||
| 8502bd9f17 | |||
| b262e9fe80 | |||
| 7c188dd248 | |||
| 480f6dcd34 | |||
| 59a51787ed | |||
| 74ff840d3d | |||
| 2611f79e67 | |||
| 10fdb18204 | |||
| 903de12f2c | |||
| b4f97bc2c6 | |||
| 846f9662e2 | |||
| c3f6793ce1 | |||
| 2da8a6d390 | |||
| d62c5eb744 | |||
| 8045f46b06 |
@@ -0,0 +1,12 @@
|
|||||||
|
.git
|
||||||
|
.pytest_cache
|
||||||
|
.mypy_cache
|
||||||
|
.ruff_cache
|
||||||
|
.venv
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
outputs
|
||||||
|
worktrees
|
||||||
|
tests
|
||||||
|
docs
|
||||||
|
candidate-manifests
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Svrnty Vision Endgoal
|
||||||
|
|
||||||
|
Endgoal: keep `svrnty-vision` as the child-local sovereign vision HTTP gateway and Visual Perception Package Candidate for VLM analysis, FLUX rendering, palette extraction, and cutout work without Core authority, Seed installation authority, Runtime startup authority, Profile Exposure authority, provider admission, wildcard tool access, or product-readiness claims.
|
||||||
|
|
||||||
|
Route: `svrnty-vision`.
|
||||||
|
Stage: CLEAN.
|
||||||
|
Clean score: 100.
|
||||||
|
Validator: `python3 tools/validate_svrnty_vision_child.py`.
|
||||||
|
Current Pickup: use this workspace for vision gateway source, BTE-shaped route adapters, package-candidate docs, visual-evidence contracts, host-adapter candidates, manifests, Docker package context, validators, fixtures, and proof packets; do not start runtimes, admit providers, broaden exposure, or claim readiness.
|
||||||
|
Authority Boundary: child-local vision gateway and package-candidate workspace only; not Cortex OS Core authority, Runtime authority, Host Runtime authority, Profile Exposure authority, provider authority, Docker/runtime lifecycle authority, release authority, production authority, or readiness authority.
|
||||||
|
Legacy-work relation: older BTE-embedded vision, cloud-provider SDK, VLM, FLUX, palette, rembg, Visual Evidence, and package-candidate work is tracked in `docs/LEGACY-INGEST.md` and distilled into this standalone gateway only when current docs and validators admit it. Do not import provider credentials, backend state, runtime behavior, or mass because it exists.
|
||||||
|
|
||||||
|
## Universal Cortex OS Agent Contract
|
||||||
|
|
||||||
|
- Follow parent `AGENTS.md`; this file is route-local instruction before chat memory.
|
||||||
|
- For broad work, run `cortex graph context` as Derived State, then read local files.
|
||||||
|
- Before edits, read `AGENTS.md`, `README.md`, and `WORKBOARD.yaml`; keep writes route-local unless Core authorizes promotion.
|
||||||
|
- Use Karpathy rules, small gateway seams, real evals, and cartesian/pragmatic/efficient/elegant no-live execution.
|
||||||
|
- Run the validator before handoff or done claims; raise proof only for runtime, provider, secret, memory, profile exposure, release, or readiness.
|
||||||
|
- Keep proof and handoffs refs-only. Do not write Hindsight memory, Core SOT, sibling repos, runtime state, provider state, external systems, or organization payloads without route approval.
|
||||||
|
|
||||||
|
## Repo-Custom Agent Contract
|
||||||
|
|
||||||
|
Svrnty Vision is a child-local sovereign vision HTTP gateway and Visual Perception Package Candidate workspace. It owns VLM/FLUX/palette/cutout gateway source, BTE-shaped HTTP route adapters, package-candidate docs, visual-evidence contracts, host-adapter candidates, tool-grant manifests, Docker package context, validators, fixtures, and proof packets.
|
||||||
|
|
||||||
|
Do not start Runtime, start Docker, build or run containers, install packages, start FastAPI/Uvicorn, call VLM/FLUX/palette/rembg endpoints, call Spark/ComfyUI/vLLM services, call cloud vision/image providers, read credentials or env values, mutate BTE/Core/Seed/sibling/OpenDesign repos, grant wildcard tools, grant Profile Exposure, write durable Hindsight memory, or claim readiness without governed approval.
|
||||||
|
|
||||||
|
## Current Pickup
|
||||||
|
|
||||||
|
Use this workspace for vision gateway source, BTE-shaped route adapters, package-candidate docs, visual-evidence contracts, host-adapter candidates, manifests, Docker package context, validators, fixtures, and proof packets.
|
||||||
|
|
||||||
|
## Allowed Writes
|
||||||
|
|
||||||
|
Write inside this repo only: source, docs, manifests, Docker package context, validators, fixtures, proof packets, workboard entries, and handoffs.
|
||||||
|
|
||||||
|
## Forbidden Effects
|
||||||
|
|
||||||
|
Do not mutate `../core/`, sibling repos, BTE, Seed, OpenDesign, provider state, credentials, runtime state, Docker lifecycle, Profile Exposure, wildcard tool grants, Hindsight live memory, or readiness/release claims without governed approval.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
After editing, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 tools/validate_svrnty_vision_child.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Handoff
|
||||||
|
|
||||||
|
Handoffs are compact and refs-only: changed files, validator output, forbidden effects avoided, and legacy intentions left for later.
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
# Svrnty Vision Context
|
||||||
|
|
||||||
|
`svrnty-vision` is a child-local Cortex OS VISION package candidate for visual
|
||||||
|
perception and visual production tools. It is not Core authority, not Seed
|
||||||
|
installed, not Runtime, not Profile Exposure, and not provider admission.
|
||||||
|
|
||||||
|
## Terms
|
||||||
|
|
||||||
|
Visual Perception Package Candidate
|
||||||
|
: A child-local candidate package that owns pixel/media perception surfaces under
|
||||||
|
canonical sense `VISION`.
|
||||||
|
|
||||||
|
VISION Sense Family
|
||||||
|
: The canonical sense family for seeing. It can include textual/source reading
|
||||||
|
through `/research` and pixel/media perception through `/vision`.
|
||||||
|
|
||||||
|
Visual Evidence
|
||||||
|
: A normalized output record produced by a VISION tool. It discloses package,
|
||||||
|
tool, source, provider mode, retention, observed content, extracted claims,
|
||||||
|
confidence, caveats, timestamp, and validation status.
|
||||||
|
|
||||||
|
Vision Tool Candidate
|
||||||
|
: A granular tool inside the visual perception package. Granting the package does
|
||||||
|
not grant every tool.
|
||||||
|
|
||||||
|
Current Route Adapter
|
||||||
|
: An existing HTTP route that can be mapped to a future Cortex OS tool id without
|
||||||
|
changing the implementation stack.
|
||||||
|
|
||||||
|
Research Handoff
|
||||||
|
: Research may cite or synthesize Visual Evidence that `/vision` already
|
||||||
|
produced, but `/vision` does not perform research synthesis, web search, page
|
||||||
|
fetch, PDF extraction, or deep research workflows.
|
||||||
|
|
||||||
|
BTE Compatibility Surface
|
||||||
|
: Existing route names and BTE-shaped behavior stay usable while the package
|
||||||
|
candidate is documented for Cortex OS.
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
PYTHONUNBUFFERED=1 \
|
||||||
|
SVRNTY_VISION_HOST=0.0.0.0 \
|
||||||
|
SVRNTY_VISION_PORT=8094
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN useradd --create-home --shell /usr/sbin/nologin vision
|
||||||
|
|
||||||
|
COPY pyproject.toml README.md ./
|
||||||
|
COPY src ./src
|
||||||
|
|
||||||
|
RUN python -m pip install --no-cache-dir --upgrade pip \
|
||||||
|
&& python -m pip install --no-cache-dir .
|
||||||
|
|
||||||
|
USER vision
|
||||||
|
|
||||||
|
EXPOSE 8094
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8094/healthz', timeout=3).read()"
|
||||||
|
|
||||||
|
CMD ["python", "-m", "svrnty_vision.server"]
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Svrnty Vision Index
|
||||||
|
|
||||||
|
Route: `svrnty-vision`.
|
||||||
|
Path: `/home/svrnty/workspaces/cortex-os/svrnty-vision`.
|
||||||
|
Category: child-local sovereign vision HTTP gateway and Visual Perception Package Candidate workspace.
|
||||||
|
Validator: `python3 tools/validate_svrnty_vision_child.py`.
|
||||||
|
|
||||||
|
## Read Order
|
||||||
|
|
||||||
|
1. `AGENTS.md` for route-local authority, forbidden effects, and validator rules.
|
||||||
|
2. `README.md` for gateway posture, operator/developer examples, and cleanup-route boundary.
|
||||||
|
3. `docs/LEGACY-INGEST.md` for legacy intention coverage and rejection gates.
|
||||||
|
4. `docs/VISION-PACKAGE-CANDIDATE.md`, `docs/VISUAL-EVIDENCE-CONTRACT.md`, and `docs/VISION-HOST-ADAPTER-CANDIDATES.md` for package-candidate work.
|
||||||
|
5. `candidate-manifests/` for tool grants and manifest contracts.
|
||||||
|
6. `WORKBOARD.yaml` for child-local work state.
|
||||||
|
|
||||||
|
## Local Authority
|
||||||
|
|
||||||
|
Svrnty Vision owns child-local VLM, FLUX, palette, and cutout gateway source; BTE-shaped HTTP route adapters; package-candidate docs; visual-evidence contracts; host-adapter candidates; tool-grant manifests; Docker package context; validators; fixtures; and proof packets.
|
||||||
|
|
||||||
|
Svrnty Vision is not Core authority, Seed installation authority, Runtime startup authority, Host Runtime authority, Docker lifecycle authority, Profile Exposure authority, provider admission authority, wildcard tool authority, product-readiness authority, release authority, or production authority.
|
||||||
|
|
||||||
|
## Legacy Relation
|
||||||
|
|
||||||
|
Older BTE-embedded vision, cloud-provider SDK, VLM, FLUX, palette, rembg, Visual Evidence, and package-candidate work is distilled into this standalone gateway only when current docs and validators admit the intention. Do not import provider credentials, backend state, runtime behavior, cloud-provider coupling, wildcard tool access, or implementation mass because it exists.
|
||||||
|
|
||||||
|
## Completion State
|
||||||
|
|
||||||
|
Stage: CLEAN.
|
||||||
|
Clean score: 100.
|
||||||
|
Current next pass: keep this route static unless a governed route authorizes Docker, FastAPI/Uvicorn, endpoint calls, Spark/ComfyUI/vLLM calls, provider calls, package installation, Profile Exposure, Seed installation, Runtime startup, or readiness claims.
|
||||||
@@ -31,12 +31,37 @@ libraries — Pillow/colorthief and rembg respectively. They land in 4b.
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
**Phase 4a (this commit):** scaffold only. All four endpoints return
|
Current implementation: all four listed endpoints exist. `/vlm/analyze` proxies
|
||||||
HTTP 501 Not Implemented. `/healthz` returns 200.
|
to Qwen3-VL through the configured VLM endpoint, `/flux/render` proxies to
|
||||||
|
ComfyUI FLUX, `/palette/extract` runs in process, `/rembg/cutout` runs in
|
||||||
|
process, and `/healthz` returns 200.
|
||||||
|
|
||||||
Phase 4b will port the real logic. Phase 4c deletes the corresponding
|
## Cortex OS Package Candidate
|
||||||
.NET code from BTE. Phase 4d wires BTE to call svrnty-vision over HTTP.
|
|
||||||
See `/home/svrnty/workspaces/hermes/sot/01-ROADMAP/BTE-REFACTOR-EXECUTION-PLAN.md`.
|
`svrnty-vision` is also documented as a child-local Visual Perception Package
|
||||||
|
Candidate under canonical sense `VISION`. Existing BTE-shaped HTTP routes remain
|
||||||
|
current route adapters; exact Cortex OS candidate tool ids, grant rules, host
|
||||||
|
adapter candidates, and Visual Evidence contract live in `docs/` and
|
||||||
|
`candidate-manifests/`.
|
||||||
|
|
||||||
|
This does not grant Core promotion, Seed installation, Runtime startup, Profile
|
||||||
|
Exposure, provider admission, or wildcard tool access.
|
||||||
|
|
||||||
|
Legacy intention coverage is tracked in `docs/LEGACY-INGEST.md`.
|
||||||
|
|
||||||
|
## Cortex OS Boundary
|
||||||
|
|
||||||
|
This repo owns child-local sovereign vision gateway source, BTE-shaped HTTP route
|
||||||
|
adapters, package-candidate docs, visual-evidence contracts, host-adapter
|
||||||
|
candidates, tool-grant manifests, Docker package context, validators, fixtures,
|
||||||
|
and proof packets only. Cleanup agents must not start Runtime, start Docker,
|
||||||
|
build or run containers, install packages, start FastAPI/Uvicorn, call VLM,
|
||||||
|
FLUX, palette, or rembg endpoints, call Spark/ComfyUI/vLLM services, call cloud
|
||||||
|
vision/image providers, read credentials or env values, mutate
|
||||||
|
BTE/Core/Seed/sibling/OpenDesign repos, grant wildcard tools, grant Profile
|
||||||
|
Exposure, write durable Hindsight memory, or claim readiness without explicit
|
||||||
|
governed approval. Run, test, Docker, endpoint, provider, and configuration
|
||||||
|
examples below are operator/developer docs, not cleanup-route authorization.
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
items:
|
||||||
|
- id: SVRNTY-VISION-WORK-001
|
||||||
|
title: Svrnty Vision Child Workspace Governance
|
||||||
|
status: complete
|
||||||
|
source: outputs/2026-06-12-svrnty-vision-workboard-readiness-reconciliation.md
|
||||||
|
owner: ""
|
||||||
|
- id: SVRNTY-VISION-WORK-002
|
||||||
|
title: Generic VISION Package Candidate And Visual Evidence Proof
|
||||||
|
status: complete
|
||||||
|
source: outputs/2026-06-06-svrnty-vision-work-002-package-candidate-validation.md
|
||||||
|
owner: ""
|
||||||
|
- id: SVRNTY-VISION-WORK-003
|
||||||
|
title: Vision Package Candidate Sandcastle
|
||||||
|
status: complete
|
||||||
|
source: outputs/2026-06-12-svrnty-vision-workboard-readiness-reconciliation.md
|
||||||
|
owner: ""
|
||||||
|
- id: SVRNTY-VISION-WORK-004
|
||||||
|
title: Package Docker Build Context
|
||||||
|
status: complete
|
||||||
|
source: Dockerfile
|
||||||
|
owner: ""
|
||||||
|
- id: SVRNTY-VISION-WORK-005
|
||||||
|
title: Svrnty Vision Agent Contract Blocks
|
||||||
|
status: complete
|
||||||
|
source: AGENTS.md
|
||||||
|
owner: ""
|
||||||
|
- id: SVRNTY-VISION-WORK-006
|
||||||
|
title: Svrnty Vision Navigation Index
|
||||||
|
status: complete
|
||||||
|
source: INDEX.md
|
||||||
|
owner: ""
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "vision.host_adapter_candidate.v1",
|
||||||
|
"adapter_id": "vision-claude-code-adapter",
|
||||||
|
"authority": "child-local",
|
||||||
|
"status": "candidate_only_not_seed_installed",
|
||||||
|
"host_runtime": "claude-code",
|
||||||
|
"host_runtime_class": "claude-code",
|
||||||
|
"package_id": "visual-perception-package-candidate",
|
||||||
|
"adapter_role": "thin_access_adapter",
|
||||||
|
"seed_artifact_target": "host-adapters/vision-claude-code-adapter.json",
|
||||||
|
"wildcard_grant_allowed": false,
|
||||||
|
"current_tool_candidates": [
|
||||||
|
"vision.image_analyze",
|
||||||
|
"vision.image_generate",
|
||||||
|
"vision.palette_extract",
|
||||||
|
"vision.background_cutout"
|
||||||
|
],
|
||||||
|
"planned_tool_candidates": [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit"
|
||||||
|
],
|
||||||
|
"disclosure_contract": {
|
||||||
|
"provider_mode_required": true,
|
||||||
|
"retention_required": true,
|
||||||
|
"visual_evidence_required": true
|
||||||
|
},
|
||||||
|
"allowed_effects": [
|
||||||
|
"analyze_image_input",
|
||||||
|
"generate_image_output",
|
||||||
|
"extract_palette",
|
||||||
|
"remove_background",
|
||||||
|
"return_visual_evidence"
|
||||||
|
],
|
||||||
|
"forbidden_effects": [
|
||||||
|
"research_synthesis",
|
||||||
|
"textual_web_search",
|
||||||
|
"textual_page_fetch",
|
||||||
|
"profile_exposure",
|
||||||
|
"runtime_start",
|
||||||
|
"provider_admission",
|
||||||
|
"wildcard_tool_exposure"
|
||||||
|
],
|
||||||
|
"non_authorization": {
|
||||||
|
"core_promotion": false,
|
||||||
|
"seed_installation": false,
|
||||||
|
"runtime_start": false,
|
||||||
|
"profile_exposure": false,
|
||||||
|
"provider_admission": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "vision.host_adapter_candidate.v1",
|
||||||
|
"adapter_id": "vision-codex-cli-adapter",
|
||||||
|
"authority": "child-local",
|
||||||
|
"status": "candidate_only_not_seed_installed",
|
||||||
|
"host_runtime": "codex-cli",
|
||||||
|
"host_runtime_class": "codex-cli",
|
||||||
|
"package_id": "visual-perception-package-candidate",
|
||||||
|
"adapter_role": "thin_access_adapter",
|
||||||
|
"seed_artifact_target": "host-adapters/vision-codex-cli-adapter.json",
|
||||||
|
"wildcard_grant_allowed": false,
|
||||||
|
"current_tool_candidates": [
|
||||||
|
"vision.image_analyze",
|
||||||
|
"vision.image_generate",
|
||||||
|
"vision.palette_extract",
|
||||||
|
"vision.background_cutout"
|
||||||
|
],
|
||||||
|
"planned_tool_candidates": [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit"
|
||||||
|
],
|
||||||
|
"disclosure_contract": {
|
||||||
|
"provider_mode_required": true,
|
||||||
|
"retention_required": true,
|
||||||
|
"visual_evidence_required": true
|
||||||
|
},
|
||||||
|
"allowed_effects": [
|
||||||
|
"analyze_image_input",
|
||||||
|
"generate_image_output",
|
||||||
|
"extract_palette",
|
||||||
|
"remove_background",
|
||||||
|
"return_visual_evidence"
|
||||||
|
],
|
||||||
|
"forbidden_effects": [
|
||||||
|
"research_synthesis",
|
||||||
|
"textual_web_search",
|
||||||
|
"textual_page_fetch",
|
||||||
|
"profile_exposure",
|
||||||
|
"runtime_start",
|
||||||
|
"provider_admission",
|
||||||
|
"wildcard_tool_exposure"
|
||||||
|
],
|
||||||
|
"non_authorization": {
|
||||||
|
"core_promotion": false,
|
||||||
|
"seed_installation": false,
|
||||||
|
"runtime_start": false,
|
||||||
|
"profile_exposure": false,
|
||||||
|
"provider_admission": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "vision.host_adapter_candidate.v1",
|
||||||
|
"adapter_id": "vision-pi-code-adapter",
|
||||||
|
"authority": "child-local",
|
||||||
|
"status": "candidate_only_not_seed_installed",
|
||||||
|
"host_runtime": "pi-code",
|
||||||
|
"host_runtime_class": "pi-code",
|
||||||
|
"package_id": "visual-perception-package-candidate",
|
||||||
|
"adapter_role": "thin_access_adapter",
|
||||||
|
"seed_artifact_target": "host-adapters/vision-pi-code-adapter.json",
|
||||||
|
"wildcard_grant_allowed": false,
|
||||||
|
"current_tool_candidates": [
|
||||||
|
"vision.image_analyze",
|
||||||
|
"vision.image_generate",
|
||||||
|
"vision.palette_extract",
|
||||||
|
"vision.background_cutout"
|
||||||
|
],
|
||||||
|
"planned_tool_candidates": [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit"
|
||||||
|
],
|
||||||
|
"disclosure_contract": {
|
||||||
|
"provider_mode_required": true,
|
||||||
|
"retention_required": true,
|
||||||
|
"visual_evidence_required": true
|
||||||
|
},
|
||||||
|
"allowed_effects": [
|
||||||
|
"analyze_image_input",
|
||||||
|
"generate_image_output",
|
||||||
|
"extract_palette",
|
||||||
|
"remove_background",
|
||||||
|
"return_visual_evidence"
|
||||||
|
],
|
||||||
|
"forbidden_effects": [
|
||||||
|
"research_synthesis",
|
||||||
|
"textual_web_search",
|
||||||
|
"textual_page_fetch",
|
||||||
|
"profile_exposure",
|
||||||
|
"runtime_start",
|
||||||
|
"provider_admission",
|
||||||
|
"wildcard_tool_exposure"
|
||||||
|
],
|
||||||
|
"non_authorization": {
|
||||||
|
"core_promotion": false,
|
||||||
|
"seed_installation": false,
|
||||||
|
"runtime_start": false,
|
||||||
|
"profile_exposure": false,
|
||||||
|
"provider_admission": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "vision.package_candidate.v1",
|
||||||
|
"package_id": "visual-perception-package-candidate",
|
||||||
|
"workspace": "svrnty-vision",
|
||||||
|
"authority": "child-local",
|
||||||
|
"status": "candidate_only_not_seed_installed",
|
||||||
|
"canonical_sense": "VISION",
|
||||||
|
"package_role": "generic_visual_perception_and_production",
|
||||||
|
"current_route_adapters": [
|
||||||
|
{
|
||||||
|
"route": "POST /vlm/analyze",
|
||||||
|
"tool_id": "vision.image_analyze",
|
||||||
|
"capability": "vlm_image_analysis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"route": "POST /flux/render",
|
||||||
|
"tool_id": "vision.image_generate",
|
||||||
|
"capability": "image_generation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"route": "POST /palette/extract",
|
||||||
|
"tool_id": "vision.palette_extract",
|
||||||
|
"capability": "palette_extraction"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"route": "POST /rembg/cutout",
|
||||||
|
"tool_id": "vision.background_cutout",
|
||||||
|
"capability": "background_cutout"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"current_tool_candidates": [
|
||||||
|
"vision.image_analyze",
|
||||||
|
"vision.image_generate",
|
||||||
|
"vision.palette_extract",
|
||||||
|
"vision.background_cutout"
|
||||||
|
],
|
||||||
|
"planned_tool_candidates": [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit"
|
||||||
|
],
|
||||||
|
"owned_capability_classes": [
|
||||||
|
"pixel_media_perception",
|
||||||
|
"visual_evidence_production",
|
||||||
|
"image_generation",
|
||||||
|
"image_editing",
|
||||||
|
"screenshot_and_browser_visual_observation",
|
||||||
|
"layout_chart_table_diagram_visual_reading"
|
||||||
|
],
|
||||||
|
"forbidden_research_owned_capabilities": [
|
||||||
|
"web_search",
|
||||||
|
"fetch_page",
|
||||||
|
"extract_pdf",
|
||||||
|
"deep_research",
|
||||||
|
"research_synthesis",
|
||||||
|
"capsule_writing"
|
||||||
|
],
|
||||||
|
"research_handoff": {
|
||||||
|
"may_produce_visual_evidence_for_research": true,
|
||||||
|
"may_perform_research_synthesis": false,
|
||||||
|
"handoff_contract": "candidate-manifests/visual-evidence-contract.json"
|
||||||
|
},
|
||||||
|
"grant_policy": {
|
||||||
|
"wildcard_grant_allowed": false,
|
||||||
|
"package_default_grants_all_tools": false,
|
||||||
|
"tool_grants_are_granular": true
|
||||||
|
},
|
||||||
|
"non_authorization": {
|
||||||
|
"core_promotion": false,
|
||||||
|
"seed_installation": false,
|
||||||
|
"runtime_start": false,
|
||||||
|
"profile_exposure": false,
|
||||||
|
"provider_admission": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "vision.tool_grants.v1",
|
||||||
|
"package_id": "visual-perception-package-candidate",
|
||||||
|
"authority": "child-local",
|
||||||
|
"status": "candidate_only_not_seed_installed",
|
||||||
|
"canonical_sense": "VISION",
|
||||||
|
"wildcard_grant_allowed": false,
|
||||||
|
"package_default_grants_all_tools": false,
|
||||||
|
"current_tool_candidates": [
|
||||||
|
{
|
||||||
|
"tool_id": "vision.image_analyze",
|
||||||
|
"route": "POST /vlm/analyze",
|
||||||
|
"grant_default": false,
|
||||||
|
"requires_visual_evidence": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool_id": "vision.image_generate",
|
||||||
|
"route": "POST /flux/render",
|
||||||
|
"grant_default": false,
|
||||||
|
"requires_visual_evidence": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool_id": "vision.palette_extract",
|
||||||
|
"route": "POST /palette/extract",
|
||||||
|
"grant_default": false,
|
||||||
|
"requires_visual_evidence": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool_id": "vision.background_cutout",
|
||||||
|
"route": "POST /rembg/cutout",
|
||||||
|
"grant_default": false,
|
||||||
|
"requires_visual_evidence": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"planned_tool_candidates": [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit"
|
||||||
|
],
|
||||||
|
"required_disclosures": {
|
||||||
|
"producing_package_id": true,
|
||||||
|
"producing_tool_id": true,
|
||||||
|
"capability_surface": true,
|
||||||
|
"provider_mode": true,
|
||||||
|
"retention_disclosure": true,
|
||||||
|
"validation_status": true
|
||||||
|
},
|
||||||
|
"forbidden_effects": [
|
||||||
|
"research_synthesis",
|
||||||
|
"textual_web_search",
|
||||||
|
"textual_page_fetch",
|
||||||
|
"pdf_text_extraction",
|
||||||
|
"deep_research_workflow",
|
||||||
|
"capsule_writing",
|
||||||
|
"runtime_start",
|
||||||
|
"profile_exposure",
|
||||||
|
"provider_admission",
|
||||||
|
"wildcard_tool_exposure"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "vision.visual_evidence_contract.v1",
|
||||||
|
"package_id": "visual-perception-package-candidate",
|
||||||
|
"authority": "child-local",
|
||||||
|
"status": "candidate_only_not_seed_installed",
|
||||||
|
"required_fields": [
|
||||||
|
"producing_package_id",
|
||||||
|
"producing_tool_id",
|
||||||
|
"capability_surface",
|
||||||
|
"source_reference",
|
||||||
|
"provider_mode",
|
||||||
|
"retention_disclosure",
|
||||||
|
"observed_content_summary",
|
||||||
|
"extracted_claims",
|
||||||
|
"confidence",
|
||||||
|
"caveats",
|
||||||
|
"timestamp",
|
||||||
|
"validation_status"
|
||||||
|
],
|
||||||
|
"first_vertical_proof": {
|
||||||
|
"source_route": "POST /vlm/analyze",
|
||||||
|
"source_tool_id": "vision.image_analyze",
|
||||||
|
"module": "src/svrnty_vision/visual_evidence.py",
|
||||||
|
"test": "tests/test_visual_evidence.py",
|
||||||
|
"live_provider_call_required": false
|
||||||
|
},
|
||||||
|
"research_handoff": {
|
||||||
|
"research_may_consume_visual_evidence": true,
|
||||||
|
"vision_may_write_research_capsules": false,
|
||||||
|
"vision_may_perform_research_synthesis": false
|
||||||
|
},
|
||||||
|
"disclosure_contract": {
|
||||||
|
"provider_mode_required": true,
|
||||||
|
"retention_required": true,
|
||||||
|
"validation_status_required": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# Svrnty Vision Legacy Ingest
|
||||||
|
|
||||||
|
Schema: `cortex.svrnty-vision.legacy-ingest.v1`
|
||||||
|
Last reviewed: `2026-06-18`
|
||||||
|
|
||||||
|
This file is Svrnty Vision child-local operator state. It is not Cortex OS Core
|
||||||
|
SOT, not Seed installation authority, not Runtime startup authority, not Docker
|
||||||
|
lifecycle authority, not Profile Exposure authority, not provider authority, not
|
||||||
|
credential access, and not readiness or release approval.
|
||||||
|
|
||||||
|
Legacy vision work is assessed by intention first. Old work is kept, ported,
|
||||||
|
archived outside the umbrella, deferred, or rejected only after the useful
|
||||||
|
intention is identified and compared against the current Svrnty Vision route.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Do not import BTE service coupling, cloud-provider credentials, backend state,
|
||||||
|
runtime behavior, Docker lifecycle effects, or wildcard tool grants.
|
||||||
|
- Do not start FastAPI/Uvicorn, Docker, Runtime, VLM, FLUX, Spark, ComfyUI,
|
||||||
|
vLLM, rembg, palette extraction, or cloud image providers from cleanup work.
|
||||||
|
- Keep records compact: refs, intention, current coverage, decision, closure
|
||||||
|
gate, and forbidden effects.
|
||||||
|
|
||||||
|
## Current Gates
|
||||||
|
|
||||||
|
### BTE-Embedded Vision Extraction
|
||||||
|
|
||||||
|
- Source refs: `src/svrnty_vision/`, `README.md`, and BTE-shaped route-adapter
|
||||||
|
docs.
|
||||||
|
- Intention: move VLM, FLUX, palette, and cutout capability out of BTE so BTE
|
||||||
|
remains narrow and sovereign-first.
|
||||||
|
- Current coverage: met as standalone FastAPI gateway source with local
|
||||||
|
validator and documented BTE-shaped HTTP adapters.
|
||||||
|
- Decision: keep as active route-local source; do not re-import BTE coupling.
|
||||||
|
- Closure gate: BTE reintegration, endpoint calls, or Runtime startup requires
|
||||||
|
governed approval and redacted proof.
|
||||||
|
|
||||||
|
### Visual Perception Package Candidate
|
||||||
|
|
||||||
|
- Source refs: `docs/VISION-PACKAGE-CANDIDATE.md`,
|
||||||
|
`docs/VISUAL-EVIDENCE-CONTRACT.md`,
|
||||||
|
`docs/VISION-HOST-ADAPTER-CANDIDATES.md`, and `candidate-manifests/`.
|
||||||
|
- Intention: preserve a Cortex OS candidate package for canonical sense
|
||||||
|
`VISION` without granting Seed installation, Runtime startup, or wildcard
|
||||||
|
tool authority.
|
||||||
|
- Current coverage: met as package-candidate docs, host-adapter candidates,
|
||||||
|
tool-grant manifests, and visual-evidence contract.
|
||||||
|
- Decision: keep as candidate material only.
|
||||||
|
- Closure gate: Core promotion, Seed installation, Profile Exposure, or
|
||||||
|
wildcard grants require separate governed route approval.
|
||||||
|
|
||||||
|
### Provider And Heavy-Model Boundaries
|
||||||
|
|
||||||
|
- Source refs: `README.md`, `.env.example`, `src/svrnty_vision/settings.py`,
|
||||||
|
and route docs.
|
||||||
|
- Intention: document Spark-hosted heavy model dependencies while keeping the
|
||||||
|
child route from owning those services or credentials.
|
||||||
|
- Current coverage: met as operator/developer docs and settings shape.
|
||||||
|
- Decision: keep only configuration shape and boundary docs.
|
||||||
|
- Closure gate: provider calls, Spark/ComfyUI/vLLM calls, credential reads, or
|
||||||
|
Docker/server startup are outside cleanup authority.
|
||||||
|
|
||||||
|
### Generated Cache Custody
|
||||||
|
|
||||||
|
- Source refs:
|
||||||
|
`/home/svrnty/workspaces/cortex-os-retired/2026-06-18/svrnty-vision-python-cache-preserved-141800/`.
|
||||||
|
- Intention: remove interpreter-generated cache residue from the active child
|
||||||
|
route without deleting custody proof.
|
||||||
|
- Current coverage: met by preserving the cache outside the umbrella and adding
|
||||||
|
a route-local validator guard against recurrence.
|
||||||
|
- Decision: reject generated cache material as archive-only, not source,
|
||||||
|
evidence, authority, or package candidate material.
|
||||||
|
- Closure gate: future cache recurrence fails
|
||||||
|
`python3 tools/validate_svrnty_vision_child.py`; no runtime, Docker, provider,
|
||||||
|
credential, Core, Seed, Hindsight, or sibling-route effects are implied.
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# VISION Host Adapter Candidates
|
||||||
|
|
||||||
|
Status: candidate only. These adapter manifests do not install into Seed and do
|
||||||
|
not grant host access.
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
|
||||||
|
Claude Code, Codex CLI, and Pi-Code should expose the same VISION package
|
||||||
|
capabilities when Seed accepts the package. Each host adapter is thin: it maps
|
||||||
|
host-specific command shape to the same package tool ids and the same disclosure
|
||||||
|
contract.
|
||||||
|
|
||||||
|
## Host Targets
|
||||||
|
|
||||||
|
- `claude-code`
|
||||||
|
- `codex-cli`
|
||||||
|
- `pi-code`
|
||||||
|
|
||||||
|
## Parity Rule
|
||||||
|
|
||||||
|
Each host adapter candidate must expose the same current tool ids, the same
|
||||||
|
planned tool ids, no wildcard grant, and the same Visual Evidence disclosure
|
||||||
|
contract.
|
||||||
|
|
||||||
|
## Candidate Manifests
|
||||||
|
|
||||||
|
- `candidate-manifests/host-adapters/vision-claude-code-adapter.json`
|
||||||
|
- `candidate-manifests/host-adapters/vision-codex-cli-adapter.json`
|
||||||
|
- `candidate-manifests/host-adapters/vision-pi-code-adapter.json`
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# VISION Package Candidate
|
||||||
|
|
||||||
|
Status: child-local candidate only. No Core promotion, Seed installation,
|
||||||
|
Runtime start, Profile Exposure, or provider admission is authorized. No
|
||||||
|
wildcard grant is authorized by this document.
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
|
||||||
|
`svrnty-vision` is the generic visual-perception package candidate for the
|
||||||
|
canonical Cortex OS sense `VISION`. It owns tools that inspect or produce pixels,
|
||||||
|
images, screenshots, browser observations, layouts, charts, diagrams, grounded
|
||||||
|
regions, segmentations, video frames, or generated/edited images.
|
||||||
|
|
||||||
|
`research` is also under the `VISION` sense family, but it owns textual/source
|
||||||
|
reading and research workflows. The boundary is by capability, not by sense name:
|
||||||
|
Research reads sources; Vision sees media.
|
||||||
|
|
||||||
|
## Current Route Adapters
|
||||||
|
|
||||||
|
| Current route | Candidate tool id | Capability |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `POST /vlm/analyze` | `vision.image_analyze` | Analyze image input with a VLM and return a normalized observation. |
|
||||||
|
| `POST /flux/render` | `vision.image_generate` | Generate image output through the existing FLUX route. |
|
||||||
|
| `POST /palette/extract` | `vision.palette_extract` | Extract dominant colors from image input. |
|
||||||
|
| `POST /rembg/cutout` | `vision.background_cutout` | Remove image background and return cutout output. |
|
||||||
|
|
||||||
|
## Planned Tool Candidates
|
||||||
|
|
||||||
|
The complete VISION visual-perception package should cover:
|
||||||
|
|
||||||
|
- `vision.ocr_read`
|
||||||
|
- `vision.screenshot_observe`
|
||||||
|
- `vision.browser_observe`
|
||||||
|
- `vision.document_layout_read`
|
||||||
|
- `vision.chart_read`
|
||||||
|
- `vision.table_read`
|
||||||
|
- `vision.diagram_read`
|
||||||
|
- `vision.object_detect`
|
||||||
|
- `vision.visual_ground`
|
||||||
|
- `vision.segment`
|
||||||
|
- `vision.video_read`
|
||||||
|
- `vision.image_edit`
|
||||||
|
|
||||||
|
These are not implemented or granted by this slice. They are named so future
|
||||||
|
work has a canonical target and does not duplicate Research capabilities.
|
||||||
|
|
||||||
|
## Boundary
|
||||||
|
|
||||||
|
Owned here:
|
||||||
|
|
||||||
|
- Pixel/media perception.
|
||||||
|
- Visual evidence production.
|
||||||
|
- Image generation or editing.
|
||||||
|
- Visual extraction from screenshots, browser views, image files, video frames,
|
||||||
|
charts, diagrams, and layouts.
|
||||||
|
|
||||||
|
Not owned here:
|
||||||
|
|
||||||
|
- Web search.
|
||||||
|
- Page fetch.
|
||||||
|
- PDF text extraction.
|
||||||
|
- Research synthesis.
|
||||||
|
- Deep research planning.
|
||||||
|
- Capsule writing.
|
||||||
|
- Profile Exposure.
|
||||||
|
- Runtime startup.
|
||||||
|
- Provider admission.
|
||||||
|
|
||||||
|
Research can consume Visual Evidence only through an explicit handoff contract.
|
||||||
|
Vision never becomes a research synthesizer by returning evidence.
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Visual Evidence Contract
|
||||||
|
|
||||||
|
Status: candidate contract. This is route-only evidence for Cortex OS and Seed
|
||||||
|
review. It does not grant tools or promote the package.
|
||||||
|
|
||||||
|
## Required Fields
|
||||||
|
|
||||||
|
Every Visual Evidence record must include:
|
||||||
|
|
||||||
|
- `producing_package_id`
|
||||||
|
- `producing_tool_id`
|
||||||
|
- `capability_surface`
|
||||||
|
- `source_reference`
|
||||||
|
- `provider_mode`
|
||||||
|
- `retention_disclosure`
|
||||||
|
- `observed_content_summary`
|
||||||
|
- `extracted_claims`
|
||||||
|
- `confidence`
|
||||||
|
- `caveats`
|
||||||
|
- `timestamp`
|
||||||
|
- `validation_status`
|
||||||
|
|
||||||
|
## First Vertical Proof
|
||||||
|
|
||||||
|
The first proof adapts a raw-mode `POST /vlm/analyze` response into Visual
|
||||||
|
Evidence through a pure Python adapter. It does not call a live provider.
|
||||||
|
|
||||||
|
Proof module: `src/svrnty_vision/visual_evidence.py`
|
||||||
|
|
||||||
|
Proof test: `tests/test_visual_evidence.py`
|
||||||
|
|
||||||
|
## Research Handoff Rule
|
||||||
|
|
||||||
|
Research may cite Visual Evidence as an input source if the record includes the
|
||||||
|
required fields and validation status. Research owns synthesis and capsule writing.
|
||||||
|
Vision owns the visual observation record only.
|
||||||
|
|
||||||
|
## Provider And Retention Disclosure
|
||||||
|
|
||||||
|
Provider mode and retention are mandatory because host agents must be able to
|
||||||
|
disclose how the visual observation was produced. Missing disclosure invalidates
|
||||||
|
the evidence record.
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"schema": "svrnty-vision.bte-product-ready-local-vlm-provider-proof.v1",
|
||||||
|
"timestamp": "2026-06-19T20:16:43Z",
|
||||||
|
"work_item_id": "SVRNTY-VISION-WORK-008",
|
||||||
|
"route": "svrnty-vision",
|
||||||
|
"goal": "Prove the configured local VLM provider is reachable for the BTE Product Ready provider-call chain without claiming readiness.",
|
||||||
|
"approval": {
|
||||||
|
"name": "BTE Product Ready local VLM provider proof refresh",
|
||||||
|
"expires_after_report": true
|
||||||
|
},
|
||||||
|
"provider_route_resolution": {
|
||||||
|
"registered_ollama_provider_route_found": false,
|
||||||
|
"adapter_owner_route_used_for_proof": "svrnty-vision",
|
||||||
|
"reason": "svrnty-vision owns the configured VLM adapter endpoint used by BTE through /vlm/analyze"
|
||||||
|
},
|
||||||
|
"configured_provider": {
|
||||||
|
"kind": "local_ollama_openai_compatible",
|
||||||
|
"base_url": "http://100.88.167.87:11434",
|
||||||
|
"expected_model": "qwen3-vl:32b"
|
||||||
|
},
|
||||||
|
"health_proof": {
|
||||||
|
"ollama_tags": {
|
||||||
|
"url": "http://100.88.167.87:11434/api/tags",
|
||||||
|
"http_status": 200,
|
||||||
|
"duration_seconds": 0.004933,
|
||||||
|
"expected_model_present": true
|
||||||
|
},
|
||||||
|
"openai_models": {
|
||||||
|
"url": "http://100.88.167.87:11434/v1/models",
|
||||||
|
"http_status": 200,
|
||||||
|
"duration_seconds": 0.001439,
|
||||||
|
"expected_model_present": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gateway_recheck": {
|
||||||
|
"host_healthz": {
|
||||||
|
"url": "http://localhost:8092/healthz",
|
||||||
|
"http_status": 200,
|
||||||
|
"duration_seconds": 0.001575,
|
||||||
|
"body_status": "ok",
|
||||||
|
"version": "0.1.0"
|
||||||
|
},
|
||||||
|
"bte_runtime_namespace_healthz": {
|
||||||
|
"url": "http://localhost:8092/healthz",
|
||||||
|
"http_status": 200,
|
||||||
|
"duration_seconds": 0.000823,
|
||||||
|
"body_status": "ok",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"downstream_bte_result_ref": "../bte/docs/goal-runs/bte-product-ready-local-vlm-provider-refresh/bte-work-020-successful-provider-call.json",
|
||||||
|
"route_validator": {
|
||||||
|
"command": "python3 tools/validate_svrnty_vision_child.py",
|
||||||
|
"status": "pass"
|
||||||
|
},
|
||||||
|
"tool_effects": {
|
||||||
|
"provider_health_probe_performed": true,
|
||||||
|
"provider_start_or_refresh_performed": false,
|
||||||
|
"direct_model_inference_performed": false,
|
||||||
|
"gateway_runtime_started": false,
|
||||||
|
"bte_provider_call_performed_by_bte_route": true,
|
||||||
|
"profile_exposure_changed": false,
|
||||||
|
"mcp_registered": false,
|
||||||
|
"archive_delete_performed": false,
|
||||||
|
"raw_payload_storage_created_by_this_route": false,
|
||||||
|
"product_ready_claim_made": false
|
||||||
|
},
|
||||||
|
"status": "local_vlm_provider_health_proven"
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
# SVRNTY-VISION-WORK-008 Local VLM Provider Proof
|
||||||
|
|
||||||
|
Status: local VLM provider health proven.
|
||||||
|
|
||||||
|
Approval: `BTE Product Ready local VLM provider proof refresh`.
|
||||||
|
|
||||||
|
Proof:
|
||||||
|
|
||||||
|
- No separate registered Ollama provider route was found; `svrnty-vision` owns the adapter endpoint used by BTE through `/vlm/analyze`.
|
||||||
|
- `GET http://100.88.167.87:11434/api/tags`: HTTP `200`; `qwen3-vl:32b` present.
|
||||||
|
- `GET http://100.88.167.87:11434/v1/models`: HTTP `200`; `qwen3-vl:32b` present.
|
||||||
|
- `GET http://localhost:8092/healthz`: HTTP `200`, status `ok`, version `0.1.0`.
|
||||||
|
- From the BTE runtime namespace, `GET http://localhost:8092/healthz`: HTTP `200`, status `ok`, version `0.1.0`.
|
||||||
|
|
||||||
|
Boundary:
|
||||||
|
|
||||||
|
- No provider start or refresh was needed.
|
||||||
|
- No direct model inference was performed from this route.
|
||||||
|
- No credentials, secrets, raw model payloads, or image payloads were recorded.
|
||||||
|
- No Profile Exposure, MCP registration, archive/delete, raw payload storage, release claim, or Product Ready claim happened.
|
||||||
|
|
||||||
|
Validators:
|
||||||
|
|
||||||
|
- `python3 tools/validate_svrnty_vision_child.py`: PASS.
|
||||||
|
- `python3 tools/validate_svrnty_vision_bte_local_vlm_provider_proof.py`: PASS.
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"schema": "svrnty-vision.bte-product-ready-provider-gateway-refresh-proof.v1",
|
||||||
|
"timestamp": "2026-06-19T20:08:14Z",
|
||||||
|
"work_item_id": "SVRNTY-VISION-WORK-007",
|
||||||
|
"route": "svrnty-vision",
|
||||||
|
"goal": "Provide bounded provider-gateway health proof for the BTE Product Ready live-effect chain without claiming readiness.",
|
||||||
|
"approval": {
|
||||||
|
"name": "BTE Product Ready provider gateway proof refresh",
|
||||||
|
"expired": true,
|
||||||
|
"expiry_reason": "first_failed_blocked_effect:bte_provider_call_timeout"
|
||||||
|
},
|
||||||
|
"precondition": {
|
||||||
|
"bte_expected_url": "http://localhost:8092/healthz",
|
||||||
|
"initial_host_health_status": "connection_refused"
|
||||||
|
},
|
||||||
|
"gateway_refresh": {
|
||||||
|
"image": "cortex-os/vision:seed",
|
||||||
|
"host_port_container": {
|
||||||
|
"name": "svrnty-vision-bte-proof",
|
||||||
|
"container_id_prefix": "b25509d4d640",
|
||||||
|
"mapping": "0.0.0.0:8092->8094/tcp",
|
||||||
|
"healthz": {
|
||||||
|
"url": "http://localhost:8092/healthz",
|
||||||
|
"http_status": 200,
|
||||||
|
"body_status": "ok",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bte_network_namespace_container": {
|
||||||
|
"name": "svrnty-vision-bte-net-proof",
|
||||||
|
"container_id_prefix": "a9a916ad2f5c",
|
||||||
|
"network": "container:bte-rest-mcp-readiness-api",
|
||||||
|
"env_override": "SVRNTY_VISION_PORT=8092",
|
||||||
|
"healthz_from_bte_runtime_namespace": {
|
||||||
|
"url": "http://localhost:8092/healthz",
|
||||||
|
"http_status": 200,
|
||||||
|
"body_status": "ok",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"downstream_bte_recheck": {
|
||||||
|
"readyz": {
|
||||||
|
"url": "http://localhost:6001/readyz",
|
||||||
|
"http_status": 200,
|
||||||
|
"body_status": "Healthy"
|
||||||
|
},
|
||||||
|
"provider_call_result_ref": "../bte/docs/goal-runs/bte-product-ready-provider-gateway-refresh/bte-work-019-provider-gateway-refresh-and-provider-call.json"
|
||||||
|
},
|
||||||
|
"route_validator": {
|
||||||
|
"command": "python3 tools/validate_svrnty_vision_child.py",
|
||||||
|
"status": "pass"
|
||||||
|
},
|
||||||
|
"tool_effects": {
|
||||||
|
"gateway_runtime_started": true,
|
||||||
|
"provider_call_from_this_route": false,
|
||||||
|
"profile_exposure_changed": false,
|
||||||
|
"mcp_registered": false,
|
||||||
|
"archive_delete_performed": false,
|
||||||
|
"raw_payload_storage_created": false,
|
||||||
|
"product_ready_claim_made": false
|
||||||
|
},
|
||||||
|
"status": "gateway_health_proven_provider_call_blocked_downstream"
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
# SVRNTY-VISION-WORK-007 Provider Gateway Refresh
|
||||||
|
|
||||||
|
Status: gateway health proven; downstream BTE provider call blocked.
|
||||||
|
|
||||||
|
Approval: `BTE Product Ready provider gateway proof refresh`. The approval expired after the first failed blocked effect: the bounded BTE provider call timed out at the local VLM backend.
|
||||||
|
|
||||||
|
Proof:
|
||||||
|
|
||||||
|
- `svrnty-vision-bte-proof` started from `cortex-os/vision:seed` and mapped host `8092` to container `8094`.
|
||||||
|
- `GET http://localhost:8092/healthz`: HTTP `200`, status `ok`, version `0.1.0`.
|
||||||
|
- `svrnty-vision-bte-net-proof` started from `cortex-os/vision:seed` in the BTE runtime network namespace with `SVRNTY_VISION_PORT=8092`.
|
||||||
|
- From `bte-rest-mcp-readiness-api`, `GET http://localhost:8092/healthz`: HTTP `200`, status `ok`, version `0.1.0`.
|
||||||
|
- BTE `GET http://localhost:6001/readyz`: HTTP `200`, status `Healthy`.
|
||||||
|
|
||||||
|
Boundary:
|
||||||
|
|
||||||
|
- No credentials or secrets were read or recorded.
|
||||||
|
- No Profile Exposure, MCP registration, archive/delete, raw payload storage, release claim, or Product Ready claim happened.
|
||||||
|
- This route did not call the VLM provider directly. The downstream bounded BTE provider-call result is recorded in BTE proof `bte-work-019`.
|
||||||
|
|
||||||
|
Validator:
|
||||||
|
|
||||||
|
- `python3 tools/validate_svrnty_vision_child.py`: PASS.
|
||||||
|
- `python3 tools/validate_svrnty_vision_bte_provider_gateway_refresh.py`: PASS.
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# SVRNTY-VISION-WORK-002 Validation Evidence
|
||||||
|
|
||||||
|
Date: 2026-06-06
|
||||||
|
|
||||||
|
Scope: generic Cortex OS VISION package candidate and Visual Evidence proof for
|
||||||
|
`svrnty-vision`.
|
||||||
|
|
||||||
|
## What Changed
|
||||||
|
|
||||||
|
- Added child-local VISION package candidate docs and manifests.
|
||||||
|
- Mapped current HTTP routes to candidate tool ids.
|
||||||
|
- Added granular tool-grant candidate manifest with no wildcard grants.
|
||||||
|
- Added Visual Evidence contract and a pure VLM response adapter proof.
|
||||||
|
- Added host adapter candidate manifests for Claude Code, Codex CLI, and
|
||||||
|
Pi-Code.
|
||||||
|
- Added a local sandcastle handoff for the next Seed acceptance route.
|
||||||
|
- Fixed package dependency declaration from `rembg` to `rembg[cpu]` so the
|
||||||
|
background cutout route has the required CPU backend on fresh installs.
|
||||||
|
|
||||||
|
## Gates Passed
|
||||||
|
|
||||||
|
- `python3 tools/validate_vision_package_candidate.py`
|
||||||
|
- `python3 tools/validate_vision_tool_grants.py`
|
||||||
|
- `python3 tools/validate_visual_evidence_contract.py`
|
||||||
|
- `python3 tools/validate_vision_host_adapter_candidates.py`
|
||||||
|
- `python3 tools/validate_svrnty_vision_child.py`
|
||||||
|
- `.venv/bin/python tools/validate_svrnty_vision_child.py`
|
||||||
|
- `pytest --noconftest tests/test_visual_evidence.py`
|
||||||
|
- `.venv/bin/pytest tests/ -m 'not integration'`
|
||||||
|
- `python3 -m py_compile src/svrnty_vision/visual_evidence.py tools/validate_vision_package_candidate.py tools/validate_vision_tool_grants.py tools/validate_visual_evidence_contract.py tools/validate_vision_host_adapter_candidates.py tools/validate_svrnty_vision_child.py`
|
||||||
|
- `.venv/bin/python -m py_compile src/svrnty_vision/visual_evidence.py tools/validate_vision_package_candidate.py tools/validate_vision_tool_grants.py tools/validate_visual_evidence_contract.py tools/validate_vision_host_adapter_candidates.py tools/validate_svrnty_vision_child.py`
|
||||||
|
- `git diff --check`
|
||||||
|
|
||||||
|
## Test Result
|
||||||
|
|
||||||
|
Non-integration suite after `rembg[cpu]` dependency fix:
|
||||||
|
|
||||||
|
- 30 passed.
|
||||||
|
- 10 integration tests deselected.
|
||||||
|
- 1 Starlette/httpx deprecation warning.
|
||||||
|
|
||||||
|
## Boundaries Preserved
|
||||||
|
|
||||||
|
- No Core mutation.
|
||||||
|
- No Seed installation.
|
||||||
|
- No Runtime start.
|
||||||
|
- No Profile Exposure.
|
||||||
|
- No provider admission.
|
||||||
|
- No wildcard grant.
|
||||||
|
- No Research synthesis in Vision.
|
||||||
|
|
||||||
|
## Follow-Up
|
||||||
|
|
||||||
|
Follow-up, optional: update the FastAPI/TestClient dependency path when the
|
||||||
|
Starlette/httpx deprecation becomes a compatibility issue.
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"schema_version": "svrnty-vision-workboard-readiness-reconciliation.v1",
|
||||||
|
"status": "complete",
|
||||||
|
"ok": true,
|
||||||
|
"cc": "core-compliant",
|
||||||
|
"date": "2026-06-12",
|
||||||
|
"workspace": "svrnty-vision",
|
||||||
|
"reconciled_rows": [
|
||||||
|
{
|
||||||
|
"id": "SVRNTY-VISION-WORK-001",
|
||||||
|
"from": "candidate",
|
||||||
|
"to": "complete",
|
||||||
|
"reason": "Workspace governance, rules, docs, board, and validator are present."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "SVRNTY-VISION-WORK-003",
|
||||||
|
"from": "ready-for-agent",
|
||||||
|
"to": "complete",
|
||||||
|
"reason": "The sandcastle handoff exists; successor consumption belongs to governed Seed/Core routes."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"evidence": [
|
||||||
|
"AGENTS.md",
|
||||||
|
"README.md",
|
||||||
|
"WORKBOARD.yaml",
|
||||||
|
"CONTEXT.md",
|
||||||
|
"docs/VISION-PACKAGE-CANDIDATE.md",
|
||||||
|
"docs/VISUAL-EVIDENCE-CONTRACT.md",
|
||||||
|
"docs/VISION-HOST-ADAPTER-CANDIDATES.md",
|
||||||
|
"candidate-manifests/vision-package-candidate.json",
|
||||||
|
"candidate-manifests/vision-tool-grants.json",
|
||||||
|
"candidate-manifests/visual-evidence-contract.json",
|
||||||
|
"tools/validate_svrnty_vision_child.py"
|
||||||
|
],
|
||||||
|
"false_claims": {
|
||||||
|
"core_promotion": false,
|
||||||
|
"seed_installation": false,
|
||||||
|
"runtime_started": false,
|
||||||
|
"profile_exposure_changed": false,
|
||||||
|
"provider_admitted": false,
|
||||||
|
"wildcard_grant": false,
|
||||||
|
"sibling_mutation": false
|
||||||
|
},
|
||||||
|
"next_roi": "Consume this validated package candidate through governed Seed/Core routes when package release and Runtime approval gates allow it."
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
title: Svrnty Vision Workboard Readiness Reconciliation
|
||||||
|
date: 2026-06-12
|
||||||
|
source: output
|
||||||
|
cc: core-compliant
|
||||||
|
status: complete
|
||||||
|
---
|
||||||
|
|
||||||
|
# Svrnty Vision Workboard Readiness Reconciliation
|
||||||
|
|
||||||
|
`svrnty-vision` is child-local validated as the Cortex OS VISION package
|
||||||
|
candidate. Its remaining candidate and ready-for-agent workboard rows were stale
|
||||||
|
workspace status, not missing local package evidence.
|
||||||
|
|
||||||
|
## Reconciled Rows
|
||||||
|
|
||||||
|
- `SVRNTY-VISION-WORK-001`: `candidate` -> `complete`; workspace governance,
|
||||||
|
local rules, docs, board, and validator are present.
|
||||||
|
- `SVRNTY-VISION-WORK-003`: `ready-for-agent` -> `complete`; the sandcastle
|
||||||
|
handoff exists and its next ROI belongs to Seed consumption, not more local
|
||||||
|
Vision package work.
|
||||||
|
|
||||||
|
## Evidence
|
||||||
|
|
||||||
|
- `python3 tools/validate_svrnty_vision_child.py`: green.
|
||||||
|
- `docs/VISION-PACKAGE-CANDIDATE.md`: package boundary.
|
||||||
|
- `docs/VISUAL-EVIDENCE-CONTRACT.md`: Visual Evidence contract.
|
||||||
|
- `docs/VISION-HOST-ADAPTER-CANDIDATES.md`: host adapter candidates.
|
||||||
|
- `candidate-manifests/`: package, grants, evidence, and host adapter
|
||||||
|
manifests.
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
No Core promotion, Seed installation, Runtime start, Profile Exposure, provider
|
||||||
|
admission, wildcard grant, or sibling mutation is claimed here.
|
||||||
|
|
||||||
|
## Next ROI
|
||||||
|
|
||||||
|
Consume this validated package candidate through governed Seed/Core routes when
|
||||||
|
package release and Runtime approval gates allow it.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# Vision Package Candidate Sandcastle
|
||||||
|
|
||||||
|
Status: ready for the next agent. This sandcastle belongs inside
|
||||||
|
`svrnty-vision`; it is not an umbrella repo and not a Core route.
|
||||||
|
|
||||||
|
## End State
|
||||||
|
|
||||||
|
Make `svrnty-vision` Seed-acceptable as the generic Cortex OS VISION
|
||||||
|
visual-perception package candidate, with host parity for Claude Code, Codex CLI,
|
||||||
|
and Pi-Code, granular grants, and Visual Evidence disclosure.
|
||||||
|
|
||||||
|
## Current Vertical Slice
|
||||||
|
|
||||||
|
- Package boundary documented.
|
||||||
|
- Current BTE routes mapped to Cortex OS candidate tool ids.
|
||||||
|
- Planned SOTA visual tool inventory named without implementing all tools.
|
||||||
|
- Visual Evidence contract documented.
|
||||||
|
- VLM raw-mode output adapted into Visual Evidence through a pure proof.
|
||||||
|
- Host adapter candidate parity documented.
|
||||||
|
|
||||||
|
## Stop Conditions
|
||||||
|
|
||||||
|
- Do not mutate Core from this workspace.
|
||||||
|
- Do not install into Seed from this workspace.
|
||||||
|
- Do not start Runtime.
|
||||||
|
- Do not grant Profile Exposure.
|
||||||
|
- Do not admit providers.
|
||||||
|
- Do not wildcard expose all tools.
|
||||||
|
|
||||||
|
## Next ROI
|
||||||
|
|
||||||
|
Build the first Seed route outside this workspace that can accept these manifests
|
||||||
|
as candidate artifacts, then prove one host adapter can expose exactly one tool
|
||||||
|
grant without wildcard access.
|
||||||
+1
-1
@@ -20,7 +20,7 @@ dependencies = [
|
|||||||
"httpx>=0.27,<1.0",
|
"httpx>=0.27,<1.0",
|
||||||
"Pillow>=11,<13",
|
"Pillow>=11,<13",
|
||||||
"colorthief>=0.2.1",
|
"colorthief>=0.2.1",
|
||||||
"rembg>=2.0,<3.0",
|
"rembg[cpu]>=2.0,<3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ pydantic-settings>=2.6,<3.0
|
|||||||
httpx>=0.27,<1.0
|
httpx>=0.27,<1.0
|
||||||
Pillow>=11,<13
|
Pillow>=11,<13
|
||||||
colorthief>=0.2.1
|
colorthief>=0.2.1
|
||||||
rembg>=2.0,<3.0
|
rembg[cpu]>=2.0,<3.0
|
||||||
|
|
||||||
# Test deps
|
# Test deps
|
||||||
pytest>=8.3,<9.0
|
pytest>=8.3,<9.0
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
"""Visual Evidence adapter for Cortex OS VISION package candidates."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from typing import Any, Protocol
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
PACKAGE_ID = "visual-perception-package-candidate"
|
||||||
|
DEFAULT_VALIDATION_STATUS = "candidate_validated"
|
||||||
|
|
||||||
|
|
||||||
|
class VlmAnalysisResponse(Protocol):
|
||||||
|
justification: str
|
||||||
|
model_id: str
|
||||||
|
raw_scores_json: str
|
||||||
|
|
||||||
|
|
||||||
|
class VisualEvidence(BaseModel):
|
||||||
|
"""Normalized visual observation record for host disclosure and handoff."""
|
||||||
|
|
||||||
|
producing_package_id: str = PACKAGE_ID
|
||||||
|
producing_tool_id: str
|
||||||
|
capability_surface: str
|
||||||
|
source_reference: str
|
||||||
|
provider_mode: str
|
||||||
|
retention_disclosure: str
|
||||||
|
observed_content_summary: str
|
||||||
|
extracted_claims: list[str] = Field(default_factory=list)
|
||||||
|
confidence: str
|
||||||
|
caveats: list[str] = Field(default_factory=list)
|
||||||
|
timestamp: str
|
||||||
|
validation_status: str
|
||||||
|
model_id: str | None = None
|
||||||
|
raw_observation_ref: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def visual_evidence_from_vlm_response(
|
||||||
|
response: VlmAnalysisResponse,
|
||||||
|
*,
|
||||||
|
source_reference: str,
|
||||||
|
provider_mode: str,
|
||||||
|
retention_disclosure: str,
|
||||||
|
timestamp: str,
|
||||||
|
producing_tool_id: str = "vision.image_analyze",
|
||||||
|
capability_surface: str = "vision.image_analyze",
|
||||||
|
confidence: str = "medium",
|
||||||
|
caveats: list[str] | None = None,
|
||||||
|
validation_status: str = DEFAULT_VALIDATION_STATUS,
|
||||||
|
) -> VisualEvidence:
|
||||||
|
"""Adapt the current VLM response into a Cortex OS Visual Evidence record."""
|
||||||
|
|
||||||
|
_require_non_empty("source_reference", source_reference)
|
||||||
|
_require_non_empty("provider_mode", provider_mode)
|
||||||
|
_require_non_empty("retention_disclosure", retention_disclosure)
|
||||||
|
_require_non_empty("timestamp", timestamp)
|
||||||
|
|
||||||
|
raw_text = response.raw_scores_json.strip()
|
||||||
|
parsed = _parse_json_object(raw_text)
|
||||||
|
summary = _summary_from_response(parsed, response.justification, raw_text)
|
||||||
|
claims = _claims_from_raw(parsed, raw_text)
|
||||||
|
if not claims and summary:
|
||||||
|
claims = [f"summary: {summary}"]
|
||||||
|
|
||||||
|
return VisualEvidence(
|
||||||
|
producing_tool_id=producing_tool_id,
|
||||||
|
capability_surface=capability_surface,
|
||||||
|
source_reference=source_reference,
|
||||||
|
provider_mode=provider_mode,
|
||||||
|
retention_disclosure=retention_disclosure,
|
||||||
|
observed_content_summary=summary,
|
||||||
|
extracted_claims=claims,
|
||||||
|
confidence=confidence,
|
||||||
|
caveats=caveats or [],
|
||||||
|
timestamp=timestamp,
|
||||||
|
validation_status=validation_status,
|
||||||
|
model_id=response.model_id,
|
||||||
|
raw_observation_ref="AnalyzeResponse.raw_scores_json",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _require_non_empty(field_name: str, value: str) -> None:
|
||||||
|
if not value or not value.strip():
|
||||||
|
raise ValueError(f"{field_name} is required for Visual Evidence")
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_json_object(raw_text: str) -> dict[str, Any] | None:
|
||||||
|
if not raw_text:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
parsed = json.loads(raw_text)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return None
|
||||||
|
return parsed if isinstance(parsed, dict) else None
|
||||||
|
|
||||||
|
|
||||||
|
def _summary_from_response(
|
||||||
|
parsed: dict[str, Any] | None, justification: str, raw_text: str
|
||||||
|
) -> str:
|
||||||
|
if parsed:
|
||||||
|
for key in (
|
||||||
|
"observed_content_summary",
|
||||||
|
"summary",
|
||||||
|
"description",
|
||||||
|
"caption",
|
||||||
|
"text",
|
||||||
|
):
|
||||||
|
value = parsed.get(key)
|
||||||
|
if isinstance(value, str) and value.strip():
|
||||||
|
return _compact(value)
|
||||||
|
if justification.strip():
|
||||||
|
return _compact(justification)
|
||||||
|
return _compact(raw_text)
|
||||||
|
|
||||||
|
|
||||||
|
def _claims_from_raw(parsed: dict[str, Any] | None, raw_text: str) -> list[str]:
|
||||||
|
if not parsed:
|
||||||
|
return [f"raw: {_compact(raw_text)}"] if raw_text else []
|
||||||
|
|
||||||
|
claims: list[str] = []
|
||||||
|
for key, value in parsed.items():
|
||||||
|
claims.append(f"{key}: {_format_claim_value(value)}")
|
||||||
|
return claims
|
||||||
|
|
||||||
|
|
||||||
|
def _format_claim_value(value: Any) -> str:
|
||||||
|
if isinstance(value, list):
|
||||||
|
if not value:
|
||||||
|
return "[]"
|
||||||
|
if all(
|
||||||
|
isinstance(item, str | int | float | bool) or item is None
|
||||||
|
for item in value
|
||||||
|
):
|
||||||
|
return ", ".join(str(item) for item in value)
|
||||||
|
return json.dumps(value, sort_keys=True, separators=(",", ":"))
|
||||||
|
if isinstance(value, dict):
|
||||||
|
return json.dumps(value, sort_keys=True, separators=(",", ":"))
|
||||||
|
if value is None:
|
||||||
|
return "null"
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
|
||||||
|
def _compact(text: str, limit: int = 500) -> str:
|
||||||
|
compacted = " ".join(text.split())
|
||||||
|
if len(compacted) <= limit:
|
||||||
|
return compacted
|
||||||
|
return compacted[: limit - 3].rstrip() + "..."
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from svrnty_vision.visual_evidence import visual_evidence_from_vlm_response
|
||||||
|
|
||||||
|
|
||||||
|
def test_vlm_raw_mode_response_becomes_visual_evidence() -> None:
|
||||||
|
response = SimpleNamespace(
|
||||||
|
rubric_mode="raw",
|
||||||
|
justification="",
|
||||||
|
model_id="qwen-test",
|
||||||
|
raw_scores_json='{"description":"solid red square","objects":["red square"],"detected_text":[]}',
|
||||||
|
)
|
||||||
|
|
||||||
|
evidence = visual_evidence_from_vlm_response(
|
||||||
|
response,
|
||||||
|
source_reference="fixture://red-square.png",
|
||||||
|
provider_mode="sovereign",
|
||||||
|
retention_disclosure="synchronous_no_async_persistence",
|
||||||
|
timestamp="2026-06-06T00:00:00Z",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert evidence.producing_package_id == "visual-perception-package-candidate"
|
||||||
|
assert evidence.producing_tool_id == "vision.image_analyze"
|
||||||
|
assert evidence.capability_surface == "vision.image_analyze"
|
||||||
|
assert evidence.source_reference == "fixture://red-square.png"
|
||||||
|
assert evidence.provider_mode == "sovereign"
|
||||||
|
assert evidence.retention_disclosure == "synchronous_no_async_persistence"
|
||||||
|
assert evidence.observed_content_summary == "solid red square"
|
||||||
|
assert "description: solid red square" in evidence.extracted_claims
|
||||||
|
assert "objects: red square" in evidence.extracted_claims
|
||||||
|
assert "detected_text: []" in evidence.extracted_claims
|
||||||
|
assert evidence.validation_status == "candidate_validated"
|
||||||
|
assert "research_synthesis" not in evidence.model_dump()
|
||||||
|
|
||||||
|
|
||||||
|
def test_non_json_vlm_response_gets_safe_raw_fallback() -> None:
|
||||||
|
response = SimpleNamespace(
|
||||||
|
rubric_mode="raw",
|
||||||
|
justification="",
|
||||||
|
model_id="qwen-test",
|
||||||
|
raw_scores_json="a screenshot of a pricing page with two columns",
|
||||||
|
)
|
||||||
|
|
||||||
|
evidence = visual_evidence_from_vlm_response(
|
||||||
|
response,
|
||||||
|
source_reference="fixture://pricing.png",
|
||||||
|
provider_mode="sovereign",
|
||||||
|
retention_disclosure="synchronous_no_async_persistence",
|
||||||
|
timestamp="2026-06-06T00:00:00Z",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert evidence.observed_content_summary == "a screenshot of a pricing page with two columns"
|
||||||
|
assert evidence.extracted_claims == [
|
||||||
|
"raw: a screenshot of a pricing page with two columns"
|
||||||
|
]
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate the Svrnty Vision local VLM provider proof packet."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
PROOF = ROOT / "docs/goal-runs/bte-product-ready-local-vlm-provider-refresh/svrnty-vision-work-008-local-vlm-provider-proof.json"
|
||||||
|
MD = ROOT / "docs/goal-runs/bte-product-ready-local-vlm-provider-refresh/svrnty-vision-work-008-local-vlm-provider-proof.md"
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition: bool, errors: list[str], message: str) -> None:
|
||||||
|
if not condition:
|
||||||
|
errors.append(message)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
proof = json.loads(PROOF.read_text(encoding="utf-8"))
|
||||||
|
md = MD.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
require(proof.get("schema") == "svrnty-vision.bte-product-ready-local-vlm-provider-proof.v1", errors, "schema")
|
||||||
|
require(proof.get("work_item_id") == "SVRNTY-VISION-WORK-008", errors, "work_item_id")
|
||||||
|
require(proof.get("route") == "svrnty-vision", errors, "route")
|
||||||
|
|
||||||
|
route = proof.get("provider_route_resolution", {})
|
||||||
|
require(route.get("registered_ollama_provider_route_found") is False, errors, "registered_route")
|
||||||
|
require(route.get("adapter_owner_route_used_for_proof") == "svrnty-vision", errors, "adapter_owner")
|
||||||
|
|
||||||
|
provider = proof.get("configured_provider", {})
|
||||||
|
require(provider.get("expected_model") == "qwen3-vl:32b", errors, "expected_model")
|
||||||
|
|
||||||
|
health = proof.get("health_proof", {})
|
||||||
|
for key in ("ollama_tags", "openai_models"):
|
||||||
|
probe = health.get(key, {})
|
||||||
|
require(probe.get("http_status") == 200, errors, f"{key}:http_status")
|
||||||
|
require(probe.get("expected_model_present") is True, errors, f"{key}:model_present")
|
||||||
|
|
||||||
|
gateway = proof.get("gateway_recheck", {})
|
||||||
|
for key in ("host_healthz", "bte_runtime_namespace_healthz"):
|
||||||
|
probe = gateway.get(key, {})
|
||||||
|
require(probe.get("http_status") == 200 and probe.get("body_status") == "ok", errors, f"{key}:healthz")
|
||||||
|
|
||||||
|
effects = proof.get("tool_effects", {})
|
||||||
|
require(effects.get("provider_health_probe_performed") is True, errors, "provider_health_probe")
|
||||||
|
require(effects.get("bte_provider_call_performed_by_bte_route") is True, errors, "bte_provider_call")
|
||||||
|
for key in (
|
||||||
|
"provider_start_or_refresh_performed",
|
||||||
|
"direct_model_inference_performed",
|
||||||
|
"gateway_runtime_started",
|
||||||
|
"profile_exposure_changed",
|
||||||
|
"mcp_registered",
|
||||||
|
"archive_delete_performed",
|
||||||
|
"raw_payload_storage_created_by_this_route",
|
||||||
|
"product_ready_claim_made",
|
||||||
|
):
|
||||||
|
require(effects.get(key) is False, errors, f"forbidden_effect:{key}")
|
||||||
|
|
||||||
|
for snippet in (
|
||||||
|
"local VLM provider health proven",
|
||||||
|
"qwen3-vl:32b",
|
||||||
|
"No direct model inference",
|
||||||
|
"No credentials",
|
||||||
|
"Product Ready claim",
|
||||||
|
):
|
||||||
|
require(snippet in md, errors, f"md_missing:{snippet}")
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "svrnty-vision-bte-local-vlm-provider-proof-v1",
|
||||||
|
"checked": [str(PROOF.relative_to(ROOT)), str(MD.relative_to(ROOT))],
|
||||||
|
"errors": errors,
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2))
|
||||||
|
return 0 if not errors else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate the Svrnty Vision BTE provider-gateway refresh proof."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
PROOF = ROOT / "docs/goal-runs/bte-product-ready-provider-gateway-refresh/svrnty-vision-work-007-provider-gateway-refresh.json"
|
||||||
|
MD = ROOT / "docs/goal-runs/bte-product-ready-provider-gateway-refresh/svrnty-vision-work-007-provider-gateway-refresh.md"
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition: bool, errors: list[str], message: str) -> None:
|
||||||
|
if not condition:
|
||||||
|
errors.append(message)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
proof = json.loads(PROOF.read_text(encoding="utf-8"))
|
||||||
|
md = MD.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
require(proof.get("schema") == "svrnty-vision.bte-product-ready-provider-gateway-refresh-proof.v1", errors, "schema")
|
||||||
|
require(proof.get("work_item_id") == "SVRNTY-VISION-WORK-007", errors, "work_item_id")
|
||||||
|
require(proof.get("route") == "svrnty-vision", errors, "route")
|
||||||
|
require(proof.get("approval", {}).get("expired") is True, errors, "approval_expired")
|
||||||
|
|
||||||
|
refresh = proof.get("gateway_refresh", {})
|
||||||
|
host = refresh.get("host_port_container", {}).get("healthz", {})
|
||||||
|
bte_ns = refresh.get("bte_network_namespace_container", {}).get("healthz_from_bte_runtime_namespace", {})
|
||||||
|
require(host.get("http_status") == 200 and host.get("body_status") == "ok", errors, "host_healthz")
|
||||||
|
require(bte_ns.get("http_status") == 200 and bte_ns.get("body_status") == "ok", errors, "bte_namespace_healthz")
|
||||||
|
|
||||||
|
readyz = proof.get("downstream_bte_recheck", {}).get("readyz", {})
|
||||||
|
require(readyz.get("http_status") == 200 and readyz.get("body_status") == "Healthy", errors, "bte_readyz")
|
||||||
|
|
||||||
|
effects = proof.get("tool_effects", {})
|
||||||
|
require(effects.get("gateway_runtime_started") is True, errors, "gateway_runtime_started")
|
||||||
|
for key in (
|
||||||
|
"provider_call_from_this_route",
|
||||||
|
"profile_exposure_changed",
|
||||||
|
"mcp_registered",
|
||||||
|
"archive_delete_performed",
|
||||||
|
"raw_payload_storage_created",
|
||||||
|
"product_ready_claim_made",
|
||||||
|
):
|
||||||
|
require(effects.get(key) is False, errors, f"forbidden_effect:{key}")
|
||||||
|
|
||||||
|
for snippet in (
|
||||||
|
"No credentials or secrets",
|
||||||
|
"No Profile Exposure",
|
||||||
|
"raw payload storage",
|
||||||
|
"Product Ready claim",
|
||||||
|
"bte-work-019",
|
||||||
|
):
|
||||||
|
require(snippet in md, errors, f"md_missing:{snippet}")
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "svrnty-vision-bte-provider-gateway-refresh-v1",
|
||||||
|
"checked": [str(PROOF.relative_to(ROOT)), str(MD.relative_to(ROOT))],
|
||||||
|
"errors": errors,
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2))
|
||||||
|
return 0 if not errors else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Executable
+140
@@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate Svrnty Vision child workspace governance shell."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
|
GENERATED_ARTIFACT_DIRS = [
|
||||||
|
"src/svrnty_vision/__pycache__",
|
||||||
|
"tools/__pycache__",
|
||||||
|
".pytest_cache",
|
||||||
|
]
|
||||||
|
REQUIRED = [
|
||||||
|
"AGENTS.md",
|
||||||
|
"INDEX.md",
|
||||||
|
"README.md",
|
||||||
|
"WORKBOARD.yaml",
|
||||||
|
"CONTEXT.md",
|
||||||
|
"docs/VISION-PACKAGE-CANDIDATE.md",
|
||||||
|
"docs/VISUAL-EVIDENCE-CONTRACT.md",
|
||||||
|
"docs/VISION-HOST-ADAPTER-CANDIDATES.md",
|
||||||
|
"candidate-manifests/vision-package-candidate.json",
|
||||||
|
"candidate-manifests/vision-tool-grants.json",
|
||||||
|
"candidate-manifests/visual-evidence-contract.json",
|
||||||
|
"outputs/2026-06-12-svrnty-vision-workboard-readiness-reconciliation.md",
|
||||||
|
"outputs/2026-06-12-svrnty-vision-workboard-readiness-reconciliation.json",
|
||||||
|
"Dockerfile",
|
||||||
|
".dockerignore",
|
||||||
|
"tools/validate_vision_package_docker_context.py",
|
||||||
|
]
|
||||||
|
VALIDATORS = [
|
||||||
|
"tools/validate_vision_package_candidate.py",
|
||||||
|
"tools/validate_vision_tool_grants.py",
|
||||||
|
"tools/validate_visual_evidence_contract.py",
|
||||||
|
"tools/validate_vision_host_adapter_candidates.py",
|
||||||
|
"tools/validate_vision_package_docker_context.py",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
validator_outputs: dict[str, str] = {}
|
||||||
|
for rel in REQUIRED:
|
||||||
|
if not (ROOT / rel).exists():
|
||||||
|
errors.append(f"missing:{rel}")
|
||||||
|
checks = {
|
||||||
|
"AGENTS.md": [
|
||||||
|
"## Universal Cortex OS Agent Contract",
|
||||||
|
"## Repo-Custom Agent Contract",
|
||||||
|
"Svrnty Vision is a child-local sovereign vision HTTP gateway",
|
||||||
|
"Do not start Runtime, start Docker, build or run containers",
|
||||||
|
"child-local",
|
||||||
|
"not Cortex OS Core authority",
|
||||||
|
"python3 tools/validate_svrnty_vision_child.py",
|
||||||
|
],
|
||||||
|
"README.md": [
|
||||||
|
"## Cortex OS Boundary",
|
||||||
|
"child-local sovereign vision gateway source",
|
||||||
|
"not start Runtime, start Docker",
|
||||||
|
"call VLM",
|
||||||
|
"call Spark/ComfyUI/vLLM services",
|
||||||
|
"write durable Hindsight memory",
|
||||||
|
"operator/developer docs, not cleanup-route authorization",
|
||||||
|
],
|
||||||
|
"INDEX.md": [
|
||||||
|
"Route: `svrnty-vision`.",
|
||||||
|
"Category: child-local sovereign vision HTTP gateway and Visual Perception Package Candidate workspace.",
|
||||||
|
"Svrnty Vision owns child-local VLM, FLUX, palette, and cutout gateway source",
|
||||||
|
"Svrnty Vision is not Core authority, Seed installation authority, Runtime startup authority",
|
||||||
|
"Stage: CLEAN.",
|
||||||
|
"Clean score: 100.",
|
||||||
|
"Docker, FastAPI/Uvicorn, endpoint calls",
|
||||||
|
],
|
||||||
|
"WORKBOARD.yaml": [
|
||||||
|
"SVRNTY-VISION-WORK-001",
|
||||||
|
"SVRNTY-VISION-WORK-003",
|
||||||
|
"SVRNTY-VISION-WORK-005",
|
||||||
|
"SVRNTY-VISION-WORK-006",
|
||||||
|
"Svrnty Vision Navigation Index",
|
||||||
|
"source: INDEX.md",
|
||||||
|
"status: complete",
|
||||||
|
'owner: ""',
|
||||||
|
],
|
||||||
|
"CONTEXT.md": ["Visual Perception Package Candidate", "Research Handoff"],
|
||||||
|
"docs/VISION-PACKAGE-CANDIDATE.md": ["Research reads sources; Vision sees media", "wildcard grant"],
|
||||||
|
"docs/LEGACY-INGEST.md": ["Generated Cache Custody", "svrnty-vision-python-cache-preserved-141800"],
|
||||||
|
"outputs/2026-06-12-svrnty-vision-workboard-readiness-reconciliation.md": [
|
||||||
|
"No Core promotion",
|
||||||
|
"Seed consumption",
|
||||||
|
"Runtime start",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
for rel, snippets in checks.items():
|
||||||
|
path = ROOT / rel
|
||||||
|
if path.exists():
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
for snippet in snippets:
|
||||||
|
if snippet not in text:
|
||||||
|
errors.append(f"{rel}:missing:{snippet}")
|
||||||
|
for rel in VALIDATORS:
|
||||||
|
path = ROOT / rel
|
||||||
|
if not path.exists():
|
||||||
|
errors.append(f"missing:{rel}")
|
||||||
|
continue
|
||||||
|
env = os.environ.copy()
|
||||||
|
env["PYTHONDONTWRITEBYTECODE"] = "1"
|
||||||
|
completed = subprocess.run(
|
||||||
|
[sys.executable, str(path)],
|
||||||
|
cwd=ROOT,
|
||||||
|
env=env,
|
||||||
|
text=True,
|
||||||
|
capture_output=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
validator_outputs[rel] = completed.stdout.strip()
|
||||||
|
if completed.returncode != 0:
|
||||||
|
errors.append(f"validator_failed:{rel}:{completed.stderr.strip()}")
|
||||||
|
for rel in GENERATED_ARTIFACT_DIRS:
|
||||||
|
if (ROOT / rel).exists():
|
||||||
|
errors.append(f"generated_artifact_residue:{rel}")
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "svrnty-vision-child-v1",
|
||||||
|
"checked": REQUIRED + VALIDATORS,
|
||||||
|
"errors": errors,
|
||||||
|
"warnings": [],
|
||||||
|
"validator_outputs": validator_outputs,
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2, sort_keys=True))
|
||||||
|
return 0 if result["ok"] else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate VISION host adapter candidate parity."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
HOSTS = {
|
||||||
|
"claude-code": "candidate-manifests/host-adapters/vision-claude-code-adapter.json",
|
||||||
|
"codex-cli": "candidate-manifests/host-adapters/vision-codex-cli-adapter.json",
|
||||||
|
"pi-code": "candidate-manifests/host-adapters/vision-pi-code-adapter.json",
|
||||||
|
}
|
||||||
|
|
||||||
|
CURRENT_TOOLS = [
|
||||||
|
"vision.image_analyze",
|
||||||
|
"vision.image_generate",
|
||||||
|
"vision.palette_extract",
|
||||||
|
"vision.background_cutout",
|
||||||
|
]
|
||||||
|
|
||||||
|
PLANNED_TOOLS = [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
checked = list(HOSTS.values()) + ["docs/VISION-HOST-ADAPTER-CANDIDATES.md"]
|
||||||
|
manifests: dict[str, dict] = {}
|
||||||
|
for host, rel in HOSTS.items():
|
||||||
|
manifest = _read_json(ROOT / rel, errors)
|
||||||
|
if manifest:
|
||||||
|
manifests[host] = manifest
|
||||||
|
|
||||||
|
for host, manifest in manifests.items():
|
||||||
|
_expect(manifest.get("host_runtime") == host, f"host_runtime_mismatch:{host}", errors)
|
||||||
|
_expect(manifest.get("package_id") == "visual-perception-package-candidate", f"package_mismatch:{host}", errors)
|
||||||
|
_expect(manifest.get("adapter_role") == "thin_access_adapter", f"adapter_role_mismatch:{host}", errors)
|
||||||
|
_expect(manifest.get("wildcard_grant_allowed") is False, f"wildcard_grant_allowed:{host}", errors)
|
||||||
|
_expect(manifest.get("current_tool_candidates") == CURRENT_TOOLS, f"current_tools_mismatch:{host}", errors)
|
||||||
|
_expect(manifest.get("planned_tool_candidates") == PLANNED_TOOLS, f"planned_tools_mismatch:{host}", errors)
|
||||||
|
disclosures = manifest.get("disclosure_contract", {})
|
||||||
|
for key in ("provider_mode_required", "retention_required", "visual_evidence_required"):
|
||||||
|
if disclosures.get(key) is not True:
|
||||||
|
errors.append(f"disclosure_missing:{host}:{key}")
|
||||||
|
forbidden = set(manifest.get("forbidden_effects", []))
|
||||||
|
for effect in ("research_synthesis", "textual_web_search", "runtime_start", "wildcard_tool_exposure"):
|
||||||
|
if effect not in forbidden:
|
||||||
|
errors.append(f"forbidden_effect_missing:{host}:{effect}")
|
||||||
|
for key, value in manifest.get("non_authorization", {}).items():
|
||||||
|
if value is not False:
|
||||||
|
errors.append(f"non_authorization_enabled:{host}:{key}")
|
||||||
|
|
||||||
|
if len(manifests) == len(HOSTS):
|
||||||
|
current_sets = {tuple(m["current_tool_candidates"]) for m in manifests.values()}
|
||||||
|
planned_sets = {tuple(m["planned_tool_candidates"]) for m in manifests.values()}
|
||||||
|
_expect(len(current_sets) == 1, "current_tool_parity_failed", errors)
|
||||||
|
_expect(len(planned_sets) == 1, "planned_tool_parity_failed", errors)
|
||||||
|
|
||||||
|
_check_snippets(
|
||||||
|
"docs/VISION-HOST-ADAPTER-CANDIDATES.md",
|
||||||
|
["Claude Code", "Codex CLI", "Pi-Code", "no wildcard grant"],
|
||||||
|
errors,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "vision-host-adapter-candidates-v1",
|
||||||
|
"checked": checked,
|
||||||
|
"errors": errors,
|
||||||
|
"warnings": [],
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2, sort_keys=True))
|
||||||
|
return 0 if result["ok"] else 1
|
||||||
|
|
||||||
|
|
||||||
|
def _read_json(path: Path, errors: list[str]) -> dict | None:
|
||||||
|
if not path.exists():
|
||||||
|
errors.append(f"missing:{path.relative_to(ROOT)}")
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
errors.append(f"{path.relative_to(ROOT)}:json:{exc}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _check_snippets(rel: str, snippets: list[str], errors: list[str]) -> None:
|
||||||
|
path = ROOT / rel
|
||||||
|
if not path.exists():
|
||||||
|
errors.append(f"missing:{rel}")
|
||||||
|
return
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
for snippet in snippets:
|
||||||
|
if snippet not in text:
|
||||||
|
errors.append(f"{rel}:missing:{snippet}")
|
||||||
|
|
||||||
|
|
||||||
|
def _expect(condition: bool, error: str, errors: list[str]) -> None:
|
||||||
|
if not condition:
|
||||||
|
errors.append(error)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate the child-local VISION package candidate manifest and docs."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
CURRENT_TOOLS = [
|
||||||
|
"vision.image_analyze",
|
||||||
|
"vision.image_generate",
|
||||||
|
"vision.palette_extract",
|
||||||
|
"vision.background_cutout",
|
||||||
|
]
|
||||||
|
|
||||||
|
PLANNED_TOOLS = [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
ROUTE_TOOLS = {
|
||||||
|
"POST /vlm/analyze": "vision.image_analyze",
|
||||||
|
"POST /flux/render": "vision.image_generate",
|
||||||
|
"POST /palette/extract": "vision.palette_extract",
|
||||||
|
"POST /rembg/cutout": "vision.background_cutout",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
required = [
|
||||||
|
"CONTEXT.md",
|
||||||
|
"docs/VISION-PACKAGE-CANDIDATE.md",
|
||||||
|
"candidate-manifests/vision-package-candidate.json",
|
||||||
|
]
|
||||||
|
for rel in required:
|
||||||
|
if not (ROOT / rel).exists():
|
||||||
|
errors.append(f"missing:{rel}")
|
||||||
|
|
||||||
|
manifest_path = ROOT / "candidate-manifests/vision-package-candidate.json"
|
||||||
|
manifest = _read_json(manifest_path, errors)
|
||||||
|
if manifest:
|
||||||
|
_expect(manifest.get("canonical_sense") == "VISION", "canonical_sense_not_vision", errors)
|
||||||
|
_expect(
|
||||||
|
manifest.get("status") == "candidate_only_not_seed_installed",
|
||||||
|
"status_not_candidate_only",
|
||||||
|
errors,
|
||||||
|
)
|
||||||
|
_expect(manifest.get("current_tool_candidates") == CURRENT_TOOLS, "current_tools_mismatch", errors)
|
||||||
|
_expect(manifest.get("planned_tool_candidates") == PLANNED_TOOLS, "planned_tools_mismatch", errors)
|
||||||
|
route_map = {
|
||||||
|
item.get("route"): item.get("tool_id")
|
||||||
|
for item in manifest.get("current_route_adapters", [])
|
||||||
|
}
|
||||||
|
_expect(route_map == ROUTE_TOOLS, "route_tool_map_mismatch", errors)
|
||||||
|
grant_policy = manifest.get("grant_policy", {})
|
||||||
|
_expect(grant_policy.get("wildcard_grant_allowed") is False, "wildcard_grant_allowed", errors)
|
||||||
|
_expect(
|
||||||
|
grant_policy.get("package_default_grants_all_tools") is False,
|
||||||
|
"package_default_grants_all_tools",
|
||||||
|
errors,
|
||||||
|
)
|
||||||
|
_expect(grant_policy.get("tool_grants_are_granular") is True, "tool_grants_not_granular", errors)
|
||||||
|
for key, value in manifest.get("non_authorization", {}).items():
|
||||||
|
if value is not False:
|
||||||
|
errors.append(f"non_authorization_enabled:{key}")
|
||||||
|
forbidden = set(manifest.get("forbidden_research_owned_capabilities", []))
|
||||||
|
for capability in ("web_search", "fetch_page", "extract_pdf", "deep_research", "research_synthesis"):
|
||||||
|
if capability not in forbidden:
|
||||||
|
errors.append(f"missing_forbidden_research_capability:{capability}")
|
||||||
|
|
||||||
|
_check_snippets(
|
||||||
|
"docs/VISION-PACKAGE-CANDIDATE.md",
|
||||||
|
[
|
||||||
|
"Research reads sources; Vision sees media",
|
||||||
|
"No Core promotion",
|
||||||
|
"wildcard grant",
|
||||||
|
"`vision.image_analyze`",
|
||||||
|
"`vision.video_read`",
|
||||||
|
],
|
||||||
|
errors,
|
||||||
|
)
|
||||||
|
_check_snippets(
|
||||||
|
"CONTEXT.md",
|
||||||
|
["Visual Evidence", "Research Handoff", "BTE Compatibility Surface"],
|
||||||
|
errors,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "vision-package-candidate-v1",
|
||||||
|
"checked": required,
|
||||||
|
"errors": errors,
|
||||||
|
"warnings": [],
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2, sort_keys=True))
|
||||||
|
return 0 if result["ok"] else 1
|
||||||
|
|
||||||
|
|
||||||
|
def _read_json(path: Path, errors: list[str]) -> dict | None:
|
||||||
|
if not path.exists():
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
errors.append(f"{path.relative_to(ROOT)}:json:{exc}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _check_snippets(rel: str, snippets: list[str], errors: list[str]) -> None:
|
||||||
|
path = ROOT / rel
|
||||||
|
if not path.exists():
|
||||||
|
return
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
for snippet in snippets:
|
||||||
|
if snippet not in text:
|
||||||
|
errors.append(f"{rel}:missing:{snippet}")
|
||||||
|
|
||||||
|
|
||||||
|
def _expect(condition: bool, error: str, errors: list[str]) -> None:
|
||||||
|
if not condition:
|
||||||
|
errors.append(error)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate the no-live Vision package Docker build context."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
DOCKERFILE = ROOT / "Dockerfile"
|
||||||
|
DOCKERIGNORE = ROOT / ".dockerignore"
|
||||||
|
WORKBOARD = ROOT / "WORKBOARD.yaml"
|
||||||
|
|
||||||
|
REQUIRED_DOCKER_SNIPPETS = [
|
||||||
|
"FROM python:3.12-slim",
|
||||||
|
"SVRNTY_VISION_HOST=0.0.0.0",
|
||||||
|
"SVRNTY_VISION_PORT=8094",
|
||||||
|
"COPY pyproject.toml README.md ./",
|
||||||
|
"COPY src ./src",
|
||||||
|
"python -m pip install --no-cache-dir .",
|
||||||
|
"USER vision",
|
||||||
|
"EXPOSE 8094",
|
||||||
|
"HEALTHCHECK",
|
||||||
|
"http://127.0.0.1:8094/healthz",
|
||||||
|
'CMD ["python", "-m", "svrnty_vision.server"]',
|
||||||
|
]
|
||||||
|
REQUIRED_IGNORE = {
|
||||||
|
".git",
|
||||||
|
".venv",
|
||||||
|
"__pycache__",
|
||||||
|
"outputs",
|
||||||
|
"worktrees",
|
||||||
|
"tests",
|
||||||
|
"candidate-manifests",
|
||||||
|
}
|
||||||
|
FORBIDDEN_PATTERNS = [
|
||||||
|
re.compile(r"sk-[A-Za-z0-9_-]{20,}"),
|
||||||
|
re.compile(r"AIza[0-9A-Za-z_-]{20,}"),
|
||||||
|
re.compile(r"\b(?:ck|cs)_[0-9A-Za-z]{20,}"),
|
||||||
|
re.compile(r"(?i)\b[A-Z0-9_]*(?:PASS|PASSWORD|SECRET|TOKEN|KEY)[A-Z0-9_]*\s*=\s*[^`\s#]{8,}"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
dockerfile = DOCKERFILE.read_text(encoding="utf-8") if DOCKERFILE.is_file() else ""
|
||||||
|
dockerignore = DOCKERIGNORE.read_text(encoding="utf-8") if DOCKERIGNORE.is_file() else ""
|
||||||
|
workboard = WORKBOARD.read_text(encoding="utf-8") if WORKBOARD.is_file() else ""
|
||||||
|
if not dockerfile:
|
||||||
|
errors.append("missing:Dockerfile")
|
||||||
|
if not dockerignore:
|
||||||
|
errors.append("missing:.dockerignore")
|
||||||
|
for snippet in REQUIRED_DOCKER_SNIPPETS:
|
||||||
|
if snippet not in dockerfile:
|
||||||
|
errors.append(f"dockerfile_missing:{snippet}")
|
||||||
|
ignore_rows = {line.strip() for line in dockerignore.splitlines() if line.strip() and not line.startswith("#")}
|
||||||
|
for row in sorted(REQUIRED_IGNORE - ignore_rows):
|
||||||
|
errors.append(f"dockerignore_missing:{row}")
|
||||||
|
if "SVRNTY-VISION-WORK-004" not in workboard:
|
||||||
|
errors.append("workboard_missing:SVRNTY-VISION-WORK-004")
|
||||||
|
if "Package Docker Build Context" not in workboard:
|
||||||
|
errors.append("workboard_missing:Package Docker Build Context")
|
||||||
|
combined = "\n".join([dockerfile, dockerignore, workboard])
|
||||||
|
for pattern in FORBIDDEN_PATTERNS:
|
||||||
|
if pattern.search(combined):
|
||||||
|
errors.append(f"value_pattern_found:{pattern.pattern}")
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "vision-package-docker-context-no-live",
|
||||||
|
"checked": ["Dockerfile", ".dockerignore", "WORKBOARD.yaml"],
|
||||||
|
"errors": errors,
|
||||||
|
"warnings": [],
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2))
|
||||||
|
return 0 if result["ok"] else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate granular VISION tool grant candidate manifest."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
CURRENT_TOOLS = [
|
||||||
|
"vision.image_analyze",
|
||||||
|
"vision.image_generate",
|
||||||
|
"vision.palette_extract",
|
||||||
|
"vision.background_cutout",
|
||||||
|
]
|
||||||
|
|
||||||
|
PLANNED_TOOLS = [
|
||||||
|
"vision.ocr_read",
|
||||||
|
"vision.screenshot_observe",
|
||||||
|
"vision.browser_observe",
|
||||||
|
"vision.document_layout_read",
|
||||||
|
"vision.chart_read",
|
||||||
|
"vision.table_read",
|
||||||
|
"vision.diagram_read",
|
||||||
|
"vision.object_detect",
|
||||||
|
"vision.visual_ground",
|
||||||
|
"vision.segment",
|
||||||
|
"vision.video_read",
|
||||||
|
"vision.image_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
path = ROOT / "candidate-manifests/vision-tool-grants.json"
|
||||||
|
manifest = _read_json(path, errors)
|
||||||
|
if manifest:
|
||||||
|
_expect(manifest.get("canonical_sense") == "VISION", "canonical_sense_not_vision", errors)
|
||||||
|
_expect(manifest.get("wildcard_grant_allowed") is False, "wildcard_grant_allowed", errors)
|
||||||
|
_expect(
|
||||||
|
manifest.get("package_default_grants_all_tools") is False,
|
||||||
|
"package_default_grants_all_tools",
|
||||||
|
errors,
|
||||||
|
)
|
||||||
|
current = manifest.get("current_tool_candidates", [])
|
||||||
|
current_tool_ids = [item.get("tool_id") for item in current]
|
||||||
|
_expect(current_tool_ids == CURRENT_TOOLS, "current_tool_ids_mismatch", errors)
|
||||||
|
_expect(manifest.get("planned_tool_candidates") == PLANNED_TOOLS, "planned_tools_mismatch", errors)
|
||||||
|
for item in current:
|
||||||
|
if item.get("grant_default") is not False:
|
||||||
|
errors.append(f"grant_default_enabled:{item.get('tool_id')}")
|
||||||
|
disclosures = manifest.get("required_disclosures", {})
|
||||||
|
for field in (
|
||||||
|
"producing_package_id",
|
||||||
|
"producing_tool_id",
|
||||||
|
"capability_surface",
|
||||||
|
"provider_mode",
|
||||||
|
"retention_disclosure",
|
||||||
|
"validation_status",
|
||||||
|
):
|
||||||
|
if disclosures.get(field) is not True:
|
||||||
|
errors.append(f"required_disclosure_missing:{field}")
|
||||||
|
forbidden = set(manifest.get("forbidden_effects", []))
|
||||||
|
for effect in (
|
||||||
|
"research_synthesis",
|
||||||
|
"textual_web_search",
|
||||||
|
"textual_page_fetch",
|
||||||
|
"deep_research_workflow",
|
||||||
|
"wildcard_tool_exposure",
|
||||||
|
):
|
||||||
|
if effect not in forbidden:
|
||||||
|
errors.append(f"forbidden_effect_missing:{effect}")
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "vision-tool-grants-v1",
|
||||||
|
"checked": ["candidate-manifests/vision-tool-grants.json"],
|
||||||
|
"errors": errors,
|
||||||
|
"warnings": [],
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2, sort_keys=True))
|
||||||
|
return 0 if result["ok"] else 1
|
||||||
|
|
||||||
|
|
||||||
|
def _read_json(path: Path, errors: list[str]) -> dict | None:
|
||||||
|
if not path.exists():
|
||||||
|
errors.append(f"missing:{path.relative_to(ROOT)}")
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
errors.append(f"{path.relative_to(ROOT)}:json:{exc}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _expect(condition: bool, error: str, errors: list[str]) -> None:
|
||||||
|
if not condition:
|
||||||
|
errors.append(error)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Validate the Visual Evidence contract and pure adapter proof."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
sys.path.insert(0, str(ROOT / "src"))
|
||||||
|
|
||||||
|
REQUIRED_FIELDS = [
|
||||||
|
"producing_package_id",
|
||||||
|
"producing_tool_id",
|
||||||
|
"capability_surface",
|
||||||
|
"source_reference",
|
||||||
|
"provider_mode",
|
||||||
|
"retention_disclosure",
|
||||||
|
"observed_content_summary",
|
||||||
|
"extracted_claims",
|
||||||
|
"confidence",
|
||||||
|
"caveats",
|
||||||
|
"timestamp",
|
||||||
|
"validation_status",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors: list[str] = []
|
||||||
|
required = [
|
||||||
|
"docs/VISUAL-EVIDENCE-CONTRACT.md",
|
||||||
|
"candidate-manifests/visual-evidence-contract.json",
|
||||||
|
"src/svrnty_vision/visual_evidence.py",
|
||||||
|
"tests/test_visual_evidence.py",
|
||||||
|
]
|
||||||
|
for rel in required:
|
||||||
|
if not (ROOT / rel).exists():
|
||||||
|
errors.append(f"missing:{rel}")
|
||||||
|
|
||||||
|
manifest = _read_json(ROOT / "candidate-manifests/visual-evidence-contract.json", errors)
|
||||||
|
if manifest:
|
||||||
|
_expect(manifest.get("required_fields") == REQUIRED_FIELDS, "required_fields_mismatch", errors)
|
||||||
|
proof = manifest.get("first_vertical_proof", {})
|
||||||
|
_expect(proof.get("source_tool_id") == "vision.image_analyze", "proof_tool_mismatch", errors)
|
||||||
|
_expect(proof.get("live_provider_call_required") is False, "live_provider_required", errors)
|
||||||
|
handoff = manifest.get("research_handoff", {})
|
||||||
|
_expect(handoff.get("research_may_consume_visual_evidence") is True, "research_handoff_missing", errors)
|
||||||
|
_expect(handoff.get("vision_may_write_research_capsules") is False, "vision_writes_capsules", errors)
|
||||||
|
_expect(handoff.get("vision_may_perform_research_synthesis") is False, "vision_research_synthesis", errors)
|
||||||
|
|
||||||
|
_check_snippets(
|
||||||
|
"docs/VISUAL-EVIDENCE-CONTRACT.md",
|
||||||
|
[
|
||||||
|
"`producing_package_id`",
|
||||||
|
"Research owns synthesis and capsule writing",
|
||||||
|
"does not call a live provider",
|
||||||
|
],
|
||||||
|
errors,
|
||||||
|
)
|
||||||
|
_validate_adapter(errors)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ok": not errors,
|
||||||
|
"validator": "visual-evidence-contract-v1",
|
||||||
|
"checked": required,
|
||||||
|
"errors": errors,
|
||||||
|
"warnings": [],
|
||||||
|
}
|
||||||
|
print(json.dumps(result, indent=2, sort_keys=True))
|
||||||
|
return 0 if result["ok"] else 1
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_adapter(errors: list[str]) -> None:
|
||||||
|
try:
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from svrnty_vision.visual_evidence import visual_evidence_from_vlm_response
|
||||||
|
except Exception as exc: # pragma: no cover - validator import report
|
||||||
|
errors.append(f"adapter_import_failed:{type(exc).__name__}:{exc}")
|
||||||
|
return
|
||||||
|
|
||||||
|
response = SimpleNamespace(
|
||||||
|
rubric_mode="raw",
|
||||||
|
justification="",
|
||||||
|
model_id="qwen-test",
|
||||||
|
raw_scores_json='{"description":"solid red square","objects":["red square"],"detected_text":[]}',
|
||||||
|
)
|
||||||
|
evidence = visual_evidence_from_vlm_response(
|
||||||
|
response,
|
||||||
|
source_reference="fixture://red-square.png",
|
||||||
|
provider_mode="sovereign",
|
||||||
|
retention_disclosure="synchronous_no_async_persistence",
|
||||||
|
timestamp="2026-06-06T00:00:00Z",
|
||||||
|
)
|
||||||
|
dumped = evidence.model_dump()
|
||||||
|
for field in REQUIRED_FIELDS:
|
||||||
|
if field not in dumped:
|
||||||
|
errors.append(f"adapter_missing_field:{field}")
|
||||||
|
_expect(dumped.get("producing_package_id") == "visual-perception-package-candidate", "adapter_package_mismatch", errors)
|
||||||
|
_expect(dumped.get("producing_tool_id") == "vision.image_analyze", "adapter_tool_mismatch", errors)
|
||||||
|
_expect(dumped.get("observed_content_summary") == "solid red square", "adapter_summary_mismatch", errors)
|
||||||
|
_expect("description: solid red square" in dumped.get("extracted_claims", []), "adapter_claim_missing", errors)
|
||||||
|
|
||||||
|
|
||||||
|
def _read_json(path: Path, errors: list[str]) -> dict | None:
|
||||||
|
if not path.exists():
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
errors.append(f"{path.relative_to(ROOT)}:json:{exc}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _check_snippets(rel: str, snippets: list[str], errors: list[str]) -> None:
|
||||||
|
path = ROOT / rel
|
||||||
|
if not path.exists():
|
||||||
|
return
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
for snippet in snippets:
|
||||||
|
if snippet not in text:
|
||||||
|
errors.append(f"{rel}:missing:{snippet}")
|
||||||
|
|
||||||
|
|
||||||
|
def _expect(condition: bool, error: str, errors: list[str]) -> None:
|
||||||
|
if not condition:
|
||||||
|
errors.append(error)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user