Skip to content

openDox root: bump code to 0b4e8bbf (§ 3.4 slice S8 leg B — the receive) - #9

Merged
brettheap merged 1 commit into
mainfrom
chore/pin-code-to-s8-landings
Sep 16, 2026
Merged

brettheap merged 1 commit into
mainfrom
chore/pin-code-to-s8-landings

Conversation

@brettheap

@brettheap brettheap commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Lane: openxfactory-4 (openXfactory-4-openDox_extraction)
Refs opensoft/openxFactory#656 (stays OPEN).
CLAIM: openxFactory#656 comment 5699629088

First leg of pin lockstep #3, on lockstep #2's own precedent (#8 → 3819625e, LANDED note 5689609863): code (opensoft/openDox-code) advances 1e469713 → 0b4e8bbf, carrying § 3.4 slice S8 leg B — openDox-code#23, the RECEIVE half of "the path constant moves, the file does not" (RULED openxFactory#656 comment 5656343213; LANDED note 5690615323).

What that leg landed, so a reviewer need not go and look: six pre-carve path constants repaired — test_outline_model.py:22, test_doxbench_view.py:303, test_doxbench_knowledge.py:31, test_doxbench_document_abstract.py:44, test_doxbench_memory_gateway.py:32, test_bullseye_widget.py:1674 — each one the reason a whole arrived suite could not run, and every one of them declared on its own row in openxFactory#1025. That leg's own validate list went from 10 files to 27 and from 283 to 694 tests. spec is unchanged at a8f5eb73.

from to
code gitlink + contracts/code-pin.yaml commit: 1e469713… 0b4e8bbf68fabfcd65d4f0d80e619c20a013e888
contracts/code-pin.yaml digests.tree_sha256 efb196d2… db8817ddde1a15574d6e7c82ef9b62f8fa6029b80f61e24818ff458cde3260ae

Two files, exactly the two the lockstep invariant predicts for a leg with no workflow @<sha> reference (AGENTS-shape.md, "Advancing a leg is ONE commit here"). The digest is sorted-ls-tree-r-v1 recomputed from the submodule's own object store — 165 entries — and re-checked independently rather than retyped from the bump script's own output.

What this leg does NOT do. It does not move spec. It does not move openXdox or openxFactory — those are legs 2 and 3 of the same lockstep, and leg 2 additionally waits on openXdox-code's opendox dependency bump (openXdox-code PR in this same claim). It changes no line of openDox-code itself.

$ python3 scripts/validate-pins.py
  ok  spec: gitlink == contracts/spec-pin.yaml commit a8f5eb73671c
  ok  spec: tree digest recomputes (658c034d6eba…)
  ok  code: gitlink == contracts/code-pin.yaml commit 0b4e8bbf68fa
  ok  code: tree digest recomputes (db8817ddde1a…)
  ok  contracts/shape-pin.yaml: 10 copied shape file(s) match their digests
pins ok
                                                            [exit 0]

$ python3 scripts/validate-manifest.py
manifest ok: openDox (opendox), 3 legs
                                                            [exit 0]

$ python3 scripts/validate-repository-naming.py --project project.yaml
  openDox                          neutral-product/assembly   also_matches project-leg/assembly
  openDox-spec                     project-leg/spec
  openDox-code                     project-leg/code
                                                            [exit 0]

🤖 Generated with Claude Code

Summary by Sourcery

Advance the openDox code dependency and its lockstep metadata to the validated receive-leg revision.

Enhancements:

  • Advance the openDox code submodule pin to the receive-leg revision containing the repaired path constants.

Chores:

  • Refresh the recorded code tree digest to match the new pinned revision.

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

Refs opensoft/openxFactory#656 (stays OPEN). CLAIM: PENDING (amend before push).

