Skip to content

feat(tot): unified tot_graphics_stubs_mono.f90 — mono is now loadable (#201 Phase 2a)#206

Merged
k-yoshimi merged 2 commits into
developfrom
chore/l7b-ii-phase-2a-unified-stubs
May 18, 2026
Merged

feat(tot): unified tot_graphics_stubs_mono.f90 — mono is now loadable (#201 Phase 2a)#206
k-yoshimi merged 2 commits into
developfrom
chore/l7b-ii-phase-2a-unified-stubs

Conversation

@k-yoshimi
Copy link
Copy Markdown
Owner

@k-yoshimi k-yoshimi commented May 18, 2026

Summary

Closes the L-7b-ii monolithic image's dlopen-loadability gap that PR #202's PoC left open. libtotapi_mono.so now passes the existing 1e-10 totlib equivalence tests via TOTLIB_PATH, establishing it as a faithful drop-in replacement for the default libtotapi.so on the existing test surface.

This is #201 Phase 2a (build-infrastructure). Phase 2b (Layer-C BPSD smoke + ("eq","tr") rule activation conditional on mono runtime) follows as a separate PR.

Phase 2a Acceptance Criteria — all met locally

AC Status
Unified stub coverage ✅ ~60 symbols across eq/tr/fp/ti/wrx, each defined once
No per-module .so deps libtotapi_mono_inspect HARD GATE 2 (regex on ldd/otool)
Dlopen success python -c "import ctypes; ctypes.CDLL(...)" returns 6 tot_* exports
1e-10 equivalence preserved ✅ 2 passed in 2.78s with TOTLIB_PATH
8-bpsd storage invariant libtotapi_mono_inspect HARD GATE 1 (unchanged from PR #202)
Default libtotapi.so path ✅ untouched
Spec §0 reflects reality ✅ in-place amendment in 1st commit

Commit structure

  1. 276fbaffdocs(spec): L-7b-ii §0 amendment — correct libtotapi.so co-link premise
    In-place edit of docs/superpowers/specs/2026-05-03-l7b-ii-bpsd-broker-coupling-design.md §0. Future readers landing on the original spec see the correction (and the chosen monolithic-image path) before reading the implementation that depends on it.

  2. 3c6936bcfeat(tot): unified tot_graphics_stubs_mono.f90 — mono is now loadable

    • tot/tot_graphics_stubs_mono.f90 (NEW, ~430 lines, ~60 stubs)
    • tot/Makefile: mono prereq fixed ($(OBJS_PIC_MONO)), all 5 per-module stubs filter-out'd, inspect HARD GATE 2 added
    • .github/workflows/python-tests.yml: mono-build job extended with Python setup + 1e-10 equivalence step

ABI choices (documented in source header)

The two cases where per-module stubs declare incompatible signatures with the SAME ELF symbol:

  • GUTIME: REAL ABI. In-house code-review 2026-05-18 audited all live CALL GUTIME sites — fp + tr pass REAL; eq/ti/tot have no live callers (CHARACTER stubs in those files are dead-code hygiene). REAL is unconditionally correct on the reachable surface.
  • EQGOUT: 1-arg form. tr/eq/fp/ti pass an integer; wrx has no live callers.

Reviewer trail

  • In-house: dd4354df → 2 MED (doc-only — comments overstated UB risk) + 1 LOW + drift-detection follow-up (not blocking). All doc MEDs addressed in amend 3c6936bc. Re-review delta: confirmed match, ship.
  • Codex rescue: dd4354df → "approve, ship". Re-review delta 3c6936bc: "ship" (comments-only fix, no code/behavior change).

Test plan (CI)

  • Local: make -C tot libtotapi_mono.so builds (macOS arm64)
  • Local: make -C tot libtotapi_mono_inspect — both HARD GATES pass
  • Local: dlopen verify — all 6 tot_* exports present
  • Local: TOTLIB_PATH=$PWD/tot/libtotapi_mono.so pytest ... --forked → 2 passed in 2.78s
  • CI pytest job: regression check on default libtotapi.so path (unchanged)
  • CI mono-build job: HARD GATE 1 + HARD GATE 2 + NEW: 1e-10 equivalence step

Follow-up (not blocking)

🤖 Generated with Claude Code


Note

Medium Risk
Medium risk because it changes how the monolithic libtotapi_mono.so is linked (new unified stub object, new hard-gates) and adds a new CI test path that loads and exercises the mono shared library, which can expose linker/ABI edge cases across platforms.

Overview
Makes the monolithic libtotapi_mono.so loadable and CI-verified. The mono build now links a new unified tot_graphics_stubs_mono.f90 object and excludes all per-module *_graphics_stubs.o, eliminating missing/duplicate graphics symbols that previously prevented dlopen.

The mono build inspection target is strengthened with a second hard gate to fail if libtotapi_mono.so has any runtime lib*api.so dependencies (in addition to the existing “8 BPSD storage symbols” invariant). CI’s mono-build job is extended to set up Python and run the existing 1e-10 python/totlib equivalence tests against libtotapi_mono.so via TOTLIB_PATH.

Documentation updates correct earlier assumptions about libtotapi.so co-linking and clarify the shift to a truly monolithic image approach for broker-mediated coupling.

Reviewed by Cursor Bugbot for commit 3c6936b. Bugbot is set up for automated code reviews on this repo. Configure here.

k-yoshimi and others added 2 commits May 18, 2026 13:43
Add a "Correction note (2026-05-14)" subsection to §0 of the
original L-7b-ii spec. The 2026-05-04 deferral note assumed
`libtotapi.so` co-links eq+tr+bpsd into one image; `otool -L` and
`nm` verification on the actual shipped artifact (Codex independent
review 2026-05-15) showed this is incorrect — libtotapi.so depends
on the 5 per-module .so files at runtime and carries no bpsd
storage of its own. Existing tot equivalence tests pass at 1e-10
not because the architecture is co-linked but because their
fixtures don't exercise the BPSD-mediated coupling path.

The amendment records:
- The factual correction with the diagnostic commands that confirm it.
- The chosen architectural path (5th option per Codex retrospective:
  true monolithic libtotapi_mono.so, NOT one of the original 4
  candidates a/b/c/d which were too narrow).
- PoC landing (PR #202) and Linux CI coverage (PR #205).
- Phase 2a deliverable (this PR series' next commits): unified
  tot/tot_graphics_stubs_mono.f90 to make the mono image
  dlopen-loadable.
- Phase 2b plan (separate PR within #201) for the actual
  ("eq","tr") rule activation with the stale-BPSD-state isolation
  requirement and conditional registration constraint from Codex
  retrospective 2026-05-15 item 5.

This is the first commit of #201 Phase 2a so future readers landing
on the original spec see the correction before the implementation
that depends on it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#201 Phase 2a)

Closes the L-7b-ii monolithic image's dlopen-loadability gap that
PR #202's PoC left open. The mono build now passes the existing
1e-10 totlib equivalence tests, establishing it as a faithful
drop-in replacement for the default libtotapi.so on the existing
test surface.

Three changes:

1. tot/tot_graphics_stubs_mono.f90 (NEW, ~430 lines, ~60 stubs)
   Hand-authored union of the symbol surface across all five
   per-module <mod>_graphics_stubs.f90 files (eq + tr + fp + ti +
   wrx). Each symbol defined exactly once, grouped by primary
   provenance. ABI choices for symbols that diverge across modules
   are documented in the source header:

   - GUTIME: REAL signature (matches fp/wrx). The CHARACTER call
     sites in eq/tr/ti/tot exist only on plotting paths that the
     equivalence-test happy path does not reach. The 1e-10
     equivalence verification below confirms this choice doesn't
     produce numerical corruption.

   - EQGOUT: 1-argument form (matches eq/tr/fp/ti; wrx's no-arg
     call site is UB but bounded to its own call frame, no read of
     the stub argument occurs in this no-op body).

   - GRD1D: both the standalone wrx form and the grd1d_mod-module
     form are provided — they are TWO DIFFERENT ELF symbols
     (`_grd1d_` vs `___grd1d_mod_MOD_grd1d`).

2. tot/Makefile
   - libtotapi_mono.so prereq corrected from $(OBJS_PIC) to
     $(OBJS_PIC_MONO) so the unified stubs object actually builds.
   - OBJS_PIC_MONO now appends the new mono stubs .o (after
     filtering out tot_graphics_stubs.o, which the default path
     still uses).
   - All 5 per-module <mod>_graphics_stubs.o files are now
     filter-out'd from EQ/TR/FP/TI/WRX_PIC_OBJS_MONO (the previous
     fp pass-through was the partial PoC state; the unified stubs
     supersede it).
   - libtotapi_mono_inspect: "no lib*api.so runtime deps" check
     promoted from observational to HARD GATE 2 with `exit 1` on
     leak. (Bugbot LOW finding from Codex retrospective 2026-05-18.)

3. .github/workflows/python-tests.yml — mono-build job extended
   - "Set up Python" + "Install pytest deps" steps added (Python
     3.11 to match one of pytest job's matrix versions).
   - New "1e-10 equivalence test against libtotapi_mono.so" step
     runs `TOTLIB_PATH=<mono.so> pytest python/totlib/tests/test_equivalence.py`
     to hard-gate the mono image's numerical correctness in CI.

Local verification (macOS arm64, gfortran 15.x):
  $ make -C tot libtotapi_mono.so      # builds
  $ make -C tot libtotapi_mono_inspect # both hard gates OK
  $ python -c "import ctypes; ctypes.CDLL('tot/libtotapi_mono.so')"  # dlopen OK
  $ TOTLIB_PATH=$PWD/tot/libtotapi_mono.so \
      python -m pytest python/totlib/tests/test_equivalence.py \
      --forked --timeout=120 --timeout-method=signal
  # 2 passed in 2.78s

Phase 2b (Layer-C BPSD smoke test + ("eq","tr") rule activation
conditional on mono runtime) is the separate next PR in #201.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@k-yoshimi
Copy link
Copy Markdown
Owner Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 3c6936b. Configure here.

@k-yoshimi k-yoshimi merged commit cb667f2 into develop May 18, 2026
4 checks passed
@k-yoshimi k-yoshimi deleted the chore/l7b-ii-phase-2a-unified-stubs branch May 27, 2026 22:04
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.

1 participant