# -*- coding: utf-8 -*-
#
# michael a.g. aïvázis <michael.aivazis@para-sim.com>
# (c) 1998-2026 all rights reserved
#

- gate for 1.13.0 (collected 2026-07-31, so nothing important slips):

  - watch the first CI runs that exercise the tensor suite under cmake: the {HAVE_TENSOR}
    gate defaulted OFF, so those legs have never run before this branch

  - writer value binding: how producers attach numeric payload sources to schema datasets;
    the still-open half of the writer, and the proof that the mosaic design carries its
    weight; producers deposit through mosaics, {Writer} flushes

  - the nisar sandbox (examples/h5/nisar) is its own mm project, so its tests are invisible
    to pyre's test aggregate and to CI; all five drivers pass against the reworked value
    model today, but only when run by hand; decide its home (example, fixture, or its own
    repository) during the value-binding work

  - densify: hand a mosaic window to consumers as a single contiguous block; cheap atop
    {fill}, and wants its HOWTO use case

  - pull model: auto-{fill} on touching a non-resident page; a policy decision, nearly free
    now that mosaics carry backing-store hooks

  - qed: adopt {pyre::py::grid} and the h5 mosaics; the NISAR out-of-core viewer is the
    motivating consumer

  - the h5.lib and h5.ext test suites are still absent from cmake; the pkg suite runs there
    [project_cmake_enable_h5_tests]

  - symmetric/diagonal packings: decide whether they ever get python exposure

- calc:

  - calc nodes cannot inherit from {Ordering} because {Observable} stores the callbacks in a
    weak key dictionary, which is incompatible with an overloaded __eq__

- externals:

  - versions: there is no vocabulary for version requirements; a consumer cannot say
    "hdf5 >= 1.12"; recipes need a version extractor and the resolver a constraint check,
    built on the algebra of {pyre.constraints}

  - producer manifests: a package built by pyre should publish a description of itself, its
    facilities, and their dependency edges into its own prefix at install time, e.g.
    {share/pyre/external.yaml}, loaded into the configuration store as one more priority
    tier between discovery and user; this is the mechanism the mm externals-facilities
    design calls for, and the path to conditional facility libraries

  - recipes: knowledge still not ported from mm: the hdf5 parallel variants and their induced
    mpi dependence, and the nonstandard layouts of cuda and mkl

  - macports: the selection normalization machinery was dropped in the rewrite; revisit if
    resolving launchers or interpreters through the select file indirection ever becomes
    necessary

- gsl:

  - the bindings emit "parameter passing for argument of type {std::pair<double, double>}
    when C++17 is enabled changed to match C++14 in GCC 10.1" at {Histogram.cc:231},
    {Matrix.cc:322}, and {Vector.cc:317}, on aarch64 under gcc; this is the psABI note about
    gcc's own C++17 calling convention repair for pairs, not a defect in the code, and it
    matters only when linking against objects built by gcc older than 10.1 in C++17 mode;
    decide whether to restructure the signatures to avoid passing pairs by value, or to
    silence the note with {-Wno-psabi} for the bindings

- ci:

  - switch all the workflows to pure package discovery: the {pr-fedora} leg proved the
    pattern, but the ubuntu legs still hand-write every package location in
    {.github/matrix/config.mm}; with {pkgdb: dpkg} and the discovery machinery now
    exercised on three database families, the crib sheet should retire, and with it a
    whole class of silent staleness

- tests:

  - move the C++ test drivers to Catch2: 242 drivers in {journal.lib}, {pyre.lib}, {h5.lib},
    {mpi.lib}, {chroma.lib}, and {cuda.lib} check their results with 1092 {assert}s, which a
    build that defines {NDEBUG} compiles away; mm keeps them live in every mode since mm#66,
    by compiling test drivers with {DEBUG}, and the cmake build does the same for its test
    targets in every configuration, but that is a workaround: Catch2's {REQUIRE} and
    {CHECK} do not depend on the build mode, report what failed, and stay silent on success.
    mm already supports it: {<suite>.runner := catch2} compiles a suite into one binary, with
    {extern := catch2}; see {examples/step09} in the mm repository. Catch2 v3, which the
    runner needs, ships with ubuntu 25.10 and later, debian trixie, conda, and macports, so
    the CI images need checking before a suite switches. Migrate suite by suite, keeping a
    driver's single behavior as a single Catch2 test case

