Skip to content

openDox root: pin both carved legs and record carved_from (split-opendox § 3.3, RULED OQ-I) - #4

Merged
brettheap merged 2 commits into
mainfrom
carve/opendox-root-pin
Sep 10, 2026
Merged

brettheap merged 2 commits into
mainfrom
carve/opendox-root-pin

Conversation

@brettheap

@brettheap brettheap commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Lane: openxfactory-4-opendox-extraction (formerly openxfactory-opendox)

Refs opensoft/openxFactory#656 — CARVE arc, Phase 3 of docs/opendox-cutover-runbook.md § 6 (assembly roots: carved_from + gitlink + pin, ONE COMMIT).

Brett Heap's words (2026-09-10), on which this pull request exists and lands: "do the openDox root pin after leg 1 lands", "then start the root pin when leg 2 lands", "merge the root pin when green". Both legs had merged to their own main before this branch was cut, so both gitlinks below pin a carve merge, never a scaffold or a pre-merge branch tip.

What moved, in the one commit

Three facts per leg are one invariant (README ## The lockstep invariant, scripts/validate-pins.py), plus § 1 record 1 at the root:

fact code leg spec leg
gitlink ce53b489f8007c37f70da19c90c95ba89156feed fc67332d5ef203624d5c557f7c53d1f134d6d2ea
contracts/<role>-pin.yaml commit: same same
digests.tree_sha256: 49a0da5b44843fd33da89b88ce9eec4ce077445ff241324aa578830b0fc0f5a4 93c4ed4287815b67eb12087eed1df912365dc8c6f7b158e139755574453e4c95
was (pre-carve scaffold) 580f61df… / 0200b00eba62… 60e546c6… / a1218f8e9686…

Each merge sha is that leg's own carve pull request's merge commit, and is that leg's main tip:

  • code — opensoft/openDox-code#6, "Carve leg 1 (re-cut): openDox-code receives its 123 rows at opendox-carve-0 (split-opendox § 3.2, RULED Q-L4)", merged 2026-09-10T12:37:23Z → ce53b489f8007c37f70da19c90c95ba89156feed. (opensoft/openDox-code#4 was the first cut and is CLOSED, superseded by the re-cut.)
  • spec — opensoft/openDox-spec#4, "Carve leg 2: openDox-spec receives its 56 rows at opendox-carve-0 (split-opendox § 3.2)", merged 2026-09-10T13:10:54Z → fc67332d5ef203624d5c557f7c53d1f134d6d2ea.

Both digests are recomputed under each pin file's own sorted-ls-tree-r-v1 definition — sha256 over the sorted git ls-tree -r -z <rev> records, each with a trailing newline — from the leg's own object store at the explicit merge sha, never HEAD. Computed twice, independently: by hand from git ls-tree -r -z, and by this repository's own scripts/repo_shape.py::tree_digest. Both agree, and validate-pins.py recomputes them a third time below.

carved_from: — RULED OQ-I record 1, as written into contracts/manifest.yaml

carved_from:
  repository: opensoft/openxFactory
  commit: "b075fd91dc8fced8e1373825ba80220c33536bae"
  carve_tag: opendox-carve-0
  manifest: docs/opendox-carve-manifest.yaml
  legs:
    code: 123
    spec: 56

Block style, matching the slot's own pre-written comment template; runbook § 1.1 renders the same YAML value in flow form (legs: {code: 123, spec: 56}). The row counts are the landed manifest's own, re-counted here against docs/opendox-carve-manifest.yaml at openxFactory main (b91af6ea): {'opendox_code': 123, 'opendox_spec': 56, 'openxdox_code': 92, 'openxdox_spec': 47, None: 138} of 456 rows.

The stale comment was corrected, not deleted. The slot's # CARVE PROVENANCE block said "NOTHING IS WRITTEN HERE YET" and carried a bracketed placeholder example — both untrue the moment real content landed beside them. The rationale prose is kept in full (RULED OQ-I, the three records, why there is no bare CARVE_COMMIT file, the openXwallet precedent, and the warning that validate-manifest.py reads project.yaml and is digest-pinned so must not be edited into reading this file); what changed is the tense: the placeholder example is replaced by the real mapping, the heading now says the slot is filled, and a new paragraph records which commit filled it and names the one piece of running code that reads the record — openxFactory's scripts/verify-carve-arrival.py and its arrival-carved-from-mismatch refusal.

carve_commit: was deliberately NOT added to code-pin.yaml / spec-pin.yaml

Record 2 of § 1 names exactly two pin files — openXdox's contracts/opendox-pin.yaml and openxFactory's contracts/openxdox-pin.yaml — each a downstream project's pin of a whole carved assembly root (the precedent being openxFactory's contracts/openxwallet-pin.yaml, which does carry carve_commit:); code-pin.yaml / spec-pin.yaml pin legs of this same project, ordinary submodule pins that exist independent of any carve, and § 6's Phase-3 checklist lists only their commit: + digests.tree_sha256:. Nothing else in either file changed.

