Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/source/development/mcp_knowledge_base_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -806,8 +806,8 @@
"document_id": "openhcs_viewer_qa",
"section_count": 0,
"source_path": "packaging/codex/openhcs/skills/use-openhcs/references/viewer-qa.md",
"summary": "Distributed raw-only faint-structure and nuisance scans with progressively lower numeric upper display limits; diagnostic soma saturation versus publication intent. Matched raw-only/result-only/combined QA across channels, positions and scales; verify live state and recapture after canvas changes.",
"tags": ["viewer QA", "raw only result only combined", "overlay visibility", "canvas resize recapture", "multiscale channels contrast", "per image contrast check", "channel switch contrast window", "remote desktop compression native capture", "segmentation visual debugging", "faint neurite lower upper display limit", "diagnostic soma saturation", "noise background illumination scan"],
"summary": "Distributed raw-only faint-structure and nuisance scans with progressively lower numeric upper display limits; diagnostic soma saturation versus publication intent. Matched raw-only/result-only/combined QA across channels, positions and scales. Settled explicit producer-incarnation retirement preserves current routes and saved evidence; measure actual memory rather than layer visibility.",
"tags": ["viewer QA", "raw only result only combined", "overlay visibility", "canvas resize recapture", "multiscale channels contrast", "per image contrast check", "channel switch contrast window", "remote desktop compression native capture", "segmentation visual debugging", "faint neurite lower upper display limit", "diagnostic soma saturation", "noise background illumination scan", "viewer layer retirement", "producer incarnation expected_producers", "settled candidate memory RSS"],
"title": "Review matched microscopy views"
},
{
Expand Down
7 changes: 7 additions & 0 deletions docs/source/guides/viewer_management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ stopped through its typed viewer-control endpoint or by the live manager that
retains its exact process handle. Non-persistent viewers belong to the execution
session's exact process group and are stopped when that session is cleaned up.

For resource-bound candidate review, retrieve the ``openhcs_viewer_qa`` knowledge
document, also bundled in the ``use-openhcs`` skill. Its conditional selective-
retirement procedure follows the installed typed capability and distinguishes
scene/payload custody from visibility, durable evidence and measured memory.
That is the operating procedure; this lifecycle overview does not maintain a
second retirement recipe or assume that every installed viewer supports it.

Display-axis ownership
----------------------

Expand Down
138 changes: 138 additions & 0 deletions docs/validation/explicit-producer-retirement-guide-20261003.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
Explicit producer retirement: canonical guide checkpoint
========================================================

Parent assigns this disjoint source-only guide change; Copernicus released
viewer-qa/canonical viewer.rst on2026-10-03 and owns separate measurement prose.
Existing checkout reused on docs/explicit-producer-retirement-guide-20261003
from current mainf7de; published522b2fa/source6c49 checkpoints remain unchanged.
Foreign gitlinks and untracked519/503 evidence are preserved. No runtime/client/
native/provider/SCI contact, package/build/install, target04 or live skill edit.

Actual owner and gap
-------------------

Knowledge manifest declares openhcs_viewer_qa.source_path directly as
packaging/codex/openhcs/skills/use-openhcs/references/viewer-qa.md. There is no
RST backer for that specific guide. docs/source/guides/viewer_management.rst
is a separate lifecycle overview; it now links the original guide, not a copied
procedure. Manifest discovery metadata changes only the viewer-QA entry.
SKILL.md already routes viewer review to this reference and stays unchanged.

The previous520 text exposed generic conditional retirement but omitted522's
actual expected_producers mapping and full invocation identity. Parent/Copernicus
read target04's actual capability/request and confirmed the gap. The new guide
reflects installed capability before use, requires known terminal/settled custody,
preserves current matched/raw/reference routes and durable evidence, submits one
explicit complete producer mapping, checks typed reply/actual surviving state
and records real memory telemetry. A known terminal failed candidate is eligible;
UNKNOWN/in-flight is not. No scalar cap/limit change, default disposal rule,
dataset identity/answer, new registry, codec or runtime implementation.

This is a conditional how-to under Diataxis; skill-creator keeps the recipe in
one existing reference with existing routing. NRA identity/boundary guidance
distinguishes a route/title from producer incarnation and layer/style from row
selection; declaration-owned runtime behavior is not implemented in this docs PR.
Packaging/knowledge delivery controls below pass; no autonomous scientific gain
is claimed.

Separate522 row-selection query
------------------------------

The current52233 controls prove native model/payload release, survivor image
style/domain/calibration and active-layer preservation, NOT untargeted feature
row selection. Source query shows both Points and Shapes handlers mount new
native layers when shared-domain rematerialization is required. Original
NapariLayerSelectionAuthority.capture/restore carries only active_layer;
NapariLayerDisplayHandler.preserve_native_presentation carries visibility/
opacity/blending. Neither captures/restores selected_data. Native Points starts
with empty Selection; Shapes starts with an empty selected-data set. Therefore
general selected-row preservation is absent across that remount boundary.

Original NapariResultElementSelectionAuthority owns state/select_indices;
NapariResultSelectionController owns linked-subject groups, observer caches and
its synchronization guard. Any production correction belongs to those owners
and the original cooperative presentation/mount hooks, not Point metadata,
Root publication, a new selection mirror or this guide. No production fix or
red/green native acceptance is claimed by this source query. The updated guide
requires explicit row readback rather than implying that active layer/style
preserves it. Target04 remains immutable and original failures remain retained.

Canonical delivery qualification
--------------------------------

At source16c203e206f63717a80bf36be6451006bad0e574, the original
project_knowledge_assets owner projects the actual declared package assets.
Original KnowledgeBaseService retrieves both openhcs_viewer_qa and
openhcs_viewer_management without truncation: complete source/projected bytes
and complete rendered reply content match. Actual knowledge search discovers
the canonical viewer guide for ``viewer layer retirement``. AgentSkillBundle
declares that same guide; original sync_skills copies identical bytes into an
isolated pytest destination and its next invocation reports unchanged. The live
managed skill, scientific installation and target04 are not synchronized.

One new delivery control plus two unchanged projection/sync controls: 3PASS,
terminal0, elapsed6.16s, maxRSS257164KiB, original cgroup memory peak170.4M,
Swap0. Original skill-creator quick_validate reports ``Skill is valid!``:
terminal0, elapsed0.05s, maxRSS14920KiB, memory peak6.7M, Swap0. These establish
source/package/retrieval/sync delivery and skill schema validity, not native
retirement, agent decision quality, measured memory release or installed MCP
construction. All original warnings and raw logs are preserved byte-exact.

Both checks used the existing paired interpreter
/home/ts/wt/basicpy-live-candidate-20260930/.venv/bin/python through the original
systemd-run owner: CPUQuota100%, AllowedCPUs3, MemoryMax536870912,
MemorySwapMax0, RuntimeMaxSec60. The pytest invocation used -B, --noconftest,
--import-mode=importlib, -p no:cacheprovider, -o addopts=, plugin autoload disabled
and existing single-thread/JIT-disabled source controls. Selected cases:

* tests/unit/agent/test_viewer_retirement_guide_projection.py
* tests/unit/test_build_mcp_knowledge_assets.py::test_projection_includes_complete_declared_plugin_skill
* tests/unit/agent/test_skill_sync.py::test_dry_run_has_no_filesystem_side_effect

Resource check returned critical disk/swap advisory (home4.3GiB, root7.5GiB,
swap14.6GiB, availableRAM19.4GiB). This tiny bounded text/projection check reused
dependencies; it is not admission evidence for another native/scientific lane.
No repeated qualification, full suite, build, install, launch or cleanup.

Qualified source SHA256 values:

* viewer-qa.md: cd45b329ea1c5826db298707c8a2224025c5417b91dd935c43f3f4788a03a75f
* viewer_management.rst: 9677f711607aaf8b3667ed02f29bf23103b33cc2518c5fb7d14b7feae3b85a14
* mcp_knowledge_base_manifest.json: a9d1cffaf18c326e731e7af9180ef375aca5ecc7cc19ac7ea868de3db5b8582e

Byte-exact archive explicit-producer-retirement-guide-20261003.tar.gz has eight
members (four original raw logs, the new delivery test and three qualified
canonical assets),21615bytes, SHA256
b33b84c63f1597cf8c5e34a43cc2d5dbdd2227e24096b9b100110e208482903c.
Original tar --compare passed for every member. Raw warning whitespace remains
inside the archive rather than rewritten as clean evidence.

Separate actual MCP construction failure
---------------------------------------

Parent's later frozen target04 run failed build_server with RecursionError;
only bootstrap diagnostics were exposed, no native/viewer was launched. Original
failure/freeze remains at next-metaxpress-p001-independent95-revision02-20261003/
METAXPRESS_P001_INDEPENDENT95/author-workspace/output/runtime/mcp.stdout under
the parent issue-batch root. Neither the source lifecycle suite nor this guide
delivery suite proves actual server construction.

Planck is the one combined integration owner. Singer read the original
engineering494/server-construction17.log and source boundary: request factory
expected_producers annotation passed unchanged through get_type_hints and
GeneratedMcpViewerRequestToolBinding to FastMCP create_model, which expanded
the implicit recursive JsonValue union. Planck's published91d449a71 corrects
the request declaration to original StreamProducerIdentity, whose nine fields
already own the complete identity; original from_payload already accepts that
type or original StreamProducerPayloadMapping. Generic server registration,
codec, invocation/whole-set guards and timeout remain unchanged. No JSON schema
alias fork, local Any escape, recursion-limit increase or competing patch here.
BOUND-2/8 apply: carry the existing owned identity across its schema boundary.

Original full named-family census engineering494/SCHEMA-FAMILY17-BEFORE.json
reports704 production modules,12 dependency modules,1090 sites, zero parse
omissions; dynamic relationships are read semantically, not equivalent-behavior
proof. This is received owner evidence, not a newly run or broader dependency
audit. Singer recorded the exact determining trace/ownership on PR522 comment
5967387805. New-target actual MCP construction/health and later selective native
retirement remain that owner's receiving qualification; frozen04 stays intact.
Binary file not shown.
46 changes: 39 additions & 7 deletions packaging/codex/openhcs/skills/use-openhcs/references/viewer-qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,45 @@ only chosen routes with `openhcs_isolate_viewer_window_layers` changes visibilit
not buffer lifetime. A new execution's stream reset is not selective retirement
of earlier mounted results. Do not budget hidden layers as released memory.

Discover a supported selective layer-retirement capability before attempting
it. If exposed, retire only explicitly identified superseded candidate routes
at a settled boundary, then read back surviving payload/source identities,
axes and camera and verify the current matched comparison still works. Keep
the needed raw source mounted, including its domain for point-only review.
Do not use blanket scene clearing, history deletion or viewer restarts as an
iteration policy.
Discover the installed selective-retirement capability and reflect its request
before using it. When the compatible `openhcs_retire_viewer_window_layers`
contract is exposed:

1. Preserve durable candidate files, source/declarations, captures and decisions.
Resolve execution/stream mutations to a known terminal disposition and let
receiver work settle before retirement. UNKNOWN, pending or in-flight work
is not permission to discard a route. A known failed terminal candidate can
be explicitly retired once no mutation is outstanding and its evidence is
retained; failure does not require keeping its buffers forever.
2. Read fresh, unfiltered viewer state on the same viewer incarnation. Choose
only explicitly superseded routes; retain the current matched candidate,
raw/source domain and reference routes still needed for the next comparison.
Build `expected_producers` by mapping each chosen **exact `route_key`** to
its **complete `producer_identities` array** from that readback, including
`invocation_key`. Do not shorten, fabricate or substitute identities from a
previous candidate, title or port. The receiving owner checks the whole set
before removal; a changed producer requires a fresh disposition/readback,
not a weaker identity check.
3. Submit that explicit mapping once. Retain the typed acknowledgement and
check `observed`, `applied`, errors, exact `retired_route_keys` and untargeted
`remaining_route_keys`. After a timeout or error, preserve the original
reply/disposition and inspect actual state read-only; do not assume rollback
or replay the mutation. This operation releases the selected scene/cache
entries, not persisted files or scientific history.
4. Read back survivor payload/source identities, domain, native calibration,
axes, camera and presentation, then verify the current matched comparison.
Check selected feature-row indices too: preserving the active layer/style
does not establish preserved Points/Shapes `selected_data`. Record a lost
or changed row as a receiving discrepancy, not another object's evidence.

Compare permitted **actual memory telemetry** for the same native process or
scope before and after settled retirement. A removed/hidden layer count is not
an RSS/PSS measurement. Native cache/scene release and lower process RSS are
different observations: allocators may retain released memory, and a small
retirement need not show a measurable RSS drop. Record the measured change or
missing attribution and keep resource accounting conservative; do not assume
reclaimed headroom from the UI. Do not use blanket scene clearing, history
deletion or viewer restarts as an iteration policy.

If no compatible retirement operation is exposed, record that contract gap
and request its original runtime owner; do not invent a remove-layer command,
Expand Down
51 changes: 51 additions & 0 deletions tests/unit/agent/test_viewer_retirement_guide_projection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Actual canonical guide -> package knowledge -> retrieval/managed skill bytes.

This is documentation discovery/delivery proof, not an agent decision or native
retirement test. Only the original projection/retrieval/sync owners do work.
"""
from pathlib import Path

from openhcs.agent.dto.knowledge import KnowledgeBaseDocumentRequest, KnowledgeBaseSearchRequest
from openhcs.agent.services.knowledge_base_service import (
KnowledgeBaseService, load_document_specs_from_manifest,
)
from openhcs.agent.skill_bundle import AGENT_PLUGIN_MANIFEST_PATH, AgentSkillBundle
from openhcs.agent.skill_sync import sync_skills
from scripts.build_mcp_knowledge_assets import (
KNOWLEDGE_MANIFEST_RELATIVE_PATH, project_knowledge_assets,
)


def test_real_viewer_guide_projection_retrieval_and_skill_delivery(tmp_path):
root = Path(__file__).resolve().parents[3]
destination = tmp_path / "package-knowledge"
projected = project_knowledge_assets(root, destination)
service = KnowledgeBaseService(
repo_root=destination,
document_specs=load_document_specs_from_manifest(
destination / KNOWLEDGE_MANIFEST_RELATIVE_PATH,
),
)
paths = []
for document_id in ("openhcs_viewer_qa", "openhcs_viewer_management"):
reply = service.get_document(KnowledgeBaseDocumentRequest.from_fields(
document_id=document_id, max_chars=50000,
))
assert not reply.errors and not reply.truncated
path = Path(reply.document.source_path)
assert destination / path in projected
assert (destination / path).read_bytes() == (root / path).read_bytes()
# The original renderer joins source lines; compare all content, not a
# wording substring that would pretend to prove the guide's decisions.
assert reply.content == "\n".join((root / path).read_text().splitlines())
paths.append(path)
found = service.search(KnowledgeBaseSearchRequest(query="viewer layer retirement", limit=5))
assert any(hit.document.document_id == "openhcs_viewer_qa" for hit in found.hits)
bundle = AgentSkillBundle.from_manifest(destination / AGENT_PLUGIN_MANIFEST_PATH)
guide = destination / paths[0]
assert guide in bundle.source_paths()
managed = tmp_path / "isolated-managed-skills"
(receipt,) = sync_skills(managed, bundle=bundle)
assert receipt.status == "installed"
assert (Path(receipt.path) / "references/viewer-qa.md").read_bytes() == guide.read_bytes()
assert sync_skills(managed, bundle=bundle)[0].status == "unchanged"
Loading