- docker:

  - stand up a postgres server in the rolling cell, maybe others, maybe all of them, so the
    {pyre.db} and {pyre-postgres} test suites can run against a live database; needs a chat
    about scope: which cells, socket vs tcp, and whether the server rides the image or a
    sibling container; the suites themselves are in good shape, and were run against a live
    18.4 server on 2026-08-02: all seven of {postgres.lib} and all thirteen of {postgres.ext}
    pass under cmake, and both suites pass under mm; what is missing is only a server in ci,
    where the cmake legs never see one and the mm legs never see {libpq} at all, so
    {.mm/pyre-postgres.mm} skips the project outright; a github actions {services:} container
    would cover the workflows on the same errand

  - teach the cmake side the trick mm already knows: {.mm/pyre-postgres.mm} sets
    {postgres.live} from {pg_isready} and excludes the drivers only when no server answers,
    so a developer with one gets the suites for free; the cmake build has no such detection
    and every workflow hard-excludes them with {ctest -E postgres}, which will keep skipping
    them even once a server is standing

  - {pyre::postgres} is exported and announced as a component, and {etc/cmake/consumer} has a
    driver for it, but the driver only runs where {libpq} is present, so it is still the
    least exercised of the exports; a ci runner carrying {libpq} would settle it

- merlin:

  - the docker cells mount the standalone {mm} checkout next to the pyre clone; the merlin
    {mm} layer bundled under {share/mm} should be capable of building pyre on its own, so
    the cells (and their mount contract) should not need {~/dv/mm}

  - {bin/mm} downloads the boot bundle into a new {tempfile.mkdtemp()} directory every time
    {pyre} is not importable, so its check for an existing copy never succeeds: every run
    downloads the bundle again and leaves a directory behind. The standalone {mm} keeps its
    copy in a {.mm} directory next to the script; {bin/mm} should keep one too, in a stable,
    per-release location such as the user's cache directory, so a second run reuses it

- framework:

  - take advantage of the new class creation protocol in 3.6+

  - have component+trait+schema participate in value resolution, not just schema

  - pyre.patterns.Named has to become a little more sophisticated with its name handling:

    - passing name=<foo> to the constructor must have an identical net effect as leaving it
      blank at construction time and setting it later

  - look for a better way to install escape handlers for the command line parser; does the
    actual parsing happen too early? how would i then bootstrap the framework without having to
    check its state every time something significant happens?

  - package names can be placed in their own namespace by auto prepending a special character
    to their name. which character? what is the current status?

  - what is the full set of options for allowing configuration changes past the initialization
    phase?

    - deal with this on a component by component basis?
    - flag the capability?
    - trap the events and redistribute?
    - is this a component attribute? or a trait decoration?

- configuration errors:

  - trap, collect, show on exit

  - is it part of {help}?

    - temporary invalid assignments that get later overridden by valid ones are not fatal
      errors; they could get reported by {help}

    - is the last valid assignment the one that wins? is it fatal if the last assignment
      violates a constraint or do I fall back? how does the user control this behavior?

- traits:

  - treat them like components; some are: input and output streams have both configuration and
    initialization phases; the latter grabs the system resource and should be done after it's
    reasonably certain that the user has made up her mind about the name of the file. the goal
    is to not leave behind zero length output files that were created when some assignment was
    made that was later overridden by something else

  - same considerations apply to components themselves; formalize the sequence of
    startup/shutdown steps

- filesystem:

  - the factories in __init__ are kind of ugly. fix

  - sync should not be done by default, especially now that it supports the number of levels to
    expand; this should speed up {import pyre} in directories with deep structures. this means
    that i need to hunt down all uses of filesystems and make sure the clients sync before they
    look things up. also, folders need to know how to cause their filesystems to fill out their
    contents, which means adding a {sync} method that dispatches to the filesystem with
    root=self

  - implement http

  - transport mechanisms: wget/curl, ftp, scp, rsync, ...

  - can i build one dynamically? create a folder and start adding files?

    - how do i know that a filesystem node is a "future" one?

- history tracking:

  - must trace all the paths that assign values to slots and make sure that locator/priority
    are saved in _history

  - install a tracker as a command line event handler; make it save the names of the traits to
    track; make it print out a report of the history of tracked traits at shutdown

  - should this be part of {help}? see below

- journal:

- weaver:

  - i want my own rst, and my own sphinx...

- help: make

  - component Inspector

    - how does python help work? who/how generates the formatted output?

    - inspect:
      properties, facilities: doc, tip, current value, default value, history?
      interface: doc, arg list, annotations, return value

    - make sure inline documentation is always sufficient for Inspector to work

    - use in opal and fold into the UI for Forms

- db:

  - db Query and View as Components

    ? not sure what i meant with this. records, sheets and views are now closer to this

- opal: make

  - Form as Component

- merlin:

  - while i am dreaming: i want my own coverage tool...

- tabular:

  - give records some of the aggregator capabilities that tables have so that streams of data
    with no associated storage can be binned; of course, no storage implies that the charts
    must immediately update some reduction, since no ranks or references to the data should be
    retained. what effect should this have on the design/implementation of Sheet, Chart and
    Pivot?

  - sheet inheritance is "broken" because derived classes rearrange the order of measures and
    derivations. this means that instances of a class are not compatible with instances of its
    direct ancestor, even in single inheritance

  - resolve the uri argument to cvs.read through the pyre fileserver

  - indexed columns must support iteration over their contents, like non-indexed ones. should
    they iterate in record order? or is any order ok?

  - take advantage of change notifications: should a record know that one of its values
    changed? should a sheet know that one of its values changed

  - allow the creation of records over multiple sessions

  - allow the deletion of records; rethink this from a {calc} viewpoint: what does it mean for
    a {calc} node to disappear? aggregators can drop it from their domain; others may raise
    UnresolvedNode, or some such...

  - views

  - pivots

    - {chart}: related to {SELECT} and {GROUP BY} from SQL: given a table, a chart can
      answer quickly questions like "produce the set of records that have <measure>=<value>", or
      even "<measure> in the neighborhood of <value>" by controlling the binning strategy

    - implement using {chart}, i.e. the binning strategy that specifies the dimensions, and
      a {cell}, i.e. the description of what operation to perform on the data slice that
      corresponds to each fully qualified coordinate vector

    - CHANGE notification: rebin a record when the matching value changed, just like an
      aggregation gets recomputed when one of the factors changes

- function overload: revisit

  - use function annotations instead of explicit signatures in the decorator

  - can the full set of funcdecls be supported?

    - positional args, positionals with defaults, keyword only, keyword only with defaults
    - what to register
    - what to cache
    - who shadows whom? what's ambiguous?
    - how to retrieve a matching signature quickly

  - is it worth the hassle and performance penalty?

  - overload on precondition a la Ebby?

- shells:

  - let "pyre" be the hosting script:

    - hosting options are command line options to this script

    - the application is specified as the directory appname.pyre

    - pyre looks inside for geometry and dynamics

  - can the reconfiguration of a component get triggered after the application has started? the
    use case here is manipulating the journal channels for long-running apps: can i turn on
    channels after launch?


- workstreams harvested from project memory (2026-07-16):

  these are concrete in-flight and planned efforts, distinct from the perennial
  design notes above; each names its memory slug under
  ~/.claude/projects/-Users-mga-dv-pyre/memory/ for the full note

  - not yet started:

    - re-evaluate the {RTLD_GLOBAL} tweak in packages/mpi/__init__.py: it works around
      openmpi plugins unresolved against libmpi, last checked in 2012 against openmpi
      1.4.3; it is linux-only, flips the dlopen flags for every subsequent extension
      import in the process, and interacts with the cross-module type isolation the
      pybind extensions now assume; check whether modern openmpi still needs it

    - cuda pybind11 migration: extensions/cuda is the last raw-CPython/capsule
      extension; bindings-only convert, but needs a Linux CUDA container to
      build and test (no CUDA on macOS). sequence: clean up etc/docker, build a
      cuda dev container, then migrate. [project_cuda_pybind11_migration,
      project_h5_own_subproject]

    - GraphQL in pyre.db: after libpq PR #191 merges, (1) a parameterized SELECT
      compiler as its own PR, then (2) a graphql-core schema/resolver generator
      to replace graphene, built against a resolver protocol. [project_pyre_db_graphql]

    - conda PackageManager for pyre.platforms: pyre.externals can't register
      conda-provided packages, blocking the mpi tests in conda CI; reuse mm's
      --pkgdb=conda design. no branch yet. [wip_platforms_conda_packager]

    - iq_t cell type: replace the std::complex<uint16> lie for NISAR IQ ADC pairs
      with a pyre iq_t POD + datatype/memtype; cross-repo, pyre moves first.
      not started. [project_iq_cell_type]

    - h5 dataspace/grid interop: make DataSpace/DataSet interoperate with
      pyre::grid concepts; folds in the deferred DataSpace sameExtent().
      deferred to a fresh session. [project_h5_dataspace_grid_interop]

    - format branch: after survey PR #187 merges, one sweep of clang-format on
      all C++ + black on all Python to kill formatting noise; skip meta.py.in.
      [project_format_branch_plan]

    - enable h5 tests in cmake: the cmake build never runs the h5 tests (mm
      does); add the HDF5-gated lib/pkg test entries so cmake CI covers h5.
      [project_cmake_enable_h5_tests]

    - clang-format 22 new options: demo what concepts/RemoveParentheses/
      QualifierAlignment/... do on pyre C++ before adopting. [project_clang_format_new_options]

    - dpkg sniffer audit: mm's dpkg discovery was never tested end to end; 3 bugs
      already found (hdf5/mpi/libpq); audit all 29 supported externals in a
      container. [project_dpkg_sniffer_audit]

  - active branches (in flight):

    - chroma: header-only pyre::chroma color+ANSI library; phases 1-5 done and
      verified. NEXT phase 6 (consolidate terminal detection across shells,
      journal, survey), then 7 (shells+survey) and 8 (cleanup). [project_chroma_color_truth]

    - survey (PR #187): stdlib prompt package; next, refactor into pyre
      components toward interactive component configuration. pivoted to build
      chroma first as the foundation. [wip_branch_survey]

    - boot: runnable pyre-boot.zip app that fetches matching source and drives an
      embedded mm; verified working. open: head-build drift, build target/verify.
      [wip_branch_boot]

    - libpq: modern header-only pyre::postgres over libpq + pybind11 bindings +
      reworked pyre.db; 3 commits verified against a live pg18. NEXT: open the
      PR; CI needs a live server (ties into the conda packager above). [wip_branch_libpq]

    - p2: python modernization (f-strings, __slots__, new algebraic/ package,
      NameLookup tracker). [wip_branch_p2]

    - tensor: quaternions, rows()/columns() matrix builders, generalized
      tensor_same_shape_c (Bianca Giovanardi's code). [wip_branch_tensor]

  - deferred / revisit:

    - timers PR: Movement::lap is unimplemented, suspicious type aliases, unclear
      Movement::reset return type; fix in a dedicated timers PR. [project_timers_revisit]

    - self_type/super_type retro pass: still owed for grid, memory, timers.
      [feedback_self_super_type_aliases]

    - header self-containment: done for grid/memory/timers/journal; LEFT are
      tensor, flow, viz, geometry. [project_header_self_containment]

    - component trait vs package name: a trait named like an imported package
      resolves to the Package; wants a separate namespace for component
      instances. [project_component_trait_global_scope]

    - python version floor: pyproject floor is stale vs CI (3.12-3.14); policy
      decision deferred by user. [project_python_version_floor]

    - journal<->pyre boot coupling: design A (relocate root to a boot-free
      foundation) vs design B (lazy pyre boot) still undecided; do not raise
      unprompted. [project_journal_pyre_boot_solutions]

    - binding import guard: re-examine remaining from-import guard sites with the
      ModuleNotFoundError-vs-ImportError lesson in mind before sweeping.
      [project_narrow_binding_import_guard]

  - open follow-ups from merged work:

    - docker matrix open items: libpq in CI, dpkg-sniffer audit (above), a cuda
      cell. [wip_branch_docker]

    - pyre docker containers: roll the reusable mm-driven container design out to
      qed/qef/speak/pet. [project_pyre_docker_containers]

  - cross-repo (lives in ~/dv/mm, tracked in mm's own TODO.md):

    - external facilities: let a supported external expose a family of
      conditionally-built libraries so clients request a subset; driving case is
      pyre shipping libpyre-h5/mpi/postgres/... design agreed, not implemented.
      see ~/dv/mm/docs/externals-facilities-design.md

    - mpi launcher vocabulary: move the launcher vocabulary into mm's extern/mpi
      (mpi.launch); pyre is only the consumer, and share/mm/make must mirror it.
      [wip_branch_mpi, project_mpi_cpp_layer]


# end of file