Nothing under .github/workflows/ moves. The lockstep invariant's third fact has no member here: validate.yml is the only workflow, and its only @<sha> reference is actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 — a third-party Action, not a leg repository, so validate-pins.py's wf_repo == leg.source_repository filter never sees it. (It is also one of the ten files digest-pinned in contracts/shape-pin.yaml.)

Evidence

§ 6's "verify the gitlink object EXISTS before pushing" — git records a gitlink without checking the object is present, so a wrong pin commits and pushes clean:

$ git -C code cat-file -t ce53b489f8007c37f70da19c90c95ba89156feed
commit
$ git -C spec cat-file -t fc67332d5ef203624d5c557f7c53d1f134d6d2ea
commit

This repository's own gate (make validate → naming, manifest, lockstep pins), on the committed tree:

$ make validate
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
python3 scripts/validate-manifest.py
manifest ok: openDox (opendox), 3 legs
python3 scripts/validate-pins.py
  ok  spec: gitlink == contracts/spec-pin.yaml commit fc67332d5ef2
  ok  spec: tree digest recomputes (93c4ed428781…)
  ok  code: gitlink == contracts/code-pin.yaml commit ce53b489f800
  ok  code: tree digest recomputes (49a0da5b4484…)
  ok  contracts/shape-pin.yaml: 10 copied shape file(s) match their digests
pins ok

The arrival verifier, from a fresh read-only clone of opensoft/openxFactory main (b91af6eab605021118e625a013961123ac9796e2) — for this destination the carved_from check is the whole job, since opendox_root declares 0 rows:

$ python3 scripts/verify-carve-arrival.py \
    --manifest docs/opendox-carve-manifest.yaml \
    --destination opendox_root \
    --dest-root /tmp/claude-1000/-home-brett-projects-xFactory-openxFactory/5b1e0e68-b739-4150-a2ca-e91c8af4ff50/scratchpad/rootpin-work/openDox \
    --source-repo . --phase A
OK /tmp/claude-1000/-home-brett-projects-xFactory-openxFactory/5b1e0e68-b739-4150-a2ca-e91c8af4ff50/scratchpad/rootpin-work/openDox: opendox_root (opensoft/openDox) at opensoft/openxFactory@b075fd91dc8f (opendox-carve-0), phase A — 0 row(s) arrived, 0 digest(s) verified, 0 declared-edit row(s) within their lines, 0 unapplied; 0 of 0 declared replica(s) byte-identical; 0 file(s) under (none declared) with none undeclared (0 scaffold, 0 replica, 0 created); scaffold admissions checked against 7334cd4ae671; carved_from opensoft/openxFactory@b075fd91dc8f

Exit 0. The --assembly-root opensoft/openXdox invocation shown beside it in § 6 was deliberately not run — that verifies openXdox's own record, a different repository and a later phase.

NOT DONE here — separate, later work

  • opensoft/openXdox's own root commit (its carved_from: + both openXdox leg gitlinks and pins) — Phase 3 at the other assembly root.
  • openXdox's contracts/opendox-pin.yaml bump to this repository's root commit and tree digest, plus its carve_commit: — runbook § 4.2 / Phase 3, in openXdox.
  • openxFactory's new contracts/openxdox-pin.yaml + the openXdox gitlink — Phase 4 (RULED OQ-L), in openxFactory.
  • The tags (dox-v1.0, xdox-v1.0) — Phase 6, always Brett Heap's act.

