Skip to content

T098: display harnesses (A), and the server's scope labels from the served facet (plan 038, T094's R2-INV-R9) - #51

Merged
brettheap merged 4 commits into
mainfrom
r2/t098-display-harnesses-a
Oct 7, 2026
Merged

brettheap merged 4 commits into
mainfrom
r2/t098-display-harnesses-a

Conversation

@brettheap

@brettheap brettheap commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Authored by lane openXfactory-3, delegated by lane openxfactory-4 (#656 6021862323)

Arc: neutral-product-standalone-operability

T098: display harnesses (A), and the server's scope labels from the served facet (plan 038)

This is a slice of T094's map R2-INV-R9 (opensoft/openxFactory#656 6021830607). tasks.md has no entry for it yet: lane 4 records the T095 to T104 entries after T002 (#1251). Until then, its contract is the map's slice-outline row plus the holder's rulings, 6021830531.

  • Realizes: 21 of the composed reds outside 12.5's set in the declared exclusion, toward requirement 9's declared composed tests (T073, F9.1):

    • canvas: DJ 8 and DJ + HR 1;
    • explorer: DJ 5 and CP 2;
    • the 5 nodes held by R9-R1: canvas 2, explorer 2, scope 1.
  • Falsifier (the outline row): the composed run of the three files, each alone, at main + T095, takes the named 21 to 0 red. These read unchanged:

    • 12.5's 16 governed suites;
    • F5.2's 5 suites;
    • test_column_contributions_governed.py (9 passed).

    tests/test_declared_exclusion.py reads green when run lone.

  • Ruled:

    • R9-R1 (a): doxbench_scope.py's labels and notes derive from the facet the browser reads, and every pin that asserts words is respelled through VR to the SERVED words.
    • R9-W1 (A″): the harnesses copy display.js beside the module they copy, as T026, U-7: the allow-list for 12.5's governed suites, with R-1 (a)'s span kind (plan 038, H-2) #43 does.
    • Both are in 6021830531. They conform to the ruled overlay (5784683830, 5801057769) and to the served-display rule for the staging suite (6016648451).
  • After: T095 (T095: the composed harness for the declared integration tests (plan 038, T094's R2-INV-R9) #46), LANDED as e2340bb6. The served display needs the governed host that T095's DECLARED_HOST_SUITES registers for these three files when the run is composed. This branch merges main e2340bb6, and every number below is measured over it.

What changes

src/openxdox/doxbench_scope.py is this slice's under R9-R1 (a), as claim 6021862323 names it.

  • The labels now come from the facet. The section labels and notes were one domain's words ("cluster documents", "topic folder documents"). They are now built from the facet by _section_meta(_served_display()) once per resolve_scope call.
    • The six sentences are word for word the ones openDox's staging model has built since § 3.4 slice S7 (views/staging-workbench-model.js SECTION_META).
    • Keys, flags and paths are unchanged.
  • Where the words come from. _served_display() is the display block that /capabilities serves: display_manifest(host_display()).
    • It is read at call time, never at import and never cached, as opendox.canvas_drafts reads its one shared sentence.
  • Decision: no host means neutral words. With no host registered there is no served page. The browser model given no facet speaks openDox's neutral words, so the server answers with those too rather than refusing.
    • The words label sections of an authorization answer and never decide it.
    • A library or test caller with no host therefore keeps its paths.
  • Who reads the labels. Server-side, no module reads a section's label or note except the parity test: no prompt and no wire field carries them.

tests/test_doxbench_scope.py

  • The browser harness copies display.js beside the two models and writes a package.json with "type": "module" (DJ). It installs the display through setDisplay(readDisplay(...)), as the shell does at mount.
  • The parity test hands the browser the served display (VR).
  • Two new cases, because the parity test alone cannot catch one thing. The composite serves openDox's neutral stage words for these three roles, since openXdox overlays only completion and the values. So parity cannot tell a server that reads the facet from one that always speaks neutral words. The new cases can:
    • A host that declares its own stage words. It declares openxFactory's pre-S7 words. The server labels read "cluster documents", "topic folder documents" and so on, and match the browser byte for byte.
    • No host. The server reads the neutral words, which equal the browser's with no facet.

tests/test_canvas.py

  • _run_node copies display.js and writes the package.json (DJ). It hands the harness the served display, so every canvas derivation runs under the words the page is served (VR).
  • The two gap pins now read the kind canvas-model.js emits under every host, unsupported-candidate, where they read unsupported-possible before (R9-R1).
  • test_js_and_python_draft_constants_agree also cross-checks the seed state of a new draft. Both halves read it off one facet: the composer plan's state against canvas_drafts.register_state("captured"). This assertion is what makes the served-display hand-off observable (mutant H4 below).

tests/test_explorer_viewer.py

  • DJ: each explorer harness copies display.js and writes the package.json.
  • VR: _EXPLORER_HARNESS is handed the served display.
  • R9-R1, the served words. The two label pins read the words the page is served, from the composite's artifact axis:
    • groups proposal.md and tasks.md;
    • classification proposal.md, design.md, tasks.md, Spec deltas, Supporting docs, other.
  • CP: the import-free pin, respelled to S7's design:
    • no import names the viewer;
    • the only module imported is ./display.js;
    • import statements spread over several lines are read whole.
  • CP: the wheel pin, respelled to opts.wheelKey === SOURCE, with SOURCE held to be STAGE_ROLES[0].

The falsifier (composed, each file alone; quoted)

The composed form, R1Q23 (a):

  • openxFactory 92010d3e (tests/composed_host_pin.yaml), with openDox, openXdox and openXwallet initialized recursively, and its scripts/ on PYTHONPATH;
  • openDox installed from openDox-code main 84f8ed83 (force-reinstalled);
  • the colour variables unset and TERM=dumb;
  • per file: python -m pytest -q -p no:cacheprovider -rfE --junitxml=<file>.xml tests/<file>.py < /dev/null.

T022's scripts/composed_placements.py (taken from #44's tree) refuses to place in these checkouts: its .gitignore entry is not on main until #41 lands. None of these files reads the runbook it places. Every checkout read clean after every run.

Measured over real main (e2340bb6, carrying T095 #46 and T026 #43): the base is main itself, and the head is this PR's c935f2a0 (this branch merged with main).

run test_canvas.py test_explorer_viewer.py test_doxbench_scope.py named reds
base: main e2340bb6 10 passed, 11 failed 15 passed, 9 failed 34 passed, 1 failed 21
head: c935f2a0 21 passed, 0 failed 24 passed, 0 failed 37 passed, 0 failed 0

Before T095 landed, the same 21 were measured at a local integration that was never pushed (main f70bc9c3 + #46 c2192e3 + this branch): 21 red at its base and 0 at its head. At main d45a0939, before T095 existed, these files read 19, 9 and 1 red.

The 21 nodes that flipped:

  • canvas (11): test_member_pane_is_exactly_the_topics_document_edges, test_downstream_artifacts_are_in_the_lineage_strip_never_members, test_evidence_board_carries_section_ref_and_passage_hash, test_missing_cluster_degrades_to_null, test_gap_unclaimed_member, test_gap_unsupported_possible, test_gap_both_kinds_on_one_cluster, test_option_set_grouping, test_js_and_python_draft_constants_agree, test_esc_escapes_markup, test_model_passes_prose_through_as_data_not_html;
  • explorer (9): test_explorer_js_exists_and_is_importable_standalone, test_staged_tile_lists_the_topic_folder_with_headers, test_aggregate_folder_entry_keeps_its_member_source_key, test_aggregate_folder_entry_disambiguates_same_repository_refs, test_aggregate_wheel_navigation_threads_the_owning_member_key, test_proposal_tile_groups_proposal_and_tasks, test_realized_tile_lists_the_archived_change_folder, test_unresolvable_tile_and_kind_degrade_to_null, test_change_file_classification;
  • scope (1): test_server_and_actual_browser_projection_are_byte_shape_equivalent.

Two nodes are new: test_the_server_labels_follow_the_facet_a_host_declares and test_with_no_host_registered_the_labels_are_openDoxs_neutral_words. No node regressed.

The unchanged set was compared node for node, base against head over main: 974 nodes, 10 red at both, 0 nodes changed outcome.

set base head
12.5's 16 governed suites 832 passed, 10 failed (pre-existing: session_runbook 9 and session_notebook 1, which read the runbook T022 places) identical, file for file
F5.2's 5 suites 123 passed identical, file for file
test_column_contributions_governed.py 9 passed 9 passed

Mutants

Each mutant was applied at the integration (main f70bc9c3 + T095 c2192e3 + this branch), its file run alone composed, and the file restored byte for byte. 11 of 12 killed:

mutant site killed by
S1 src: ignores the host's facet (always neutral) test_the_server_labels_follow_the_facet_a_host_declares
S2 src: no-host fallback dropped test_with_no_host_registered_the_labels_are_openDoxs_neutral_words
S3 src: members label hard-coded "cluster documents" parity (served) + no-host
S4 src: folder label one/many swapped parity + declaring host + no-host
S5 src: neighbourhood note drops a facet word declaring host
H1 scope harness: no display.js all three browser cases
H2 scope harness: browser ignores the display declaring host
H3 canvas: no display.js the 11 canvas Node cases
H4 canvas: neutral display instead of served test_js_and_python_draft_constants_agree
H5 explorer: no display.js 7 explorer Node cases
H6 explorer: neutral display instead of served test_proposal_tile_groups_proposal_and_tasks, test_change_file_classification
H7 scope harness: no package.json SURVIVES (37 passed)

H7 is an equivalent mutant on the measured runtime. Node v24 detects module syntax in a .js file with no "type" declared, so package.json changes nothing there. It is kept for runtimes without that detection, as #43's harness keeps it. T097 measured the same survivor.

The lone CI form (validate.yml's exact step, at c935f2a0)

python -m pytest -q --junitxml=pytest-report.xml --deselect "$LEFT_OUT", run locally, read:

SELECTED=1165 PASSED=1161 SKIPPED=4 FAILURES=0 ERRORS=0   (floors MIN_SELECTED=1099 MIN_PASSED=1095 EXPECT_SKIPPED=4)
1161 passed, 4 skipped, 1 deselected in 169.43s
  • tests/test_declared_exclusion.py run alone: rc 0. Each of the three files still fails lone on its declared reason (doc_health, at collection).
  • The floors are untouched; only T029 raises them.

CI and Copilot at c935f2a0

Files changed

  • src/openxdox/doxbench_scope.py
  • tests/test_canvas.py
  • tests/test_explorer_viewer.py
  • tests/test_doxbench_scope.py

No protected suite is edited: none of the four is in 12.5's 16 or F5.2's 7. No allow-list entry is needed, and tests/declared_exclusion.yaml is untouched.

Not done

🤖 Generated with Claude Code

Summary by Sourcery

Use the served display facet consistently across server and browser projections so labels, classifications, and derived values remain aligned.

New Features:

  • Make scope section labels and notes follow the served display facet, including host-specific vocabulary and neutral fallback words when no host is registered.
  • Pass the served display facet into canvas, explorer, and scope browser-model harnesses so projections use the same vocabulary as the server.

Bug Fixes:

  • Align server and browser projections with the served facet, including updated gap kinds, artifact labels, and file classifications.

Enhancements:

  • Update standalone JavaScript harnesses to include the shared display module and module configuration.
  • Strengthen parity and facet-specific tests for host-declared and hostless display vocabulary.

Tests:

  • Add coverage for served-display parity, host-specific scope labels, neutral no-host labels, and shared canvas draft state.

brettheap and others added 2 commits October 6, 2026 19:12
…erved facet (R9-R1 (a))

Plan 038 T098, a slice of T094's map R2-INV-R9 (opensoft/openxFactory#656
6021830607), on the holder's rulings 6021830531 (R9-R1 (a); W1 (A″)).

- src/openxdox/doxbench_scope.py: every section label and note is built
  from the display facet the browser reads (the /capabilities display under
  the registered host), word for word as openDox's staging model builds them
  since section 3.4 slice S7. With no host registered, openDox's neutral words.
- tests/test_doxbench_scope.py: the browser harness copies display.js beside
  the models and installs the served display; two new parity cases (a host
  declaring its own stage words; no host).
- tests/test_canvas.py, tests/test_explorer_viewer.py: the harnesses copy
  display.js (W1 (A″)) and are handed the served display (VR); the gap kind
  and the explorer's group labels respelled to the served words; the
  explorer's import pin and wheel pin respelled to S7's design (CP).

Lane: openXfactory-3

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Lane: openXfactory-3

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@brettheap
brettheap requested a balanced review from Copilot October 6, 2026 22:15
@sourcery-ai

sourcery-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown

Reviewer's Guide

This draft aligns server scope metadata and browser projections around the served display facet, lazily resolving host vocabulary with neutral fallback, and updates the Node harnesses and assertions to validate display propagation, role-based labels, and parity across hosted and hostless cases.

Sequence diagram for served display vocabulary during scope resolution

sequenceDiagram
    participant Caller
    participant Scope as doxbench_scope
    participant Registry as domain_profile
    participant Display as display_profile

    Caller->>Scope: resolve_scope(...)
    Scope->>Registry: is_registered()
    alt host registered
        Scope->>Display: host_display()
        Display-->>Scope: host display facet
    else no host
        Scope->>Display: display_manifest(None)
        Display-->>Scope: neutral display facet
    end
    Scope->>Display: display_manifest(host display)
    Display-->>Scope: served display
    Scope->>Scope: _section_meta(served display)
    Scope-->>Caller: scope sections with facet-derived labels
Loading

File-Level Changes

Change Details Files
Derive server-side scope section metadata from the served display facet instead of fixed domain-specific wording.
  • Build labels and notes from source, grouping, and selection stage words while preserving section keys and flags.
  • Resolve the display at scope-resolution time through the registered host, with neutral-word fallback when no host exists.
  • Thread the generated metadata through all scope section builders.
src/openxdox/doxbench_scope.py
Update browser-based harnesses to execute display-aware JavaScript with the same served facet as the page.
  • Copy display.js beside each tested model and add module-package setup.
  • Pass the served display into canvas, explorer, and scope projection derivations.
  • Update assertions for facet-derived labels, role-based gap kinds, wheel keys, and draft-state parity.
tests/test_canvas.py
tests/test_explorer_viewer.py
tests/test_doxbench_scope.py
Expand scope parity coverage to validate host-specific vocabulary and no-host behavior.
  • Add a custom host facet case that checks server/browser byte parity and legacy host wording.
  • Add a no-host case that verifies neutral wording without rejecting scope resolution.
  • Retain import-isolation coverage while allowing the display.js dependency.
tests/test_doxbench_scope.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Required prerequisite #46 remains unmerged, and composed validation must be repeated after integration.

Review effort: Balanced
Findings: None

What changed in this PR

Aligns openXdox’s scope metadata and browser test harnesses with the served display vocabulary.

Changes:

  • Derives scope labels from host display settings, with neutral fallback.
  • Supplies display dependencies and vocabulary to browser harnesses.
  • Updates terminology assertions and adds host-specific and no-host parity coverage.
File Description
tests/​test_explorer_viewer.py Updates display-aware harnesses and dependency assertions.
tests/​test_doxbench_scope.py Adds host-specific and neutral vocabulary parity tests.
tests/​test_canvas.py Supplies served display and checks draft-state parity.
src/​openxdox/​doxbench_scope.py Derives section metadata from the display facet.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Lane: openXfactory-3

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Prerequisite #46 has landed, but final composed validation after integration remains unverified.

Review effort: Balanced
Findings: None

@brettheap brettheap changed the title DRAFT: T098: display harnesses (A), and the server's scope labels from the served facet (plan 038, T094's R2-INV-R9) T098: display harnesses (A), and the server's scope labels from the served facet (plan 038, T094's R2-INV-R9) Oct 6, 2026
@brettheap
brettheap marked this pull request as ready for review October 6, 2026 23:49
@sourcery-ai

sourcery-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown

Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 21 hours and 53 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@brettheap
brettheap requested a balanced review from Copilot October 6, 2026 23:55
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No blocking issues remain; the targeted checks support the existing coverage, and authorization paths are unchanged.

Review effort: Balanced
Findings: None

@brettheap

Copy link
Copy Markdown
Contributor Author

READY at 55dc1ee

Lane: openxfactory-4 (openXfactory-4-openDox_extraction)

Holder, automatic READY on Brett's word "land lane 3's PRs when green" (2026-10-06). At the head: CLEAN, rollup SUCCESS, nothing pending, 0 unresolved threads, and Copilot at 55dc1ee7 reads "🟢 Approval recommended". The per-repo lander checks closing keywords and lands it.

@brettheap
brettheap merged commit fc1115d into main Oct 7, 2026
4 checks passed
@brettheap

Copy link
Copy Markdown
Contributor Author

Lane: openxfactory-4 (openXfactory-4-openDox_extraction)

LANDED — lane openxfactory-4, 2026-10-07T00:04:10Z, PR #51 → fc1115d (opensoft/openXdox-code main; plain gate)

Brett: plan 038 RULED incl. lane openxfactory-4 lands every PR (#656 6013547504); Start release 2 (#656 6001702967)

brettheap added a commit that referenced this pull request Oct 7, 2026
Lane: openXfactory-3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap added a commit that referenced this pull request Oct 7, 2026
…n 038, T094's map R2-INV-R9) (#54)

Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Authored by lane openXfactory-3, delegated by lane openxfactory-4 (#656 6021862323)

Arc: neutral-product-standalone-operability

## T100: the repo selector's declared tests, respelled to the carve (plan 038, T094's map R2-INV-R9)

**Contract.** There is no `tasks.md` entry yet. Lane 4 records T095 to T104 after T002. The contract is T094's slice-outline row for T100 and the holder's rulings on the map, opensoft/openxFactory#656 comment 6021830531.
- **Realizes:** the requirement 9 declared composed tests (T073, F9.1), for `tests/test_repo_selector.py`. It owns 24 composed reds, and its 7 host-registration nodes arrive with T095.
- **Falsifier:** the composed run of the file, alone, goes from red to green. The unchanged set stays node-for-node unchanged, and `tests/test_declared_exclusion.py` stays green lone.
- **After:** T095 (#46), LANDED as `e2340bb6`. main is merged in.

**Ruled (#656 6021830531), as applied here:**
- **R9-W1 (A″):** the three Node harnesses copy `display.js` beside the model, with `package.json`, as T026's harnesses do. 17 nodes.
- **R9-R1 (a):** the sparse-station node is handed the display `/capabilities` serves under the registered host, and asserts the served words. 1 node.
- **MN:** `SNAPSHOT_INDEX_ROUTE` is read from `openxdox.serve_projection`. 2 nodes.
- **R9-W4:** the plain-script and module subprocess tests register the host from THIS checkout before `opendox.serve` runs. 2 nodes. The child, in order:
  1. puts this checkout's `src/` first and imports openXdox's governed columns from it;
  2. checks that `openxdox` resolves to this checkout;
  3. registers openXdox's governed projection (`projection_contributions.register()`, the call openxFactory's host makes, plan 034 T064);
  4. builds openxFactory's composite with `sys.path` saved and put back;
  5. runs T020's `_refuse_an_openxdox_from_elsewhere`, the very function (its source, run in the child);
  6. registers the composite.
- **R9-R2 (a):** re-scoped to openDox with no host (`python -m opendox.serve`, a PyYAML blocker as its only path entry). The refresh is refused as `unknown_action`, and no `yaml` is loaded. 1 node.
- **R9-W3:** `test_serve_module_uses_no_relative_imports` is RETIRED. 1 node.

**Two notes for the holder (measured; no ruling taken):**
1. **R9-R2: openDox's serve tries `import yaml` at START, not on a POST.**
   - Measured: `build_server()`, then `_probe_nlm`, then `real_notebook_adapter`, then `opendox.workbench:52`, which imports PyYAML.
   - The blocker refuses it, and the probe reads that as no notebook support.
   - None of the three POSTs tries it. So the blocker counts every import attempt, and the test asserts that the count after the POSTs equals the count once the serve is up.
   - Mutant M11 (below) shows the count catches a POST that reaches for `yaml`.
2. **R9-W3's scope: the regex retires together with its self-test.**
   - The pin was the scan, the pattern it scanned with (`RELATIVE_IMPORT_RE`), and that pattern's 7-case self-test (`test_the_relative_import_guard_catches_every_dot_and_segment_depth`). The file's own comment named the three as one pin.
   - All three are retired: 1 red node and 7 green.
   - Say if you want the self-test kept.

**R9-R2's lone consequence: none.**
- Run alone lone, the re-scoped node does not run. The file still fails at COLLECTION on `doc_health` (`openxdox.generator`): `ModuleNotFoundError: No module named 'doc_health'`, `1 error in 0.39s`.
- So `tests/declared_exclusion.yaml` is unchanged, and the entry keeps `[doc_health]`.

## Falsifier, quoted

**The composed form (R1Q23 (a)):**
- openxFactory `92010d3e` (`tests/composed_host_pin.yaml`), with `openDox`, `openXdox` and `openXwallet` recursive, and its `scripts/` on `PYTHONPATH`;
- openDox-code `84f8ed83`, installed;
- T022's runbook placement made before the run and removed after;
- the colour variables unset, with `TERM=dumb`;
- each file run ALONE: `python -m pytest -q -p no:cacheprovider -rfE --junitxml=… <file>`.

Measured over REAL main, after T095 (#46) landed:
- **base:** main `e2340bb6`;
- **head:** this PR's head `ba0c3446`, which is main `e2340bb6` plus this PR's one file.

| | `tests/test_repo_selector.py` |
|---|---|
| base, main `e2340bb6` | `18 passed, 24 failed` |
| head `ba0c3446` | `34 passed, 0 failed` |

The 24 at the base are DJ 17, DJ+VR 1, MN 2, W4 2, W3 1 and R9-R2 1. T095's 7 host-registration nodes are already green there. 42 nodes become 34: W3 retires 1 red and 7 green.

**Unchanged set, composed, each file alone, at base and head: node-for-node identical, 974 nodes, 0 red at both.**
- 12.5's 16 governed suites: the same 16 at both.
- F5.2's 5: `test_generator` 45, `test_session_snapshot` 23, `test_snapshot_determinism` 6, `test_snapshot_registry` 40, `test_snapshot_validation_launch` 9, all passed.
- `test_column_contributions_governed.py`: `9 passed`.
- Over all 23 files: base `992 passed, 24 failed`; head `1008 passed, 0 failed`.

**Lone (CI venv, openDox `dede32b4` by the pin), at `ba0c3446`:**
- `tests/test_declared_exclusion.py`: `207 passed`.
- The R9-R2 node alone: `1 error`, `ModuleNotFoundError: No module named 'doc_health'` at collection. Its entry stays as it is.
- The CI form (`python -m pytest -q --deselect "$LEFT_OUT"`): `1161 passed, 4 skipped, 1 deselected`. That is selected 1165, against the floors 1099 / 1095 / 4. The floors are untouched.

## Mutants (one exact edit each, the file run composed alone)

Measured at the earlier integration of main `f70bc9c3` + #46 `c2192e3e`. This PR's file is byte-identical at `ba0c3446`.

| id | mutation | result |
|---|---|---|
| M1 | `display.js` not copied | KILLED, 18 red |
| M2 | no `package.json` | survived: equivalent on Node 24, whose syntax detection reads `display.js` as a module; kept for parity with T026's harnesses |
| M3 | the harness ignores the display it is handed | KILLED |
| M4 | `sparseNotice` not given the display | survived: equivalent at this pin, since the served words for the four empty stations are openDox's neutral ones (the ruled overlay changes only `completion` and the values). M3 guards the hand-off |
| M5 | this checkout's `src/` not put first | KILLED, both W4 nodes. Locally, the editable install is another clone; in CI it is the checkout itself, so there this edit is equivalent |
| M6 | openXdox's columns not imported from this checkout first | KILLED, both W4 nodes, by T020's guard |
| M7 | M6, with the guard call removed too | survived: the control, showing that the guard is what kills M6 |
| M8 | the governed projection not registered | KILLED, both W4 nodes |
| M9 | `sys.path` not put back | survived: no `openxdox` import after the composite is read reaches the pinned leg in these two tests. The in-process harness has the same posture |
| M10 | the composite not registered | KILLED, both W4 nodes |
| M11 | R9-R2 on loopback, with the notebook asserts dropped, so a POST reaches `yaml` | KILLED, by the attempt count |

## Files changed
- `tests/test_repo_selector.py` (only).

## Gates at `ba0c3446`
- **CI:**
  - `validate` passed (run 37548690247): `1161 passed, 4 skipped, 1 deselected`, and `triple: selected=1165 passed=1161 skipped=4 failures=0 errors=0` against the floors 1099 / 1095 / 4.
  - SonarCloud Code Analysis passed.
- **Copilot:** review 5435813621 at `ba0c3446` reads "Findings: None". Its "Needs a closer look" note concerns the then-unlanded #46, which has since LANDED as `e2340bb6` and is merged into this head. The earlier review, 5435251251 at `0c0f8bc8`, also read "Findings: None".
- **Review threads:** 0, so 0 unresolved.

## What remains
- Nothing for the writer. The PR is final and frozen.
- It is behind main `fc1115d6`. Lane 4's autoland loop runs update-branch and re-requests Copilot.
- `main` since `e2340bb6` (#48 T101, #51 T098) does not touch `tests/test_repo_selector.py`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


Arc: neutral-product-standalone-operability
Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
brettheap added a commit that referenced this pull request Oct 7, 2026
Lane: openXfactory-3

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
brettheap added a commit that referenced this pull request Oct 8, 2026
Brings T101 (#48), T098 (#51), T103 (#49), T096 (#53), T100 (#54), T099
(#47), T021's follow-on (#55), T102 (#52), T022 (#41, landed as aefd109),
T097 (#50) and T096's follow-on (#56).

Conflicted: scripts/composed_placements.py and tests/test_composed_placements.py,
both T022's files, which this branch carried from #41 through #44. Main's
landed side is kept for both. tests/declared_exclusion.yaml merged clean
(T101's entry edits beside T073's header and open_until).

Lane: openXfactory-3

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants