Skip to main content

NORP-Core

A pure, domain-neutral meta-framework kernel.

NORP-Core is a minimal kernel for assembling software out of pluggable parts. It assumes no upper-layer implementation and no particular domain: it is the four non-replaceable components plus the registration triad and the machinery they need. Any program - a service, a CLI, a game loop, a compiler, a build tool

  • can build on it and declare its own slots, hook layers, event vocabulary and component kinds.

The direction of dependency is strictly one-way:

        host / application   (any concrete software)
                  |
                  v
              NORP-Core
                  |
                  v
          Python standard library

NORP-Core never imports an upper layer.

The kernel

Exactly four non-replaceable components, plus supporting machinery:

# Component Module Responsibility
1 Slot connector norp_core.layer.ArchLayer assemble slot values into implementations, hot-mount
2 Address resolver norp_core.address.resolve_address turn an address string into an object
3 Registry norp_core.registry.Registry generic kind -> name -> object store
4 Event bus norp_core.events.EventBus the only decoupling point

Supporting machinery:

  • norp_core.slots - the slot table (mechanism only; ships no slots);
  • norp_core.hooks - the hook mechanism (HookSystem / HookLayer / Hook / BoundHook; ships no standard hook layers);
  • the registration triad register_slot / register_layer / register_hook.

Domain neutrality

The kernel understands only generic software concepts - a slot, a hook, an event, an address, a layer, a registry. It contains no domain vocabulary and no baked-in assumption about what is being assembled:

Guarantee How
no fixed event vocabulary event names are free-form strings chosen by the host
no pre-defined slots SLOT_SPECS starts empty; the host calls register_slot
no standard hook layers HookSystem.standard_layers() returns []
no assumed component kinds Registry is generic kind -> name -> object
no special slot names baked in string passthrough is opt-in via register_passthrough_slot
no special dict-value handling callables in dict values are controlled per-slot by SlotSpec.call_dict_factories
no host concept of its own Registry.extras is an opaque host extension point the kernel never inspects

An upper layer that wants any of the above simply declares it:

# a host declares its own slots (the kernel ships none)
core.register_slot(core.SlotSpec(
    name="storage",
    description="where data is persisted",
    protocol="StorageProtocol",
    string_semantics="name_or_address",
    call_dict_factories=False,      # this slot's dict values are callbacks
), builtin=True)

# a host declares its own hook layers
core.register_layer(name="net", order=100,
                    hooks={"before_request": {"mutating": True}})

# a host declares its own event topics just by emitting them
bus.emit("before_request", url="...")

Layout

core/
  pyproject.toml          # distribution: norpcore (import name norp_core)
  README.md               # this file
  LICENSE                 # MIT
  publish_pypi.ps1        # build + PyPI publish helper (PowerShell, primary)
  release.ps1             # build + PyPI publish helper (PowerShell, legacy)
  release.py              # build + PyPI publish helper (Python, legacy)
  .gitignore
  norp_core/
    __init__.py           # the whole public surface
    py.typed              # PEP 561 typing marker
    events.py             # component 4: EventBus / Event / HookVeto
    registry.py           # component 3: Registry / ComponentError
    address.py            # component 2: resolve_address / is_address_like / AddressError
    layer.py              # component 1: ArchLayer / call_factory / register_passthrough_slot
    slots.py              # slot table mechanism (no built-in slots)
    hooks.py              # hook mechanism + register_layer / register_hook
  tests/
    test_norp_core.py     # functional tests for all four components + triad
    test_purity.py        # import-graph purity: NORP-Core leaks no upper layer

Quick start

import norp_core as core

# 1. declare slots (NORP-Core ships none)
core.register_slot(core.SlotSpec(
    name="service",
    description="a pluggable service",
    protocol="ServiceProtocol",
    string_semantics="name_or_address",
))

# 2. register components by kind (kinds are chosen by the host)
reg = core.Registry()
reg.register("service", "mock", lambda: MyMockService())