Rollback

Runbook § 10, Phase 3: revert this commit (gitlink + pin + carved_from together). Cost is zero outside this repository — the legs are unchanged by it, nothing outside this root reads it yet, and openxFactory pins nothing until Phase 5.

Landing

Lands on Brett Heap's word "merge the root pin when green" via the lane's gate. Asking for Brett Heap's separate word to land this (CODEOWNERS * @brettheap; gh opens pull requests as brettheap, so the code-owner requirement cannot clear on his own click — admin merge with a recorded OrganizationAdmin bypass actor is the standing pattern, runbook § 12 act 1).

🤖 Generated with Claude Code

Summary by Sourcery

Finalize the openDox assembly root by recording its carve provenance and synchronizing both leg pins with their merged carve revisions.

Enhancements:

  • Record the openDox carve provenance in contracts/manifest.yaml, including the source commit, carve tag, manifest, and per-leg row counts.
  • Pin the code and spec submodules to their merged carve commits and update their corresponding tree digests to preserve the lockstep invariant.

Tests:

  • Validate the updated gitlinks, pin commits, and tree digests with the repository validation gate.

…dox § 3.3, RULED OQ-I)

Phase 3 of the CARVE arc (openxFactory `docs/opendox-cutover-runbook.md`
§ 6): at an assembly root the `carved_from:` record, both leg gitlinks and
both leg pin files move in ONE commit, because they are one invariant.

  code  ce53b489f8007c37f70da19c90c95ba89156feed
        merge of opensoft/openDox-code#6 (leg 1, re-cut; 123 rows)
        tree_sha256 49a0da5b44843fd33da89b88ce9eec4ce077445ff241324aa578830b0fc0f5a4
  spec  fc67332d5ef203624d5c557f7c53d1f134d6d2ea
        merge of opensoft/openDox-spec#4 (leg 2; 56 rows)
        tree_sha256 93c4ed4287815b67eb12087eed1df912365dc8c6f7b158e139755574453e4c95

Each digest is recomputed under that pin file's own `sorted-ls-tree-r-v1`
definition, from the leg's own object store at the explicit merge sha — never
`HEAD` — and `git -C <leg> cat-file -t <sha>` printed `commit` for both
before this was pushed, which is § 6's own precondition: git records a
gitlink without checking the object is present, so a wrong pin commits and
pushes clean.

`carved_from:` in `contracts/manifest.yaml` is record 1 of RULED OQ-I's three
provenance records (§ 1, § 1.1): opensoft/openxFactory at
b075fd91dc8fced8e1373825ba80220c33536bae, tag opendox-carve-0, manifest
docs/opendox-carve-manifest.yaml, legs {code: 123, spec: 56}. The slot's
pre-written comment block is KEPT and re-tensed: its "NOTHING IS WRITTEN
HERE YET" paragraph and bracketed placeholder example are replaced by the
real mapping and by a note of which commit filled it.

No `carve_commit:` is added to `code-pin.yaml` / `spec-pin.yaml`. Record 2
names openXdox's `contracts/opendox-pin.yaml` and openxFactory's
`contracts/openxdox-pin.yaml` — a downstream project's pin of a whole carved
assembly root — not a same-project leg pin, which exists independent of any
carve. Nothing under `.github/workflows/` moves either: the only `@<sha>`
there is `actions/create-github-app-token`, not a leg repository, so the
lockstep invariant's third fact has no member in this repository.

`make validate` green: naming, manifest, and the lockstep pins with both
digests recomputed.

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

sourcery-ai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Pins the openDox assembly root to the merged code and spec carve legs, updates both lockstep tree digests, and records the carve provenance and row counts in the root manifest. The change is validated by the repository pin checks and the source arrival verifier; downstream openXdox pinning and later assembly phases remain out of scope.

Sequence diagram for validating the carved openDox root

sequenceDiagram
    participant Root as openDox root
    participant Pins as validate-pins.py
    participant Arrival as verify-carve-arrival.py
    participant Source as openxFactory source

    Root->>Pins: validate pins
    Pins->>Pins: recompute tree digests
    Pins-->>Root: pins ok
    Root->>Arrival: verify-carve-arrival.py
    Arrival->>Source: read carved_from commit and manifest
    Source-->>Arrival: source and carve metadata
    Arrival-->>Root: carved_from verified