First leg of pin lockstep #3, on lockstep #2's precedent (#8 ->
3819625, LANDED note 5689609863): `code` (opensoft/openDox-code) advances
`1e469713` -> `0b4e8bbf`, carrying S 3.4 slice S8 leg B
(opensoft/openDox-code#23 -> 0b4e8bbf, LANDED note 5690615323): six path
constants repaired, each of them the reason a whole suite could not run, and
that leg's `validate` list 10 files -> 27 and 283 -> 694 tests. RULED
5656343213, "the path constant moves, the file does not". `spec` unchanged at
`a8f5eb73`. Two files, the two the pin mechanics predict; the digest is
sorted-ls-tree-r-v1 recomputed from the submodule's own object store, not
retyped.

Lane: openxfactory-4
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 16, 2026 15:02
@sourcery-ai

sourcery-ai Bot commented Sep 16, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR advances only the openDox-code dependency for §3.4 slice S8 leg B, updating the submodule gitlink and matching contract commit/tree digest. The pinned revision contains six repaired test path constants and broader validation coverage; spec and other lockstep legs remain unchanged, with all pin, manifest, and naming checks reported passing.

File-Level Changes

Change Details Files
Advance the openDox-code submodule pin to the receive-leg commit and synchronize its recorded tree digest.
  • Update the code gitlink from 1e469713 to 0b4e8bbf.
  • Update contracts/code-pin.yaml with the new commit and recomputed sorted-ls-tree-r-v1 digest.
  • Leave the spec pin, workflows, and source code unchanged.
code
contracts/code-pin.yaml
Carry the S8 receive leg’s repaired path-constant test coverage into the pinned dependency.
  • The new code revision repairs six pre-carve path constants across the affected test suites.
  • The pinned revision expands its validate coverage from 10 files/283 tests to 27 files/694 tests.
code
Validate repository pin, manifest, and naming invariants for the lockstep update.
  • Confirm both submodule commits match their contract pins and tree digests recompute.
  • Confirm the three-leg manifest and repository naming checks pass.
contracts/code-pin.yaml
scripts/validate-pins.py
scripts/validate-manifest.py
scripts/validate-repository-naming.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

@sonarqubecloud

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.

🟢 Approval recommended

No unresolved review comments; the dependency pin and metadata are synchronized.

Pull request overview

Advances the openDox code dependency to the validated receive-leg revision.

Changes:

  • Updates the code pin to 0b4e8bbf.
  • Refreshes the recorded commit and tree digest.
File summaries
File Description
contracts/code-pin.yaml Updates the pinned commit and matching tree digest.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

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

@brettheap
brettheap marked this pull request as ready for review September 16, 2026 18:03
@brettheap
brettheap merged commit c4c5014 into main Sep 16, 2026
3 checks passed

@sourcery-ai sourcery-ai Bot 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.

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 1 day and 7 hours by commenting @sourcery-ai review. Upgrade to get a review now.

brettheap added a commit to opensoft/openXdox that referenced this pull request Sep 17, 2026
…cy bump) and openDox pin to c4c5014d (S8 leg B) (#11)

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

Refs opensoft/openxFactory#656 (stays OPEN). CLAIM: 5699629088.

Second leg of pin lockstep #3, on #10 -> a650014's precedent:
`code` (opensoft/openXdox-code) advances `c1ad341a` -> `2529c10a`, and
`contracts/opendox-pin.yaml` advances `3819625e` -> `c4c5014d` to match
opensoft/openDox#9. `spec` unchanged at `ae59dfa5`.

`code` CROSSES TWO LANDINGS in one advance, because lockstep #2 stopped at
c1ad341a deliberately, before #19 existed:
  1. S 3.4 S8 leg A - openXdox-code#19 -> 0a0265f7: 44 of the 46 root spellings
     across 31 files stop naming `REPO_ROOT / "src" / "openxdox" / "web"`, a
     directory this leg does not have, and read openDox's bundle through the
     PIN instead (RULED openxFactory#656 comment 5656343213, "the path constant
     moves, the file does not"; LANDED note 5690615323).
  2. The `opendox` dependency bump - openXdox-code#21 -> 2529c10a (LANDED note
     5714326926): pyproject.toml pins `opendox` at openDox-code 0b4e8bbf, the
     act owed by the S5 LANDED note 5656797299 item 4 and by pin lockstep #2's
     residue item 1. That leg's `validate` reads 360 passed / 6 skipped at the
     landed head, of which the bump alone is 317 / 6 - the three S5
     materialization assertions and the thirteen node probes stop skipping and
     pass - and the rest is its 43 direct tests of the PEP 610 provenance guard.
So this is the first openXdox assembly commit whose `code` both points at
openDox's bundle AND declares an `opendox` that carries one.

`contracts/opendox-pin.yaml` moves in the SAME commit because openxFactory's
`scripts/verify-opendox-pin.py` check 5 reads THIS file as a git BLOB out of
this repository's object store, at whatever commit openxFactory's `openXdox`
gitlink names, and refuses `opendox-pin-lockstep-mismatch` the moment it
disagrees with openxFactory's own direct pin of openDox. Leg 3 cannot pass
until this leg has landed naming the same openDox assembly commit.

Three files, the three #10 predicts. Both digests are sorted-ls-tree-r-v1
recomputed - the code one from this repository's own object store
(d4cff06d27127f949a3e51bddace29f8164777e7cf7d95695eccb43c3b789358), the openDox
one from a sibling checkout of opensoft/openDox
(f7b9b0236ae6afabcb2692abb3f7e084053ea67babf450222efff7452cac51f6) - not
retyped from anywhere. `digest_source` does not move: it is already
`local-checkout`.

GATE EVIDENCE, MEASURED AT THE LANDED HEAD 38b36e4: `validate` SUCCESS, run
35221373195 (check run 105202087872), this leg's only required check;
validate-pins.py `pins ok` with the tree digests recomputed and the
gitlink/pin-file lockstep confirmed, validate-manifest.py `manifest ok:
openXdox (openxdox), 3 legs` and validate-repository-naming.py exit 0.
SonarCloud PASSES here. Copilot's review 5235635969 at this head reads
"Approval recommended - Pin updates and corresponding digests are synchronized
and validated", files reviewed 3/3, comments generated 0, with NO suppressed
comments section; 0 review threads / 0 unresolved.

Lane: openxfactory-4
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
brettheap added a commit to opensoft/openxFactory that referenced this pull request Sep 17, 2026
…the opendox dependency bump (#1084)

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

Refs #656 (stays OPEN). CLAIM: 5699629088.

Third and final leg of pin lockstep #3, after opensoft/openDox#9 -> c4c5014d
and opensoft/openXdox#11 -> 88a1047e. Precedent #1054 -> 3c614d3 (lockstep #2,
LANDED note 5689609863): two gitlinks, two pin YAMLs, one test literal.

  openDox  gitlink + contracts/opendox-pin.yaml  3819625e -> c4c5014d
           digests.tree_sha256                   40c6216c -> f7b9b023
  openXdox gitlink + contracts/openxdox-pin.yaml a6500141 -> 88a1047e
           digests.tree_sha256                   47a420da -> cdbe7573
  tests/openxdox_pin/test_openxdox_pin_verifier.py (the lockstep literal)
                                                 3819625e -> c4c5014d

WHAT THE TWO ADVANCES CARRY. openDox 3819625e -> c4c5014d moves `code`
1e469713 -> 0b4e8bbf: S 3.4 slice S8 leg B (openDox-code#23), six pre-carve
path constants repaired, that leg's validate list 10 -> 27 files and 283 ->
694 tests. openXdox a6500141 -> 88a1047e moves `code` c1ad341a -> 2529c10a,
crossing TWO landings because lockstep #2 stopped at c1ad341a deliberately,
before #19 existed: S 3.4 slice S8 leg A (openXdox-code#19 - 44 of the 46 root
spellings across 31 files read openDox's bundle through the PIN instead of a
directory that leg does not have) and the `opendox` dependency bump
(openXdox-code#21 -> 2529c10a, LANDED note 5714326926 - pyproject.toml pins
openDox-code 0b4e8bbf; that leg's validate reads 360 passed / 6 skipped at its
landed head, of which the bump alone is 317 / 6 and the rest is the 43 direct
tests of the PEP 610 provenance guard its thirty review rounds asked for).

THIS IS THE LOCKSTEP THAT CLOSES THE LOOP THE LAST ONE LEFT OPEN. Copilot's
suppressed finding on #1054 was that the pinned openXdox code declared an
`opendox` OLDER than the lockstep contract named, so that leg's materialization
assertions SKIPPED rather than ran. It is answered here by the object pinned,
not by prose: openXdox-code's pyproject.toml now names the same 0b4e8bbf that
contracts/opendox-pin.yaml reaches through the openDox assembly.

THE MIGRATION DECLARATION is a CHAIN ADVANCE, not a schema change, and the
sentinel was RE-MEASURED rather than assumed: `git ls-tree -r 0b4e8bbf |
grep -i migration` on openDox-code's own checkout returns nothing, so
`not_yet_deployed` still holds. The sentence now names 0b4e8bbf under
c4c5014d, keeping 1e469713 under 3819625e, 05bbde80 under 7cf6c143 and
a99eba03 under 8ec3036c as the chain (#1020's shape, carried by #1054).

THE CONSUMER SURFACE, and the baseline it is read against. This branch was cut
from main at a93d268, and main's OWN pytest-suite run at that exact commit -
35219872882 - concluded SUCCESS (2026-09-17T12:13Z). That is the baseline the
runbook requires before any red here is called a regression.

Measured at the head: scripts/verify-opendox-pin.py and
scripts/verify-openxdox-pin.py both OK, with the cross-repository lockstep
confirmed; pytest tests/opendox_pin tests/openxdox_pin -q -> 105 passed;
validate-carve-manifest.py OK (456 rows, 143/175/138, 318 digests recomputed,
none undeclared, 4 RE-DESTINED by RULED Q6); and the whole consumer surface
lockstep #2 needed three review rounds to clear -
tests/carve_manifest, tests/carve_arrival, tests/carve_conformance,
tests/opendox_pin, tests/openxdox_pin - 481 passed at the same pin values.

TWO CONSUMER FILES MOVED, and they are prose rather than behaviour:
scripts/profile_openxfactory.py::_display_facet and
tests/test_engineering_profile_display_facet.py described 1e469713 as the code
leg this repository pins, which this commit makes stale. Both now name the
CHAIN - 1e469713 is where the live import path became possible, 0b4e8bbf is the
leg pinned now - each live claim re-measured in the pinned checkout's own object
store (git ls-tree -r 0b4e8bbf names src/opendox/display_profile.py with
normalize_display at :445, and src/opendox/view_extension.py with
host_profile_name). Copilot's review of 268a6fe found them; that test file
reads 16 passed after the edit. The openspec/changes tasks.md hits on the same
sha are slice S7's record and are deliberately left alone.

NOT DONE HERE, by name. (1) opensoft/openXdox's own contracts/opendox-pin.yaml
MIGRATION DECLARATION still says "checked at da8aae96, the commit this root's
own code pin currently names" while that root's code pin is 2529c10a. It is a
COMMENT no verifier reads - check 5 reads that blob's commit: field, which is
c4c5014d and which the verifier confirms in lockstep - and it was already stale
at the previous pin a6500141 (root code c1ad341a), so this act neither
introduced it nor is the first to carry it; correcting it needs an openXdox
root PR and a re-pin, which is a fourth leg mid-lockstep for a comment.
REGISTERED for the declared act on that file. (2) The xFactory aggregation
re-sync - four sites in one commit - becomes owed the moment this lands and
Brett admin-lands it under RULING R-5 (#656 comment 5690428146). (3)
openXdox-code README.md:40-43's "validate runs only the scaffold's shape
assertions" is stale since slice S8 and still owed to a later declared act.

GATE EVIDENCE, MEASURED AT THE LANDED HEAD 96f52cc: ALL ELEVEN checks
SUCCESS - pytest-suite (run 35222985270), lane-line, clearing-dispatch-gate,
former-id-arrival-gate, merge-master-approval, openreposhape-pin,
openspec-cli-pin, openxdox-consumer-gate, release-tag-gate,
signed-execution-chain-gate and wallet-validation. pytest-suite's own floor line
reads `floors: selected>=7050 (margin 1074) passed>=7044 (margin 1074)
skipped==6` - CHARACTER-FOR-CHARACTER the line main's own run 35219872882
printed at the base commit a93d268, which is the baseline this branch is read
against. Copilot's review 5235818601 at this head: "Approval recommended - No
unresolved review issues remain", files reviewed 7/7, comments generated 0, with
NO suppressed-comments section; 0 review threads / 0 unresolved. The one round
this pull request took is recorded in its description.

Lane: openxfactory-4
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
brettheap added a commit that referenced this pull request Sep 19, 2026
… 3.7 FLOOR PART 3, § 5.4 (d)) and spec to 8fe8c4c7 (four of the five § 6 re-homes) (#10)

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

Refs opensoft/openxFactory#656 (stays OPEN). CLAIM: [5738280604](opensoft/openxFactory#656 (comment)).

Runbook **Phase 3** — `docs/opendox-cutover-runbook.md`:1812, *"the assembly
roots: `carved_from` + gitlink + pin, ONE COMMIT"*. The second and last of the
pair; opensoft/openXdox#12 is the first.

## What moves — four paths, no fifth

| leg | gitlink + pin `commit:` | `digests.tree_sha256:` |
| --- | --- | --- |
| `code` | `0b4e8bbf…` → **`d816cf06f1c9752a39c2b71ba40adc4ae3f3bf66`** | `db8817dd…` → **`ac877e49b7ec001a22be21ce18021208e00f9d1d2c2ceb997b060a0b247fbcac`** |
| `spec` | `a8f5eb73…` → **`8fe8c4c71c4da8d363394441ad9e2c9547e540a3`** | `658c034d…` → **`f63c5b8fee6bf0fded4cb745555dea6427b274683c5d5bccac01c82e2b0fadbb`** |

```
 code                    | 2 +-
 contracts/code-pin.yaml | 4 ++--
 contracts/spec-pin.yaml | 4 ++--
 spec                    | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)
```

Each target is that repository's `main` tip, **measured at 2026-09-19T01:31Z**
and not carried forward. The runbook's pre-push object check (:1825-1830 — *git
stores a gitlink without checking the object is present, so a wrong pin commits
and pushes clean*): `git -C code cat-file -t d816cf06…` and `git -C spec
cat-file -t 8fe8c4c7…` both print `commit`, and both equal `origin/main` in
their own repository.

## What the advance carries — the largest of the arc

**`code`, nine commits** (64 files, 37 529 insertions, 1 358 deletions):

| | |
| --- | --- |
| `d816cf0` | § 3.6 follow-up #2: a linked worktree's metadata, and a store refusal that is a refusal (openDox-code#32) |
| `93ccc3d` | § 3.7 FLOOR PART 3, openDox side: the declared conformance factory and Q-F1's transposition (#31) |
| `5c86713` | § 3.6 follow-ups: the seven findings #26 registered, each with its case (#30) |
| `373b05a` | § 5.4 FLOOR PART 2 clause (d), openDox leg: the collection triple pinned on the required check (#29) |
| `4f8ae01` | § 3.6: openDox creates a repository as a first-class act, with RULING C3's conformant local-git adapter (#26) |
| `aca94ec` | § 3.5: the openDox runtime — FastAPI + Postgres, identity and coordination, and nothing else (RULED Q1/Q2) (#25) |
| `52b237e` | § 3.4 S7 residue: the display facet threaded to the seven leaves it never reached (#28) |
| `5c137a9` | § 3.4 RULED Q7: a contributed binding's CSS leaves `styles.css` for the binding's own sheet (#27) |
| `0e65b5f` | the two intent-feed DOM suites retired at this leg (#24) |

**`spec`, eight commits** (15 files, 3 636 insertions, 0 deletions):

| | |
| --- | --- |
| `8fe8c4c` | § 6.2 — the surviving `-v2` chat-turn family (openDox-spec#15) |
| `66d5977` | § 6.5 — `add-lens-document-selection`, the set-builder half (#14) |
| `3b7f80c` | § 6.3 — `add-doxchat-model-intake`, the model plane (#13) |
| `edeed08` | § 6.4 — `add-composed-view-authoring`, openDox's first OpenSpec change (#12) |
| `54e9107` | Front-end boundary note, amendment #3 (#11) |
| `7d12428` | Front-end boundary note, amendment #2 (#10) |
| `61866d2` | § 3.4 boundary note: the five rulings Q1–Q5 and the S1–S3 start (#9) |
| `a44ac06` | § 3.4 design note: the front-end package boundary (#8) |

**Taken with openXdox#12, this pair is the first moment BOTH roots name all five
§ 6 re-homes:** § 6.1's refresh lane is `openXdox-spec` `f088b097`, pinned by
#12; § 6.2–6.5 are `openDox-spec` `8fe8c4c7`, pinned here.

## The third fact-class is VACUOUS here, measured rather than assumed

`scripts/validate-pins.py` holds gitlink + pin-file `commit:` + **every**
`.github/workflows/*.yml` `<org>/<leg>@<sha>` reference as one invariant. This
root has one workflow and exactly one 40-hex `@sha` in it —
`actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349`
(`validate.yml`:104) — naming neither leg, so there is no third fact to move and
no *"workflow @&lt;sha&gt; reference(s) agree"* note is printed.
`neutral_product_pins: []` here, so unlike openXdox's root there is no
neutral-pin recheck either: **five `ok` lines, not six.** A grep for the two
outgoing shas across the whole tree finds them in exactly the two pin files and
nowhere else.

## Both digests recomputed, by two independent paths that agree

`sorted-ls-tree-r-v1`, via this repository's own `scripts/repo_shape.py` —
`tree_digest()` reads the submodule's **object store**, `tree_digest_from_gh()`
reads the **forge's** recursive tree listing:

```
code d816cf06f1c9  local=ac877e49b7ec001a22be21ce18021208e00f9d1d2c2ceb997b060a0b247fbcac
                   gh   =ac877e49b7ec001a22be21ce18021208e00f9d1d2c2ceb997b060a0b247fbcac  AGREE=True
spec 8fe8c4c71c4d  local=f63c5b8fee6bf0fded4cb745555dea6427b274683c5d5bccac01c82e2b0fadbb
                   gh   =f63c5b8fee6bf0fded4cb745555dea6427b274683c5d5bccac01c82e2b0fadbb  AGREE=True
```

Neither was retyped from anywhere.

## Verification — BEFORE and AFTER, the same five lines so they compare line for line

**BEFORE**, at root `c4c5014d9b39ac55e5df957db23a56db38847a6b`, legs initialized
with `git submodule update --init code spec` (never a bare `git add` of a
submodule):

```
  ok  spec: gitlink == contracts/spec-pin.yaml commit a8f5eb73671c
  ok  spec: tree digest recomputes (658c034d6eba…)
  ok  code: gitlink == contracts/code-pin.yaml commit 0b4e8bbf68fa
  ok  code: tree digest recomputes (db8817ddde1a…)
  ok  contracts/shape-pin.yaml: 10 copied shape file(s) match their digests
pins ok
```
exit 0.

**AFTER**, at this branch's head:

```
  ok  spec: gitlink == contracts/spec-pin.yaml commit 8fe8c4c71c4d
  ok  spec: tree digest recomputes (f63c5b8fee6b…)
  ok  code: gitlink == contracts/code-pin.yaml commit d816cf06f1c9
  ok  code: tree digest recomputes (ac877e49b7ec…)
  ok  contracts/shape-pin.yaml: 10 copied shape file(s) match their digests
pins ok
```
exit 0.

`make validate` — naming + manifest + pins, *what CI runs* — is green end to
end: `validate-repository-naming.py` exit 0 (`openDox
neutral-product/assembly`, `openDox-spec project-leg/spec`, `openDox-code
project-leg/code`), `validate-manifest.py` `manifest ok: openDox (opendox), 3
legs`, `validate-pins.py` `pins ok`.

## Negative control — so the green is not read as vacuous

With the gitlink moved and `contracts/code-pin.yaml` left at the old commit in
the working tree, the same command exits **1** with two findings:

```
FINDING pin-gitlink-mismatch: code: gitlink d816cf06f1c9752a39c2b71ba40adc4ae3f3bf66 != contracts/code-pin.yaml commit 0b4e8bbf68fabfcd65d4f0d80e619c20a013e888
FINDING pin-digest-mismatch: contracts/code-pin.yaml: digests.tree_sha256 ac877e49b7ec…
       recomputed at 0b4e8bbf68fa db8817ddde1a…
2 finding(s). THE LOCKSTEP RULE: …
```

Restored from the index and re-verified green. **The arm that has to fire, fires.**

## What deliberately does NOT move

`contracts/manifest.yaml` `carved_from` = `{opensoft/openxFactory,
b075fd91dc8fced8e1373825ba80220c33536bae}` — the CARVE commit, a provenance
record of an event (runbook § 1.1), not a pin that tracks a head; the runbook's
item (3) was discharged by the commit that wrote it. Also
`contracts/shape-pin.yaml`, `project.yaml`, and every other file.

## The downstream consequence, measured

openxFactory pins openDox **directly** (`contracts/opendox-pin.yaml` =
`c4c5014d…`, `openDox` gitlink = `c4c5014d…`) and openXdox's root pins it too
(`c4c5014d…`). `verify-opendox-pin.py` **check 5** compares those two
declarations **to each other**, not to openDox's current head — so this advance
breaks nothing: openxFactory continues to pin an older openDox root, which is
what a pin is for.

**Registered as the follow-up, not taken here:** advancing openxFactory to this
new root is a **three-repository** lockstep — openxFactory's `openDox` gitlink,
openxFactory's `contracts/opendox-pin.yaml`, and openXdox's
`contracts/opendox-pin.yaml` (read as a **blob** at whatever commit
openxFactory's `openXdox` gitlink names) must all name the same openDox commit
in one landing, or check 5 refuses `opendox-pin-lockstep-mismatch`.

## Sequencing, and what this PR is not

This is the Phase 3 **pin** act. § 3.8 (`tasks.md`:1517-1521) and § 4.6
(`tasks.md`:2049-2050) cut `dox-v1.0` / `xdox-v1.0` **in the assembly root**,
*"over the commit that names both legs"* — this commit is the first one that
names the landed legs. It **cuts nothing**: runbook § 9, Phase 6 (:2000) — *"the
tags (§ 3.8 and § 4.6). **BRETT'S ACT, ALWAYS.**"*

Sibling search before authoring: `gh pr list --repo opensoft/openDox --state
open` returned **zero** open pull requests at 2026-09-19T01:31:12Z.

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


Lane: openxfactory-4
Co-Authored-By: Claude Fable 5.1 <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