# 3. assemble
layer = core.ArchLayer(service="mock")
layer.set_default("service", lambda ctx: reg.build("service", "mock"))
layer.connect()
svc = layer["service"]

# 4. wire the hooks / event bus
system = core.HookSystem(reg.bus)
core.register_layer(name="L1", hooks={"before_start": {"mutating": True}},
                    system=system)
core.register_hook("before_start", my_guard, system=system)

Testing

cd core
python tests/test_norp_core.py     # functional
python tests/test_purity.py        # purity (no upper-layer imports)
# or, with pytest installed:
pytest -q

test_purity.py launches a fresh interpreter, imports norp_core, and asserts that no top-level module of an upper layer appears in sys.modules, and that every newly imported module is either the standard library or norp_core itself. It also statically scans the sources so a lazy import cannot sneak in.

Releasing

The distribution name is norpcore (the import name stays norp_core).

publish_pypi.ps1 is the primary one-command build-and-publish helper. It:

  1. checks version consistency between pyproject.toml and norp_core/__init__.py;
  2. checks the Python / build / twine environment;
  3. removes stale dist/ artifacts of the SAME version;
  4. builds the sdist and wheel with python -m build;
  5. verifies the built wheel carries the declared version;
  6. validates the packages with twine check;
  7. resolves credentials, then uploads to the chosen index.

PowerShell

pip install -e ".[release]"                    # build + twine

.\publish_pypi.ps1 -CheckOnly                  # build + validate, no upload
.\publish_pypi.ps1 -DryRun                     # preview the upload command
.\publish_pypi.ps1 -Target testpypi -Token "pypi-xxxxxxxx"
.\publish_pypi.ps1 -Target pypi     -Token "pypi-xxxxxxxx" -Force

Pass the publish token straight in with -Token to customise the credential for a single run; if -Token is omitted the script reads PYPI_TOKEN / TESTPYPI_TOKEN / TWINE_PASSWORD and finally falls back to ~/.pypirc, or prompts for a masked token. The token is never written to disk or echoed.

Other flags: -SkipBuild, -SkipExisting, -Force (skip the confirmation). If Windows blocks the script, run it with powershell -ExecutionPolicy Bypass -File .\publish_pypi.ps1 ....

Legacy helpers

release.ps1 and release.py are the earlier equivalent helpers (test suite + clean + build + twine check + optional upload). Credentials there are read from PYPI_API_TOKEN / TESTPYPI_API_TOKEN or ~/.pypirc:

.\release.ps1 -BuildOnly
.\release.ps1 -Target pypi -Token "pypi-xxxxxxxx" -Yes
python release.py --build-only
python release.py --target pypi

The distribution is licensed under the MIT License — see LICENSE.

Metadata

Release files for norpcore 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for norpcore 0.1.0
File Size Uploaded Provenance Actions
norpcore-0.1.0.tar.gz 30.0 kB Without provenance Details for norpcore-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for norpcore 0.1.0
File Interpreter ABI Platform Actions
norpcore-0.1.0-py3-none-any.whl Python 3 none any Details for norpcore-0.1.0-py3-none-any.whl

Total release size: 56.8 kB

Release files / norpcore-0.1.0.tar.gz

Download URL norpcore-0.1.0.tar.gz
Size 30.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b635f2978dd01025e6f6636417451f0a7fabfb75bdac65ec5290be4244255cdf
BLAKE2b-256 checksum
How to use checksums
d1decb48252a4c4cdff24200f1d201d644a8ce2902f8801de211a1a23f949db7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / norpcore-0.1.0-py3-none-any.whl

Download URL norpcore-0.1.0-py3-none-any.whl
Size 26.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5bc6e77919996a72828a2728bcc4aac3567f4b714664129bde6c1530a5863981
BLAKE2b-256 checksum
How to use checksums
6fcaa8db3bb6d9bfda40b2ce257296032067485f152ccaf84722b2b3d640fbc4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for norpcore 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page