Loading

File-Level Changes

Change Details Files
Advance both openDox leg gitlinks and lockstep pin metadata to the merged carve commits.
  • Update the code leg gitlink and its pinned commit/tree digest.
  • Update the spec leg gitlink and its pinned commit/tree digest.
  • Preserve the invariant that each gitlink, pin commit, and tree digest refer to the same leg revision.
code
spec
contracts/code-pin.yaml
contracts/spec-pin.yaml
Record the openDox carve provenance at the assembly root.
  • Add the resolved carved_from mapping with source commit, tag, manifest, and code/spec row counts.
  • Update the provenance comments to document the filled Phase 3 slot, validation ownership, and arrival-verifier behavior.
  • Do not add carve_commit to the leg pin files or modify workflows.
contracts/manifest.yaml

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

@brettheap
brettheap marked this pull request as ready for review September 10, 2026 13:19

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

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.

🟡 Changes recommended

The updated provenance comment block in contracts/manifest.yaml contains ambiguous/misleading phrasing that should be clarified to match the actual keys and pin-file contents.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the openDox assembly root to reflect the completed carve by (1) pinning both leg submodules to their carve merge commits and (2) recording the carve provenance in contracts/manifest.yaml, aligning the root state with the project’s lockstep pin/digest workflow.

Changes:

  • Update contracts/code-pin.yaml and contracts/spec-pin.yaml to the new leg commit SHAs and corresponding digests.tree_sha256 values.
  • Fill the previously reserved provenance slot in contracts/manifest.yaml with a concrete carved_from: mapping (repository, commit, tag, manifest path, and per-leg row counts).
  • Refresh the surrounding provenance commentary to reflect that the slot is now populated and how it’s consumed externally.
File summaries
File Description
contracts/code-pin.yaml Advances the code leg pin to the carve merge commit and updates the tree digest.
contracts/spec-pin.yaml Advances the spec leg pin to the carve merge commit and updates the tree digest.
contracts/manifest.yaml Records carve provenance via carved_from: and updates the explanatory comment block.
Review details

Suppressed comments (1)

contracts/manifest.yaml:51

  • “unless the two fields below name … source_repository and carve_commit” is ambiguous about which fields it means (keys vs values). Since the YAML uses carved_from.repository / carved_from.commit, spell that out so the check is unambiguous.
# reads the record lives in openxFactory, whose
# `scripts/verify-carve-arrival.py` refuses `arrival-carved-from-mismatch`
# unless the two fields below name the carve manifest's own
# `source_repository` and `carve_commit`; run from an openxFactory checkout:
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

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

Comment thread contracts/manifest.yaml
…al verifier reads (Copilot round)

Comment prose only in `contracts/manifest.yaml` — no machine-read value
moves, and the `carved_from:` mapping is byte-identical to 2f672cc. The
lockstep facts (both gitlinks, both pin `commit:`, both
`digests.tree_sha256:`) and `carved_from:` itself all still land in that ONE
commit, as runbook § 6 requires.

Copilot, on this PR (thread 3979492411, `contracts/manifest.yaml:20`): the
slot's inherited sentence "`carve_commit:` in the pin files is the referent
that survives into the tree the gate reads" reads, IN THIS FILE, as if it
named this repository's own leg pins — which do not define `carve_commit:`,
and deliberately do not (§ 1 record 2 names openXdox's
`contracts/opendox-pin.yaml` and openxFactory's
`contracts/openxdox-pin.yaml`, downstream pins of this whole carved assembly
root). Misleading exactly where this pull request makes a scoping call, so
record 2 and record 3 are now spelled out, with the reason a leg pin carries
no `carve_commit:`.

Copilot's second, suppressed note on the same block: "the two fields below"
was ambiguous between keys and values, so the sentence now names
`carved_from.repository` and `carved_from.commit` and says their VALUES must
equal the carve manifest's `source_repository` and `carve_commit`.

Lane: openxfactory-4-opendox-extraction
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 10, 2026 13:22
@brettheap

