feat(contract): reserve the additive day-level office key (v1.2 Stage 0.1) #495

Merged
manlycucumber merged 7 commits from feat/office-contract-seam into develop 2026-07-18 05:36:18 +00:00

Stage 0.1 of the approved v1.2 build (design of record: docs/design/office-text-layer.md, #494). Reserves the additive day-level office key — the attachment point for the office-structure tree (Office → Hours → parts); ships null until an edition structure is seeded. Additive/minor (ContractShapeTest/DayContractTest/output-contract.md updated in step); golden re-frozen (617 years) in the same commit under the byte-stability gate. Validated in the Coder workspace (PHP 8.4): composer test 1155 ✓ · phpcs ✓ · phpstan No errors ✓; signed+verified as manlycucumber. ⚠️ Forgejo CI is red for a pre-existing environmental reason (GitHub-specific actions on the Forgejo runner; PHP legs fail in CI env despite passing locally on develop) — not introduced by this PR.

**Stage 0.1** of the approved v1.2 build (design of record: `docs/design/office-text-layer.md`, #494). Reserves the additive **day-level `office` key** — the attachment point for the office-structure tree (Office → Hours → parts); ships `null` until an edition structure is seeded. Additive/minor (ContractShapeTest/DayContractTest/output-contract.md updated in step); golden re-frozen (617 years) in the same commit under the byte-stability gate. Validated in the Coder workspace (PHP 8.4): composer test 1155 ✓ · phpcs ✓ · phpstan No errors ✓; signed+verified as manlycucumber. ⚠️ Forgejo CI is red for a pre-existing environmental reason (GitHub-specific actions on the Forgejo runner; PHP legs fail in CI env despite passing locally on develop) — not introduced by this PR.
feat(contract): reserve the additive day-level office key (v1.2 Office/text layer)
Some checks failed
ci / check (7.4) (pull_request) Failing after 3s
ci / check (8.1) (pull_request) Failing after 3s
ci / check (8.2) (pull_request) Failing after 3s
ci / check (8.3) (pull_request) Failing after 3s
ci / validate (1954) (pull_request) Failing after 3s
ci / validate (1955) (pull_request) Failing after 3s
ci / validate (1962) (pull_request) Failing after 3s
ci / validate (novus-ordo-2002) (pull_request) Failing after 3s
ci / validate (overlays) (pull_request) Failing after 3s
ci / corpus-verify (pull_request) Successful in 15s
CodeQL / Analyze (actions) (pull_request) Failing after 3s
pr-title / lint (pull_request) Failing after 2s
project-status-rollup / rollup (pull_request) Failing after 2s
9640310831
Adds `office` to the day contract as a reserved slot that ships `null` until an
edition's office structure is seeded — the attachment point for the v1.2
office-structure tree (Office -> Hours -> parts), per docs/design/office-text-layer.md.

Additive/minor: no existing key removed, renamed, or repurposed; no closed enum
grows; a 1.1.0 consumer that never reads `office` is unaffected. ContractShapeTest
TOP_LEVEL, DayContractTest, and the class docblock are updated in step. The golden
digest moves (every day now serialises `office: null`) and is re-frozen in this
same commit under the byte-stability review gate.
manlycucumber force-pushed feat/office-contract-seam from 9640310831
Some checks failed
ci / check (7.4) (pull_request) Failing after 3s
ci / check (8.1) (pull_request) Failing after 3s
ci / check (8.2) (pull_request) Failing after 3s
ci / check (8.3) (pull_request) Failing after 3s
ci / validate (1954) (pull_request) Failing after 3s
ci / validate (1955) (pull_request) Failing after 3s
ci / validate (1962) (pull_request) Failing after 3s
ci / validate (novus-ordo-2002) (pull_request) Failing after 3s
ci / validate (overlays) (pull_request) Failing after 3s
ci / corpus-verify (pull_request) Successful in 15s
CodeQL / Analyze (actions) (pull_request) Failing after 3s
pr-title / lint (pull_request) Failing after 2s
project-status-rollup / rollup (pull_request) Failing after 2s
to 345d62d5a6
Some checks failed
ci / check (7.4) (pull_request) Has been cancelled
ci / check (8.1) (pull_request) Has been cancelled
ci / check (8.2) (pull_request) Has been cancelled
ci / check (8.3) (pull_request) Has been cancelled
ci / validate (1954) (pull_request) Has been cancelled
ci / validate (1955) (pull_request) Has been cancelled
ci / validate (1962) (pull_request) Has been cancelled
ci / validate (novus-ordo-2002) (pull_request) Has been cancelled
ci / validate (overlays) (pull_request) Has been cancelled
ci / corpus-verify (pull_request) Has been cancelled
CodeQL / Analyze (actions) (pull_request) Has been cancelled
pr-title / lint (pull_request) Has been cancelled
2026-07-17 21:30:04 +00:00
Compare
docs(contract): declare availability + leaf rights OPEN; add v1.2 text-layer scope (Stage 0.2)
All checks were successful
ci / check (7.4) (pull_request) Successful in 1m5s
ci / check (8.1) (pull_request) Successful in 1m1s
ci / check (8.2) (pull_request) Successful in 57s
ci / check (8.3) (pull_request) Successful in 1m13s
ci / validate (1954) (pull_request) Successful in 34s
ci / validate (1955) (pull_request) Successful in 33s
ci / validate (1962) (pull_request) Successful in 32s
ci / validate (novus-ordo-2002) (pull_request) Successful in 34s
ci / validate (overlays) (pull_request) Successful in 33s
ci / corpus-verify (pull_request) Successful in 16s
CodeQL / Analyze (actions) (pull_request) Has been skipped
pr-title / lint (pull_request) Successful in 2s
2f078108e4
- output-contract.md: add the text/chant leaf `availability` and leaf `rights`
  enums to the OPEN list (a future member stays a minor bump). Leaf `rights` is
  free-form (SPDX/URN) and distinct from the CLOSED corpus source-registry rights
  enum. (office-text-layer Open Q #1, #5.)
- text-licensing-model.md: add the v1.2 text-layer scope section — v1.2 ships PD
  text only (Clementine Vulgate + Douay-Rheims, born-cited), office structure is
  CC0, and any copyrighted-only office leaf is citation-only, never full (must-fix
  #A citation-only office scope).
test(contract): track engineVersion via Directorium::VERSION (Stage 0.3, must-fix #B)
Some checks failed
ci / validate (novus-ordo-2002) (pull_request) Successful in 35s
ci / validate (overlays) (pull_request) Successful in 36s
ci / corpus-verify (pull_request) Successful in 13s
CodeQL / Analyze (actions) (pull_request) Has been skipped
pr-title / lint (pull_request) Successful in 2s
ci / check (7.4) (pull_request) Failing after 39s
ci / check (8.1) (pull_request) Failing after 37s
ci / check (8.2) (pull_request) Failing after 37s
ci / check (8.3) (pull_request) Failing after 38s
ci / validate (1954) (pull_request) Successful in 37s
ci / validate (1955) (pull_request) Successful in 39s
ci / validate (1962) (pull_request) Successful in 37s
f9b795099f
The three hardcoded '0.4.0' engineVersion literals in DayContractTest duplicated
the single source of truth at src/Directorium.php (`Directorium::VERSION`), which
production already flows into the contract via DayResolver. Reference the const so
the tests can never silently diverge from the engine version they assert.
feat(contract): corpus-vs-engine golden digest gate; engineVersion 0.5.0 (Stage 0.3b)
Some checks failed
ci / check (7.4) (pull_request) Failing after 38s
ci / check (8.1) (pull_request) Failing after 37s
ci / check (8.2) (pull_request) Failing after 39s
ci / validate (1954) (pull_request) Has been cancelled
ci / validate (1955) (pull_request) Has been cancelled
ci / validate (1962) (pull_request) Has been cancelled
ci / validate (novus-ordo-2002) (pull_request) Has been cancelled
ci / validate (overlays) (pull_request) Has been cancelled
ci / corpus-verify (pull_request) Has been cancelled
CodeQL / Analyze (actions) (pull_request) Has been cancelled
pr-title / lint (pull_request) Has been cancelled
ci / check (8.3) (pull_request) Has been cancelled
f9d1ec43b6
Adds the office-text-layer.md §7B gate that attributes a golden-digest move
to its cause and enforces the matching provenance bump:
  - engine-driven move (corpus content pinned)  => Directorium::VERSION must move
  - corpus-driven move  (MANIFEST sha256 delta) => corpusVersion must move

The two causes are told apart by a corpus-content fingerprint (sha256 over the
MANIFEST per-file sha256s). Enforcement lives at the freeze boundary:
bin/freeze-golden-year.php reads the previously committed lock before
overwriting and refuses a golden move that lacks its bump; GoldenProvenanceLock
+ a committed resolve-year-provenance.lock.json record the axes the fixture was
frozen under; GoldenProvenanceLockTest exercises the classifier and asserts the
lock still describes the committed tree.

Home decided (§10 Open-Q #7): a PHPUnit gate in tests/Golden/ over a
git-diffing CI step -- runs in `composer test`, needs no git history, survives
the --depth=1 CI checkout.

engineVersion adopts its own semver line, decoupled from ROADMAP-milestone
numbering and the release-please distribution version, and moves 0.4.0 -> 0.5.0:
the additive day-level `office` key is an engine-driven digest move, so the gate
requires the bump. DayContractTest already tracks Directorium::VERSION (0.3a),
so no test literals change.
style(test): wrap over-long Provenance line from the 0.3a de-hardcode
All checks were successful
ci / check (7.4) (pull_request) Successful in 1m15s
ci / check (8.1) (pull_request) Successful in 1m10s
ci / validate (1955) (pull_request) Successful in 37s
ci / validate (1962) (pull_request) Successful in 36s
ci / validate (novus-ordo-2002) (pull_request) Successful in 35s
ci / validate (overlays) (pull_request) Successful in 35s
ci / corpus-verify (pull_request) Successful in 15s
CodeQL / Analyze (actions) (pull_request) Has been skipped
pr-title / lint (pull_request) Successful in 2s
ci / check (8.2) (pull_request) Successful in 1m6s
ci / check (8.3) (pull_request) Successful in 1m6s
ci / validate (1954) (pull_request) Successful in 36s
e6548b90f6
The 0.3a swap of the '0.4.0' literal for Directorium::VERSION pushed
DayContractTest.php:198 to 124 chars, tripping PSR12 LineLength (phpcs
fails on warnings here). Wrap the DayContract::from(...) call; no behaviour
change.
feat(corpus): generalize the born-cited gate to office/text; reserve schemas (Stage 0.4a)
Some checks failed
ci / check (8.2) (pull_request) Successful in 1m9s
ci / check (8.3) (pull_request) Successful in 1m8s
ci / check (7.4) (pull_request) Successful in 1m12s
ci / check (8.1) (pull_request) Successful in 1m3s
ci / validate (1962) (pull_request) Has been cancelled
ci / validate (novus-ordo-2002) (pull_request) Has been cancelled
ci / validate (overlays) (pull_request) Has been cancelled
ci / corpus-verify (pull_request) Has been cancelled
ci / validate (1954) (pull_request) Successful in 36s
pr-title / lint (pull_request) Has been cancelled
CodeQL / Analyze (actions) (pull_request) Has been cancelled
ci / validate (1955) (pull_request) Has been cancelled
9d96cc97a1
Extends the fail-closed provenance gate (provenance.mjs) from its name-only
allowlist to an EXPLICIT transcribed-text field map (office-text-layer.md §7C):
office-part titles (title.la/label.la) and text-leaf bodies (value/incipit) are
gated like names — a public-domain `text` source ONLY, no option-A descriptor
exemption — while Directorium-minted address/key fields (textRef, psalter,
scripture, id, seq) are excluded, so they never demand a spurious citation. Adds
the availability/rights arm: a text leaf must declare a known availability tier,
only a `full` leaf may ship a body, value XOR incipit — so a missing licence can
withhold text but never leak it.

Adds two RESERVED/PROVISIONAL corpus schemas (office-structure, text-leaf)
mirroring the identity schemas: they lock the born-cited invariants (Latin
title/label present + non-empty; availability enum; leaf `rights` OPEN and
distinct from the closed source-registry enum) before the first office/text
datum, refined additively when Stages 1-2 author the axis.

Existing 302-record behaviour is byte-identical (corpus output unchanged; verify
OK, 40 files). New gate unit tests cover the strict-PD office rule, the
availability arm, and the withhold path.
feat(corpus): register v1.2 Office/text sources; bump corpusVersion (Stage 0.4b)
All checks were successful
ci / check (7.4) (pull_request) Successful in 1m14s
ci / check (8.2) (pull_request) Successful in 1m3s
ci / check (8.3) (pull_request) Successful in 1m7s
ci / check (8.1) (pull_request) Successful in 1m3s
ci / validate (1954) (pull_request) Successful in 38s
ci / validate (1955) (pull_request) Successful in 35s
ci / validate (1962) (pull_request) Successful in 33s
ci / validate (novus-ordo-2002) (pull_request) Successful in 33s
ci / validate (overlays) (pull_request) Successful in 42s
ci / corpus-verify (pull_request) Successful in 14s
CodeQL / Analyze (actions) (pull_request) Has been skipped
pr-title / lint (pull_request) Successful in 2s
project-status-rollup / rollup (pull_request) Has been skipped
6ed48117a3
Registers the seven v1.2 source keys in the ENFORCED sources.yaml
(office-text-layer.md §6, §9.4a), ahead of the Stage 1-5 authoring that cites them:
  - clementina-1592, dr-challoner-1899            (text/PD — psalter + scripture)
  - lobvm-benziger-1915, off-defunct-keating-1825 (text/PD — office propers)
  - catholic-encyclopedia-1910 / -1913            (text/PD — office SHAPE facts only)
  - br-1961                                       (reference — 1962 cross-check, never transcribed)

Reconciles SOURCES.md to the enforced registry (adds the v1.2 text-source table;
br-1961 was already listed). The §6 NEEDS-VERIFICATION caveats are preserved as
notes; the contested Clementine imprint/scan (Open-Q #10) is a per-leaf :locator
concern pinned at Stage 2 ingest, not the registry row — so registering the rows
needs no maintainer decision and authors NO transcribed text.

Corpus content changed (sources.ndjson), so corpusVersion bumps
1962-2026-07-11.2 -> 1962-2026-07-18 and the corpus is regenerated. The resolved
liturgy is byte-identical (the new sources are unused, and corpusVersion is
stripped from the golden digest), so the golden fixture does not move: a
corpus-driven, non-liturgical change — the golden provenance lock refreshes its
corpusContentDigest + corpusVersion with goldenDigest unchanged, exactly as the
Stage 0.3b gate models. verify OK (40 files); generator tests 70/70.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Directorium/Core!495
No description provided.