Posterior Memory Harness
A model- and framework-neutral memory middleware for agents that preserves uncertain local observations and reconciles them with global relation constraints before each model call.
This package is a reusable implementation of the central mechanism studied in the PosteriorGlue experiments. It is not another vector database and it does not replace semantic retrieval. Use it beside a conventional memory system when several observations describe related checkpoints, entities, plans, tool states, or world states and their composition law matters.
Why this memory is different
Most agent memory pipelines commit early:
- an extractor emits one label or one summary;
- the label is stored as fact;
- retrieval ranks snippets independently;
- contradictions are left for the LLM to notice.
This harness instead stores the complete local posterior (q_{uv}(r\mid x)), its local class prior (\mu_{uv}(r)), time validity, provenance, evidence-family fallback, and explicit source lineage. At query time it builds the factor
[ \ell_{uv}(r)\propto q_{uv}(r\mid x)/\mu_{uv}(r) ]
and infers globally compatible node states under a registered finite relation law. The output is a small structured memory capsule containing ranked beliefs, conflicts, and the exact observation IDs used.
The distinction is useful when:
- the locally correct state often remains in the top two or three candidates;
- cycles or redundant observations can resolve local ambiguity;
- relation order is meaningful;
- stale information and corrections must support as-of queries;
- compaction or repeated retrieval could otherwise count one source twice.
What is included
- In-memory and persistent SQLite stores.
- Versioned SQLite schema adoption with an append-only migration history.
- Append-only observations with validity windows and timed revocation.
- Explicit local-prior correction.
- Cross-family evidence-lineage deduplication; only the latest active representative of one underlying source event counts.
- A non-blocking prior-only capsule when a new Agent has no observations yet.
- Seed-based bounded subgraph discovery, so callers need not know every related memory node in advance.
- Matched-budget
recent,coverage, andcycle_awareretrieval policies. - Structural retrieval diagnostics including connected components, cycle rank, covered-node fraction, and informative cycle-factor mass.
- A registry for custom finite relation laws.
- Built-in cyclic groups and the noncommutative (S_3) law.
- Exhaustive exact inference for small graphs.
- Deterministic beam inference for larger graphs.
- A dual-width beam stability diagnostic with MAP, marginal-TV, and entropy checks; the wider run supplies the returned approximation.
- Durable delayed-label calibration and prediction-drift monitoring, with hash-locked reference windows and pre-specified guards.
- Atomic observation/prediction commits and append-only outcome corrections.
- Restart-safe monitor replay, knowledge-time
as_ofreports, and journal integrity verification. - A compact target-specific
memory_decisionprojection for models that cannot reliably locate one action inside the full audit capsule. - Node priors, tag/namespace isolation, trust tempering, and hard-top-1 control.
- A framework-neutral before-model/after-event middleware.
- A versioned, strict JSON input contract and a SQLite-backed command-line interface.
- Structured capsules with no free-form instruction field.
Install
From this directory:
python -m pip install .
For development:
python -m pip install -e .
python -m unittest discover -s tests -v
The only runtime dependency is NumPy. Python 3.10 or newer is required.
The release has four independent version axes:
| Contract | Current version |
|---|---|
| Python package | 0.9.0 |
| SQLite schema | 3 |
| observation/query/outcome JSON input | 2 (legacy 1 accepted) |
| calibration-monitor report | 2 |
The JSON schemas are included both in the source tree and in the installed
package under posterior_memory_harness/schemas/.
Release bundles are built from an explicit allowlist, use one safe top-level directory, include a per-file SHA-256 manifest, and exclude local models, databases, caches, and prior build outputs:
python tools/build_release.py `
--wheel dist/posterior_memory_harness-0.9.0-py3-none-any.whl
Minimal Python integration
from posterior_memory_harness import (
MemoryMiddleware,
PosteriorMemoryHarness,
SQLiteMemoryStore,
cyclic_law,
)
from posterior_memory_harness.middleware import StructuredObservationEncoder
harness = PosteriorMemoryHarness(SQLiteMemoryStore("agent_memory.sqlite"))
harness.register_relation("task-phase", cyclic_law(4))
middleware = MemoryMiddleware(harness, StructuredObservationEncoder())
harness.observe_payload({
"schema_version": 2,
"observation_id": "tracker:7",
"namespace": "run-42",
"relation_type": "task-phase",
"source": "start",
"target": "after-build",
"posterior": {"0": 0.02, "1": 0.92, "2": 0.04, "3": 0.02},
"prior": {"0": 0.25, "1": 0.25, "2": 0.25, "3": 0.25},
"evidence_family": "raw-tool-call:7",
"source_event_id": "tool-event:7",
"lineage_root_id": "tool-event:7",
"derived_from": [],
"encoder_revision": "verified-tool-parser:v1",
"calibration_revision": "tool-deterministic:v1",
"observed_at": 100.0,
"valid_from": 100.0,
"provenance": {"tool": "build-tracker", "event": "7"},
"tags": ["project-x"],
})
request = middleware.before_model(
{"messages": [{"role": "user", "content": "What should I do next?"}]},
{
"schema_version": 2,
"namespace": "run-42",
"relation_type": "task-phase",
"seeds": ["start"],
"root": "start",
"as_of": 101.0,
"tags": ["project-x"],
"max_hops": 2,
"max_nodes": 16,
"max_observations": 32,
"retrieval_policy": "cycle_aware",
},
)
# Pass request to any model/framework. It now contains `memory_capsule`.
A runnable version is in
examples/generic_agent_loop.py.
Explicit and discovered queries
An explicit query supplies "nodes" and is useful for locked evaluations or
when the surrounding application already owns the graph. A discovered query
supplies "seeds" instead:
{
"schema_version": 2,
"namespace": "agent-run-42",
"relation_type": "task-phase",
"seeds": ["current-checkpoint"],
"root": "current-checkpoint",
"as_of": 101,
"max_hops": 2,
"max_nodes": 32,
"max_observations": 512,
"retrieval_policy": "cycle_aware"
}
The store discovers only active, tag-matching, independent observations
reachable within max_hops. It first keeps the latest active observation in
each explicit lineage root (falling back to source_event_id, then
evidence_family) and then applies deterministic node and observation
budgets. coverage preserves an information-ranked rooted spanning forest;
cycle_aware fills the remaining matched budget with informative
cycle-closing factors. SQLite performs reachability with a recursive CTE after
time, tag, revocation, and lineage filtering.
Every capsule includes retrieval metadata:
{
"retrieval": {
"mode": "neighborhood",
"seed_nodes": ["current-checkpoint"],
"hops_explored": 2,
"node_limit_hit": false,
"observation_limit_hit": false,
"truncated": false,
"policy": "cycle_aware",
"selected_observation_count": 5,
"independent_lineage_count": 5,
"connected_components": 1,
"cycle_rank": 2,
"covered_node_fraction": 1.0,
"factor_information_score": 0.60,
"cycle_information_score": 0.23
}
}
The two information scores are deterministic selection diagnostics derived from posterior-versus-prior Jensen--Shannon change, ambiguity, and trust. They are not proper predictive scores and must not be compared across unrelated relation laws.
Approximate queries also include an inference diagnostic. By default the harness compares beam widths (B) and (2B), returns the wider result, and reports MAP agreement, maximum node-marginal total variation, and maximum entropy change:
{
"inference_diagnostics": {
"mode": "dual-width-beam",
"stable": true,
"base_beam_size": 1024,
"comparison_beam_size": 2048,
"map_agreement": true,
"max_marginal_tv": 0.004,
"max_entropy_delta": 0.009,
"marginal_tv_tolerance": 0.02,
"entropy_tolerance": 0.05
}
}
This is a budget-sensitivity diagnostic, not a proof of distance to the exact posterior. A false result should trigger a wider beam, a smaller retrieved subgraph, or exact inference where feasible.
The two modes are mutually exclusive. Supplying both nodes and seeds, or
neither, is rejected.
Agent lifecycle contract
The integration surface deliberately uses plain mappings:
| Lifecycle point | Harness operation | Purpose |
|---|---|---|
| after tool | after_tool / after_event |
store calibrated tool evidence |
| after model | after_model |
store extractor output when appropriate |
| before model | before_model |
attach a reconciled memory capsule |
| compaction | on_compaction |
store derived summaries as non-independent |
| memory-evidence correction | revoke plus a new observation |
preserve evidence history |
An observation encoder is an adapter boundary. It may be a calibrated classifier, an LLM structured-output extractor, or a verified tool parser. The harness never assumes a particular LLM vendor, chat message format, agent loop, or vector store.
Compaction outputs must use "independent_evidence": false unless they contain
new independent evidence. Otherwise the summary and its source observations
would be counted twice.
This lifecycle row concerns correcting stored memory evidence. Correcting a
delayed calibration label instead uses correct_outcome(...), which appends a
superseding outcome event without revoking the observation.
Relation semantics
For node states (z_u,z_v), an edge observation describes (r_{uv}=z_u^{-1}z_v). Register a law whose labels have a closed, associative composition table, identity, and inverses:
from posterior_memory_harness import FiniteRelationLaw
law = FiniteRelationLaw.from_dict({
"name": "my-law",
"labels": ["..."],
"table": [[...]],
"inverse": [...],
"identity": 0,
})
harness.register_relation("my-relation", law)
The constructor exhaustively validates the finite law. Noncommutative laws are supported; reversing the multiplication order is not treated as equivalent.
One node in each query is fixed to the identity as a gauge root. The returned beliefs are therefore relative to that root, not absolute real-world claims.
CLI
The CLI accepts observation and query JSON matching
schemas/observation.schema.json and
schemas/query.schema.json:
posterior-memory --db memory.sqlite --relation-type task-phase `
--law cyclic:4 observe examples/observation.json
posterior-memory --db memory.sqlite --relation-type task-phase `
--law cyclic:4 query examples/query.json
posterior-memory --db memory.sqlite revoke tracker:7 --at 120
posterior-memory --db memory.sqlite --relation-type task-phase `
--law cyclic:4 decision examples/query.json --focus-node after-build
posterior-memory --db memory.sqlite --relation-type task-phase `
--law cyclic:4 outcome examples/outcome.json
posterior-memory --db memory.sqlite health --namespace agent-run-42
posterior-memory --db memory.sqlite verify
Use --law s3 for the built-in noncommutative law or pass a finite-law JSON
file. observe, query, decision, and outcome require a law;
health, verify, and revoke do not. If a JSON payload already contains
relation_type, it must match the CLI value—the CLI never silently overwrites
a conflicting relation.
query and decision do not create a durable relation-law registration. They
accept an empty database for a prior-only answer, but fail closed if matching
observations exist without a previously bound database-global law. Normal
observe and Python register_relation(...) paths perform that binding.
An outcome file follows
schemas/outcome.schema.json:
{
"schema_version": 2,
"observation_id": "tracker:7",
"true_relation": "1",
"outcome_event_id": "verified:tracker:7:v1",
"labeled_at": 120.0
}
To correct a verified label, append a second event instead of editing the first:
{
"schema_version": 2,
"observation_id": "tracker:7",
"true_relation": "2",
"outcome_event_id": "verified:tracker:7:v2",
"labeled_at": 120.0,
"correction_reason": "human adjudication"
}
To use non-default monitor guards, provide them on the first observe for a
new run:
posterior-memory --db memory.sqlite --monitor-run production-v1 `
--monitor-config examples/monitor_config.json --relation-type task-phase `
--law cyclic:4 observe examples/observation.json
Later commands use --monitor-run production-v1 and reload the locked config
from SQLite. health fails if the requested run does not yet exist; it never
creates or silently configures a monitor. Stable observation/outcome event IDs
should be derived from the source event so crash retries are detectable.
CLI exit codes are stable and machine-readable:
| Code | Meaning |
|---|---|
| 0 | success |
| 1 | unexpected internal failure |
| 2 | invalid input or payload |
| 3 | incompatible schema or failed integrity verification |
| 4 | durable state/idempotency conflict |
Strict adapter input contract
Agent adapters are untrusted JSON boundaries. Payloads are validated before
any coercion or storage. Add "schema_version": 2 to use lineage and
structure-aware retrieval fields. Version 1 remains accepted for backwards
compatibility and defaults to recency retrieval; omitted versions are
interpreted as version 1. Unknown future versions are rejected.
Unknown fields, string booleans, boolean probabilities, non-finite numbers,
duplicate identifiers, oversized relation supports, out-of-query node priors,
and non-JSON provenance are rejected. Hard resource limits cover identifier
length, tag count, provenance bytes/depth, query nodes, hops, and observation
budgets. evidence_family remains mandatory. A v2 adapter should additionally
set lineage_root_id from the original source event whenever the same evidence
can appear through different parsers, model echoes, or summaries.
See STRICT_INPUT_BEAM_STABILITY_ZH.md
for the exact limits and stability semantics.
Calibration and drift monitoring
The monitor evaluates the local posterior interface without changing stored
evidence or refitting online. With SQLiteMemoryStore, its configuration,
prediction snapshots, label order, relation-law fingerprint, and outcome
events are durable:
from posterior_memory_harness import (
CalibrationDriftMonitor,
MonitorConfig,
PosteriorMemoryHarness,
SQLiteMemoryStore,
cyclic_law,
)
monitor = CalibrationDriftMonitor(MonitorConfig(
reference_size=200,
current_size=100,
min_current_size=30,
run_id="production-v1",
))
harness = PosteriorMemoryHarness(
SQLiteMemoryStore("agent_memory.sqlite"),
monitor=monitor,
).register_relation("task-phase", cyclic_law(4))
# The monitor must be bound before this independent observation is stored.
harness.observe_payload({
"schema_version": 2,
"observation_id": "tracker:7",
"namespace": "run-42",
"relation_type": "task-phase",
"source": "start",
"target": "after-build",
"posterior": [0.02, 0.92, 0.04, 0.02],
"prior": [0.25, 0.25, 0.25, 0.25],
"evidence_family": "raw-tool-call:7",
"source_event_id": "tool-event:7",
"lineage_root_id": "tool-event:7",
"observed_at": 100.0,
})
# After the environment, a verified tool, or a human supplies delayed truth:
harness.record_outcome(
"tracker:7",
"1",
outcome_event_id="verified:tracker:7:v1",
)
health = harness.calibration_report(namespace="run-42")
# A correction is a new immutable event; it never overwrites v1.
harness.correct_outcome(
"tracker:7",
"2",
reason="human adjudication",
outcome_event_id="verified:tracker:7:v2",
)
Reports are segmented by relation law and observation source family. They
contain accuracy, NLL, Brier, ECE, top-2 coverage, confidence, entropy,
reference/current deltas, prediction-marginal Jensen--Shannon divergence, and
machine-readable alerts. Insufficiently labeled windows are reported as
insufficient_data, never healthy.
For durable runs, MonitorConfig is canonicalized and SHA-256 locked by
run_id; reopening the same run with changed thresholds fails closed.
as_of reports include only predictions and outcome/correction events already
known by that cutoff. The monitor never applies an automatic calibration
update and its report is not inserted into model prompts. Thresholds should be
frozen before an audit.
See
CALIBRATION_DRIFT_MONITOR_ZH.md.
Target-specific decision projection
The full capsule is the audit record, but small language models may fail to locate one target belief inside it. Project a focus node without recomputing or re-ranking the posterior:
request = middleware.before_model(
{"messages": messages},
memory_query,
focus_node="checkpoint_4",
alternatives=2,
)
The attached memory_capsule is then a compact memory_decision with
highest_probability_state, probability, alternatives, evidence/conflict
counts, and inference stability. It retains an empty instruction channel.
SQLite schema lifecycle
Every SQLite database records PRAGMA user_version and an append-only
memory_schema_migrations history. Explicitly migrate it without loading a
relation law:
posterior-memory-schema --db memory.sqlite migrate
Check an existing database without migrating or creating it:
posterior-memory-schema --db memory.sqlite check
Schema v2 introduced five locked registry/journal tables: database-global
relation_laws,
monitor_runs, per-run monitor_laws, monitor_predictions, and
monitor_outcomes. Those five tables and memory_schema_migrations are
protected by database triggers against update/delete; root and
superseding-event uniqueness prevents correction forks. Changing run_id
cannot bypass the database-global relation-law binding. Before legacy
adoption, migration verifies every required observation column and the
observation_id primary key. Existing rows and additional application columns
are preserved. A malformed legacy table fails without destructive
reconstruction, and a database created by a newer package version is refused
rather than silently downgraded. Schema v3 adds nullable source/lineage and
encoder/calibration revision columns plus a validated derived_from_json
array. Old rows retain evidence_family as their lineage fallback; their
posterior payloads are not rewritten.
Migration uses an immediate transaction and is idempotent under concurrent
initialization. The subsequent WAL-mode transition uses bounded
SQLITE_BUSY/SQLITE_LOCKED retry with a fresh connection and verifies that
SQLite actually selected WAL; this closes the separate cross-process lock
window after migration commits. For monitored observations, the observation
and its exact posterior snapshot commit in one transaction, so a crash cannot
expose half a monitor record. Observation inserts name every column explicitly,
so a compatible additive application column with a default does not shift
stored values. posterior-memory ... verify performs quick_check,
foreign-key, schema, journal-shape, and payload-hash checks without repairing
the file. See
SQLITE_SCHEMA_MIGRATION_ZH.md.
When a legacy database already contains observations, the first law binding fully decodes every matching row and checks that its posterior/prior support length matches the proposed labels. Equal support size cannot reveal historical composition semantics, so that first binding remains an operator attestation and should be made from the original deployment configuration.
Safety and accounting rules
- Memory data is emitted as typed evidence, never as executable instructions.
- Raw provenance is stored for audit but is not copied into the model capsule.
- Namespace and tags are enforced before the observation budget is applied.
- Neighborhood discovery applies time, tag, revocation, and independence filters before graph traversal.
- Queries can be evaluated at historical
as_oftimes. - Historical queries never retrieve observations from their future.
- Revocation is timed and does not erase the prior record.
- Verified outcomes are append-only; corrections explicitly supersede an earlier event and retain both records.
- Durable monitor thresholds, label order, and relation law are hash-locked.
- Historical monitor reports are cut off by knowledge time, so a later correction cannot leak into an earlier audit snapshot.
- Prior correction prevents a classifier's training prior from being counted again as observation likelihood.
- Lineage-root deduplication prevents different parser families, model echoes, summaries, or retries from multiplying one source event. Legacy rows fall back to evidence-family deduplication.
- Every
derived_fromparent must already exist in the same namespace and relation type. An independent echo must also retain its parent's lineage root and relation endpoints, making the ancestry acyclic by append order. - Compaction middleware forcibly marks summaries as derived evidence even if an encoder incorrectly labels them independent.
- A registered relation type cannot silently change its composition law.
- Existing SQLite observations cannot be queried under an unbound or support-size-incompatible relation law.
- Approximate outputs explicitly report the beam backend and
"approximate": true, plus a dual-width stability diagnostic by default.
This does not make untrusted memory harmless by itself. The surrounding agent must still authorize tools, isolate tenants, validate extractor schemas, and keep retrieved evidence separate from system/developer instructions.
Evidence from the controlled harness experiment
The accompanying controlled (S_3) checkpoint-graph experiment used 20 seeds and 200 episodes per seed. With mean local top-1 accuracy of 64.76%, full posterior reconciliation improved cycle-rich node accuracy from 65.59% to 94.45%, a paired gain of 28.86 percentage points with a 95% bootstrap interval of [27.89, 29.84]. Episode success rose from 34.28% to 88.33%.
The controls matter:
- wrong composition order: 66.53%;
- posterior-to-episode shuffle: 17.13%;
- oracle local factors: 100%;
- cycle-free accuracy gain: only 0.94 percentage points, although NLL and Brier still improved.
This supports a narrow conclusion: the mechanism can recover locally retained
probability mass when correct redundant constraints are present. It is not yet
evidence that every LLM agent will improve. The runnable experiment, per-seed
outputs, bootstrap tables, and provenance are bundled under
benchmark/controlled_experiment/.
The matched-budget structural retrieval audit then holds the observation count
at five in every condition. On 20 seeds and 200 episodes per seed,
cycle_aware retrieval reached 96.27% node accuracy, compared with 81.57% for
coverage-only and 16.34% for recent-only selection in an intentionally
adversarial recency-clutter design. Its paired accuracy interval versus
recency was [78.77, 81.10] percentage points, and exact cross-family lineage
echoes produced marginal TV 0. Recent-only selection actually had a larger raw
multigraph cycle rank (4 versus 2) but zero cycle-information score and only
50% node coverage. Thus cycle count alone is not used as a quality claim.
This is a controlled selector stress test, not an open-domain claim. Frozen
outputs and hashes are under
benchmark/structural_retrieval/.
A separate frozen local-LLM audit found that a full capsule was not directly
usable by Qwen2.5-0.5B-Instruct (15.0% accuracy; 15.0% capsule adherence).
After a development-only interface diagnosis, a target-specific decision
projection was frozen and evaluated on new seeds. Full-posterior memory reached
97.5% answer accuracy versus 70.0% for hard-top-1 memory, a paired gain of
27.5 percentage points with a 95% bootstrap interval of [12.5, 42.5].
Raw-context accuracy was 10.0%. Both the failed v1 and passing fresh v2 outputs
are retained under
benchmark/llm_agent_audit/. See
LLM_AGENT_AUDIT_ZH.md for scope and provenance.
Limits
- The current runtime implements finite group-like relation laws, not arbitrary natural-language facts or continuous state spaces.
- Local posterior fidelity and calibration remain the caller's responsibility.
- Exact inference is exponential in the number of free nodes;
autoswitches to beam inference above the configured budget. - Beam marginals are conditional on retained assignments and are approximate. Dual-width stability is a sensitivity check, not an exact-error certificate.
- SQLite monitor state is durable and incrementally synchronized across long-lived workers; the in-memory store remains process-local.
max_trackedis a hard, database-enforced run capacity. Roll over to a new hash-lockedrun_idinstead of silently changing a full reference period.- Outcome-before-observation is rejected atomically and must be retried after the monitored observation exists.
- Explicit
lineage_root_idvalues must identify the underlying source event correctly. If omitted, the fallback source-event/evidence-family key remains a caller responsibility. - Neighborhood discovery starts from exact node IDs. Semantic/vector retrieval can supply seeds, but is intentionally outside this package.
- This is complementary to semantic retrieval, episodic summaries, and durable fact databases; it is not a drop-in replacement for them.
- The real-model audit uses one small local model and a controlled synthetic relation task; generalization to frontier models and open-domain agents is untested.
Repository layout
src/posterior_memory_harness/
models.py observation, query, and capsule contracts
validation.py strict versioned JSON adapter boundary
store.py in-memory and SQLite persistence
sqlite_schema.py version checks, migration history, and legacy adoption
laws.py finite relation laws and registry
inference.py prior-corrected exact/beam inference
retrieval.py lineage deduplication and matched-budget graph selection
monitoring.py delayed-label calibration and drift guards
projection.py compact target-specific decision capsules
harness.py high-level API
middleware.py framework-neutral lifecycle hooks
cli.py JSON command-line adapter
schemas/ schemas bundled as installed package data
schemas/ observation, query, and delayed-outcome JSON schemas
examples/ minimal integration
tests/ unit, persistence, and end-to-end regressions
benchmark/ runnable controlled experiment and frozen results
tools/ deterministic allowlisted release builder
The production dogfood findings and fixes are recorded in
DOGFOOD_AUDIT_ZH.md. A fixed-command example that
actually invokes test/compile tools and feeds their lifecycle events through
the middleware is available at
examples/tool_using_agent_dogfood.py.
The rationale and validation for automatic neighborhood retrieval are in
IMPROVEMENT_TARGET_ZH.md.
The v0.9 matched-budget audit is documented in
benchmark/structural_retrieval/README.md.
Release files for posterior-memory-harness 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| posterior_memory_harness-0.9.0.tar.gz | 95.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| posterior_memory_harness-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 163.5 kB
Release files / posterior_memory_harness-0.9.0.tar.gz
| Download URL | posterior_memory_harness-0.9.0.tar.gz |
|---|---|
| Size | 95.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
23c602db69f0dd27fc5560e94ed66bcbf3b9b47293678412de1491a09c0e9764
|
|
BLAKE2b-256 checksum How to use checksums |
ac512550bb3d285a9183ccd320a609cb72c4bb9e3bf173850b3bed417e7bea2b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / posterior_memory_harness-0.9.0-py3-none-any.whl
| Download URL | posterior_memory_harness-0.9.0-py3-none-any.whl |
|---|---|
| Size | 67.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
22f0a65eac3bf6549482e7a21391d4a11078ca24aaab9341b8c60db99077ca22
|
|
BLAKE2b-256 checksum How to use checksums |
ef60b5d1605ee4b47bdeeae026f9ea0b621b2442e6b573ae2c4800156119665c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|