brettheap commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor Author

Lane: openxfactory-4-opendox-extraction

Copilot round complete; head is now 6f6096ec789e8f40bbd0c8bae9715ec330f9883a.

One thread, FACTUAL, fixed and resolved: contracts/manifest.yaml:20 — the slot's inherited sentence "carve_commit: in the pin files is the referent that survives into the tree the gate reads" read, in this file, as if it named this repository's leg pins. It does not, and deliberately does not. Copilot's second note on the same block (suppressed; keys vs values at line 51) is fixed in the same commit. Both are comment prose only — see the reply on the thread for the reasoning.

The lockstep facts did not move in the fix commit. carved_from: is byte-identical to 2f672ccb7e3110f5e6eb33b6222917ea54410fd2, and both leg gitlinks, both pin commit: fields and both digests.tree_sha256: values still land in that one commit, as runbook § 6 requires:

$ git diff 2f672cc..6f6096e --stat
 contracts/manifest.yaml | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)
$ git diff 2f672cc..6f6096e -- contracts/manifest.yaml | grep -E '^[-+]' | grep -vcE '^[-+]#|^(\+\+\+|---) '
0

Re-proved on the new head:

  • make validate green — pins ok, both digests recomputed from the legs' own object stores (93c4ed428781… spec, 49a0da5b4484… code), contracts/shape-pin.yaml's 10 copied shape files unchanged.
  • validate on CI green (run 34482286009, 11s) — and its lockstep pins step ran, rather than taking the "legs unavailable" skip branch, so CI recomputed both digests too.
  • python3 scripts/verify-carve-arrival.py --manifest docs/opendox-carve-manifest.yaml --destination opendox_root --dest-root <this checkout> --source-repo . --phase A → exit 0, OK … phase A — 0 row(s) arrived … carved_from opensoft/openxFactory@b075fd91dc8f.

Sourcery is rate-limited on this account for ~11 hours ("you've used your own review budget of 250,000 diff characters for the last 7 days"), so its check reports skipping and there is no Sourcery finding to answer. Nothing is STOPPED on.

🤖 Generated with Claude Code

@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

The updated pins and the new carved_from record are internally consistent and match the repository’s documented pin/provenance structure without introducing code-path changes.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@brettheap
brettheap merged commit 49a99df into main Sep 10, 2026
4 checks passed
brettheap added a commit that referenced this pull request Sep 11, 2026
…UILD slices 1+2) (#5)

Routine pin-sync at the openDox assembly root (step 1 of the lockstep chain; CLAIM 5628856871): both legs move to their current mains in ONE commit, as this root's own Phase-3 PR #4 did — `code` `ce53b489` → `da8aae969b4057bd46d2550c265e5bb363142458` (openDox-code #8 Q-L8 (a) 8e9ffa62, then #9 BUILD slice 2) and `spec` `fc67332d` → `1a216ea413cdcc14791aa3939712e2e459cfa6b6` (openDox-spec #6, the slice-1 stale-citations erratum); `contracts/code-pin.yaml` / `spec-pin.yaml` digests recomputed with the root's own `repo_shape.py::tree_digest` (`sorted-ls-tree-r-v1`; `425c00fd…`, `7a358601…`), each cross-checked independently. Untouched: `contracts/manifest.yaml`'s `carved_from` (openxFactory `b075fd91`, `opendox-carve-0`). Validators: naming ok; `validate-manifest.py` "manifest ok: openDox (opendox), 3 legs"; `validate-pins.py` "pins ok" (both gitlinks == pins, both digests recompute, shape-pin 10 files); arrival verifier `--assembly-root opensoft/openDox` → OK, carved_from unchanged. Required `validate` run 34557598845 success; Sourcery APPROVED; 0 threads; 0 closing references. This closes the pin-chain regression the § 4 scoping found (openXdox-code consumed openDox-code `da8aae96` while this root still pinned `ce53b489`). Steps 2 and 3 follow: openXdox's `contracts/opendox-pin.yaml` → this commit (with task 4.2's three fields, RULED ASK-1), then openxFactory's `openDox` gitlink + pins in lockstep.

Refs opensoft/openxFactory#656.

Lane: openxfactory-4-opendox-extraction
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