flywheel-canon 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flywheel_canon-0.2.0/CHANGELOG.md +42 -0
- flywheel_canon-0.2.0/LICENSE +110 -0
- flywheel_canon-0.2.0/MANIFEST.in +8 -0
- flywheel_canon-0.2.0/PKG-INFO +204 -0
- flywheel_canon-0.2.0/README.md +191 -0
- flywheel_canon-0.2.0/docs/art/canon-header.svg +1 -0
- flywheel_canon-0.2.0/docs/art/canon.art.json +234 -0
- flywheel_canon-0.2.0/docs/art/record-table.svg +17 -0
- flywheel_canon-0.2.0/docs/art/surface-lane.svg +19 -0
- flywheel_canon-0.2.0/docs/art/verdict-lane.svg +19 -0
- flywheel_canon-0.2.0/project-docs/F0-DECISIONS.md +63 -0
- flywheel_canon-0.2.0/project-docs/F0-DECLARED-DROPS.md +126 -0
- flywheel_canon-0.2.0/project-docs/F0-LAYERING.md +77 -0
- flywheel_canon-0.2.0/project-docs/F0-SCHEMA.md +92 -0
- flywheel_canon-0.2.0/project-docs/F0-SECTION-OWNERSHIP.md +65 -0
- flywheel_canon-0.2.0/project-docs/F1-BACKENDS.md +170 -0
- flywheel_canon-0.2.0/project-docs/F1-DECISIONS.md +93 -0
- flywheel_canon-0.2.0/project-docs/M4-CANON-CHECK.md +112 -0
- flywheel_canon-0.2.0/project-docs/M4-DECISIONS.md +539 -0
- flywheel_canon-0.2.0/project-docs/M4-EXPANDED-SCOPE-PROPOSAL-20260831.md +1067 -0
- flywheel_canon-0.2.0/project-docs/M4-TRANSPORT.md +192 -0
- flywheel_canon-0.2.0/project-docs/M4-VAULT-READER.md +215 -0
- flywheel_canon-0.2.0/project-docs/M4-VERSIONS.md +276 -0
- flywheel_canon-0.2.0/project-docs/MCP-DECISIONS.md +102 -0
- flywheel_canon-0.2.0/project-docs/R0-DECISIONS.md +117 -0
- flywheel_canon-0.2.0/project-docs/R1-DECISIONS.md +131 -0
- flywheel_canon-0.2.0/project-docs/R2-DECISIONS.md +285 -0
- flywheel_canon-0.2.0/project-docs/V2-DECISIONS.md +121 -0
- flywheel_canon-0.2.0/project-docs/V3-DECISIONS.md +169 -0
- flywheel_canon-0.2.0/project-docs/V4-DECISIONS.md +378 -0
- flywheel_canon-0.2.0/pyproject.toml +28 -0
- flywheel_canon-0.2.0/setup.cfg +4 -0
- flywheel_canon-0.2.0/src/canon/__init__.py +188 -0
- flywheel_canon-0.2.0/src/canon/__main__.py +9 -0
- flywheel_canon-0.2.0/src/canon/adapter.py +275 -0
- flywheel_canon-0.2.0/src/canon/atom.py +299 -0
- flywheel_canon-0.2.0/src/canon/backends/__init__.py +67 -0
- flywheel_canon-0.2.0/src/canon/backends/base.py +160 -0
- flywheel_canon-0.2.0/src/canon/backends/files.py +67 -0
- flywheel_canon-0.2.0/src/canon/backends/flywheel.py +77 -0
- flywheel_canon-0.2.0/src/canon/backends/mneme.py +177 -0
- flywheel_canon-0.2.0/src/canon/backends/sqlite.py +107 -0
- flywheel_canon-0.2.0/src/canon/blocks.py +102 -0
- flywheel_canon-0.2.0/src/canon/bootstrap.py +136 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_report.py +145 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_runtime.py +227 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_runtime_cache.py +263 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_runtime_error.py +10 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_runtime_inputs.py +171 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_sources.py +298 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_state_root.py +193 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_validation.py +248 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_witness_store.py +274 -0
- flywheel_canon-0.2.0/src/canon/bootstrap_witness_store_posix.py +148 -0
- flywheel_canon-0.2.0/src/canon/canon_check.py +140 -0
- flywheel_canon-0.2.0/src/canon/canonical_json.py +62 -0
- flywheel_canon-0.2.0/src/canon/canonmd.py +287 -0
- flywheel_canon-0.2.0/src/canon/canonpack.py +298 -0
- flywheel_canon-0.2.0/src/canon/capsule.py +46 -0
- flywheel_canon-0.2.0/src/canon/capsule_build.py +130 -0
- flywheel_canon-0.2.0/src/canon/capsule_rules.py +106 -0
- flywheel_canon-0.2.0/src/canon/capsule_types.py +279 -0
- flywheel_canon-0.2.0/src/canon/capsule_validation.py +238 -0
- flywheel_canon-0.2.0/src/canon/cli.py +216 -0
- flywheel_canon-0.2.0/src/canon/cli_artifacts.py +226 -0
- flywheel_canon-0.2.0/src/canon/cli_compile.py +295 -0
- flywheel_canon-0.2.0/src/canon/cli_export.py +275 -0
- flywheel_canon-0.2.0/src/canon/cli_export_support.py +62 -0
- flywheel_canon-0.2.0/src/canon/cli_format.py +247 -0
- flywheel_canon-0.2.0/src/canon/cli_init.py +270 -0
- flywheel_canon-0.2.0/src/canon/cli_parser.py +170 -0
- flywheel_canon-0.2.0/src/canon/cli_publish.py +300 -0
- flywheel_canon-0.2.0/src/canon/cli_rescue.py +297 -0
- flywheel_canon-0.2.0/src/canon/client_capture.py +225 -0
- flywheel_canon-0.2.0/src/canon/client_capture_payload.py +161 -0
- flywheel_canon-0.2.0/src/canon/concurrency.py +58 -0
- flywheel_canon-0.2.0/src/canon/concurrency_capability.py +84 -0
- flywheel_canon-0.2.0/src/canon/concurrency_errors.py +7 -0
- flywheel_canon-0.2.0/src/canon/concurrency_lock.py +212 -0
- flywheel_canon-0.2.0/src/canon/concurrency_lock_backend.py +192 -0
- flywheel_canon-0.2.0/src/canon/concurrency_posix.py +70 -0
- flywheel_canon-0.2.0/src/canon/concurrency_windows.py +123 -0
- flywheel_canon-0.2.0/src/canon/concurrency_windows_api.py +273 -0
- flywheel_canon-0.2.0/src/canon/context_mcp.py +145 -0
- flywheel_canon-0.2.0/src/canon/context_query.py +197 -0
- flywheel_canon-0.2.0/src/canon/context_records.py +90 -0
- flywheel_canon-0.2.0/src/canon/context_related.py +111 -0
- flywheel_canon-0.2.0/src/canon/context_store.py +234 -0
- flywheel_canon-0.2.0/src/canon/doctor.py +224 -0
- flywheel_canon-0.2.0/src/canon/drift.py +134 -0
- flywheel_canon-0.2.0/src/canon/exit_codes.py +50 -0
- flywheel_canon-0.2.0/src/canon/export_output.py +87 -0
- flywheel_canon-0.2.0/src/canon/fidelity.py +235 -0
- flywheel_canon-0.2.0/src/canon/frontmatter.py +127 -0
- flywheel_canon-0.2.0/src/canon/import_policy.py +298 -0
- flywheel_canon-0.2.0/src/canon/import_review.py +247 -0
- flywheel_canon-0.2.0/src/canon/import_review_safety.py +147 -0
- flywheel_canon-0.2.0/src/canon/layering.py +123 -0
- flywheel_canon-0.2.0/src/canon/local_mcp.py +252 -0
- flywheel_canon-0.2.0/src/canon/omission.py +131 -0
- flywheel_canon-0.2.0/src/canon/path_policy.py +249 -0
- flywheel_canon-0.2.0/src/canon/persona_thesis.py +189 -0
- flywheel_canon-0.2.0/src/canon/readiness.py +298 -0
- flywheel_canon-0.2.0/src/canon/reconcile.py +269 -0
- flywheel_canon-0.2.0/src/canon/reconcile_gate.py +107 -0
- flywheel_canon-0.2.0/src/canon/reconcile_run.py +172 -0
- flywheel_canon-0.2.0/src/canon/region.py +151 -0
- flywheel_canon-0.2.0/src/canon/registry.py +183 -0
- flywheel_canon-0.2.0/src/canon/replay.py +103 -0
- flywheel_canon-0.2.0/src/canon/rescue.py +81 -0
- flywheel_canon-0.2.0/src/canon/rescue_artifacts.py +117 -0
- flywheel_canon-0.2.0/src/canon/rescue_output.py +122 -0
- flywheel_canon-0.2.0/src/canon/retention.py +272 -0
- flywheel_canon-0.2.0/src/canon/retention_receipts.py +110 -0
- flywheel_canon-0.2.0/src/canon/retention_safety.py +62 -0
- flywheel_canon-0.2.0/src/canon/schema.py +214 -0
- flywheel_canon-0.2.0/src/canon/secret_quarantine.py +256 -0
- flywheel_canon-0.2.0/src/canon/source_safe_read.py +300 -0
- flywheel_canon-0.2.0/src/canon/source_state.py +119 -0
- flywheel_canon-0.2.0/src/canon/source_state_cache.py +300 -0
- flywheel_canon-0.2.0/src/canon/surface.py +54 -0
- flywheel_canon-0.2.0/src/canon/textblock.py +252 -0
- flywheel_canon-0.2.0/src/canon/textutil.py +36 -0
- flywheel_canon-0.2.0/src/canon/transform.py +168 -0
- flywheel_canon-0.2.0/src/canon/transport/__init__.py +56 -0
- flywheel_canon-0.2.0/src/canon/transport/base.py +300 -0
- flywheel_canon-0.2.0/src/canon/transport/capabilities.py +67 -0
- flywheel_canon-0.2.0/src/canon/undo.py +81 -0
- flywheel_canon-0.2.0/src/canon/undo_io.py +279 -0
- flywheel_canon-0.2.0/src/canon/undo_posix.py +113 -0
- flywheel_canon-0.2.0/src/canon/undo_posix_core.py +184 -0
- flywheel_canon-0.2.0/src/canon/undo_posix_files.py +218 -0
- flywheel_canon-0.2.0/src/canon/undo_receipts.py +210 -0
- flywheel_canon-0.2.0/src/canon/validator.py +191 -0
- flywheel_canon-0.2.0/src/canon/vault.py +296 -0
- flywheel_canon-0.2.0/src/canon/vault_fidelity.py +147 -0
- flywheel_canon-0.2.0/src/canon/vault_mirror.py +300 -0
- flywheel_canon-0.2.0/src/canon/vault_read_fidelity.py +153 -0
- flywheel_canon-0.2.0/src/canon/vault_reader.py +299 -0
- flywheel_canon-0.2.0/src/canon/versions.py +306 -0
- flywheel_canon-0.2.0/src/canon/versions_migrate.py +133 -0
- flywheel_canon-0.2.0/src/canon/witness.py +297 -0
- flywheel_canon-0.2.0/src/canon/writing_gate.py +95 -0
- flywheel_canon-0.2.0/src/flywheel_canon.egg-info/PKG-INFO +204 -0
- flywheel_canon-0.2.0/src/flywheel_canon.egg-info/SOURCES.txt +229 -0
- flywheel_canon-0.2.0/src/flywheel_canon.egg-info/dependency_links.txt +1 -0
- flywheel_canon-0.2.0/src/flywheel_canon.egg-info/entry_points.txt +2 -0
- flywheel_canon-0.2.0/src/flywheel_canon.egg-info/requires.txt +3 -0
- flywheel_canon-0.2.0/src/flywheel_canon.egg-info/top_level.txt +1 -0
- flywheel_canon-0.2.0/tests/fixtures/bootstrap/atoms.jsonl +4 -0
- flywheel_canon-0.2.0/tests/fixtures/bootstrap/readiness_fail_missing_goal.json +22 -0
- flywheel_canon-0.2.0/tests/fixtures/bootstrap/readiness_pass.json +22 -0
- flywheel_canon-0.2.0/tests/fixtures/bootstrap/records.jsonl +1 -0
- flywheel_canon-0.2.0/tests/fixtures/bootstrap/secret_atoms.jsonl +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/CANON.expected.md +70 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/adapter_a2a_artifact_guided.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/adapter_codex_cli_native_advisory.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/adapter_mcp_readonly_guided.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/atom_active_goal.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/atom_conflict.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/atom_constraint.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/atom_frontier_state.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/atom_permission.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/atom_prohibition.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/atom_unknown.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/bootstrap_witness_pass.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/capsule_handoff_full.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/capsule_minimal_needle.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/omission_budget_noncritical.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/readiness_probe.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/foundation/transform_summary.json +1 -0
- flywheel_canon-0.2.0/tests/fixtures/layering_expected.json +12 -0
- flywheel_canon-0.2.0/tests/fixtures/layering_pool.json +56 -0
- flywheel_canon-0.2.0/tests/fixtures/records/adr_decision.json +29 -0
- flywheel_canon-0.2.0/tests/fixtures/records/episodic_memory.json +26 -0
- flywheel_canon-0.2.0/tests/fixtures/records/personality_block.json +23 -0
- flywheel_canon-0.2.0/tests/fixtures/records/research_artifact_ref.json +22 -0
- flywheel_canon-0.2.0/tests/fixtures/records/synthesized_persona_l3.json +26 -0
- flywheel_canon-0.2.0/tests/test_backend_base.py +140 -0
- flywheel_canon-0.2.0/tests/test_blocks.py +181 -0
- flywheel_canon-0.2.0/tests/test_canon_check.py +247 -0
- flywheel_canon-0.2.0/tests/test_client_capture.py +413 -0
- flywheel_canon-0.2.0/tests/test_concurrency.py +1045 -0
- flywheel_canon-0.2.0/tests/test_context_identifier_query.py +210 -0
- flywheel_canon-0.2.0/tests/test_context_mcp.py +268 -0
- flywheel_canon-0.2.0/tests/test_context_related_events.py +207 -0
- flywheel_canon-0.2.0/tests/test_context_store.py +276 -0
- flywheel_canon-0.2.0/tests/test_context_store_identity.py +227 -0
- flywheel_canon-0.2.0/tests/test_declared_drops.py +91 -0
- flywheel_canon-0.2.0/tests/test_doctor_cli.py +471 -0
- flywheel_canon-0.2.0/tests/test_drift.py +227 -0
- flywheel_canon-0.2.0/tests/test_export_rescue_cli.py +797 -0
- flywheel_canon-0.2.0/tests/test_fidelity.py +264 -0
- flywheel_canon-0.2.0/tests/test_files_backend.py +79 -0
- flywheel_canon-0.2.0/tests/test_flywheel_backend.py +90 -0
- flywheel_canon-0.2.0/tests/test_frontmatter.py +134 -0
- flywheel_canon-0.2.0/tests/test_import_policy.py +401 -0
- flywheel_canon-0.2.0/tests/test_import_review.py +441 -0
- flywheel_canon-0.2.0/tests/test_layering.py +157 -0
- flywheel_canon-0.2.0/tests/test_local_mcp.py +236 -0
- flywheel_canon-0.2.0/tests/test_mcp_check.py +76 -0
- flywheel_canon-0.2.0/tests/test_mneme_backend.py +207 -0
- flywheel_canon-0.2.0/tests/test_orchestration.py +220 -0
- flywheel_canon-0.2.0/tests/test_persona_thesis.py +307 -0
- flywheel_canon-0.2.0/tests/test_reconcile.py +636 -0
- flywheel_canon-0.2.0/tests/test_reconcile_gate.py +149 -0
- flywheel_canon-0.2.0/tests/test_reconcile_run.py +445 -0
- flywheel_canon-0.2.0/tests/test_region.py +172 -0
- flywheel_canon-0.2.0/tests/test_registry.py +159 -0
- flywheel_canon-0.2.0/tests/test_replay.py +194 -0
- flywheel_canon-0.2.0/tests/test_repo_art.py +282 -0
- flywheel_canon-0.2.0/tests/test_retention.py +461 -0
- flywheel_canon-0.2.0/tests/test_schema_roundtrip.py +111 -0
- flywheel_canon-0.2.0/tests/test_selective_continuity_cli.py +306 -0
- flywheel_canon-0.2.0/tests/test_soul.py +142 -0
- flywheel_canon-0.2.0/tests/test_source_safe_read.py +95 -0
- flywheel_canon-0.2.0/tests/test_sqlite_backend.py +93 -0
- flywheel_canon-0.2.0/tests/test_surface.py +153 -0
- flywheel_canon-0.2.0/tests/test_textblock.py +334 -0
- flywheel_canon-0.2.0/tests/test_textutil.py +161 -0
- flywheel_canon-0.2.0/tests/test_transport_base.py +292 -0
- flywheel_canon-0.2.0/tests/test_transport_conformance.py +216 -0
- flywheel_canon-0.2.0/tests/test_validator.py +164 -0
- flywheel_canon-0.2.0/tests/test_vault.py +321 -0
- flywheel_canon-0.2.0/tests/test_vault_fidelity.py +92 -0
- flywheel_canon-0.2.0/tests/test_vault_mirror.py +408 -0
- flywheel_canon-0.2.0/tests/test_vault_reader.py +409 -0
- flywheel_canon-0.2.0/tests/test_vault_reader_fidelity.py +106 -0
- flywheel_canon-0.2.0/tests/test_versions.py +383 -0
- flywheel_canon-0.2.0/tests/test_versions_migrate.py +211 -0
- flywheel_canon-0.2.0/tests/test_writing_gate.py +134 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0 - 2026-09-22
|
|
4
|
+
|
|
5
|
+
- Publishes to PyPI as `flywheel-canon`. The bare name `canon` belongs to an
|
|
6
|
+
unrelated project, so the distribution carries the prefix while the console
|
|
7
|
+
script stays `canon`.
|
|
8
|
+
- Adds an OIDC trusted-publishing release workflow with tag/version, artifact
|
|
9
|
+
digest, clean-venv entry-point resolution, and sdist-rebuild gates.
|
|
10
|
+
- Adds run-lock concurrency control, and fixes POSIX run-lock descriptor release.
|
|
11
|
+
- Adds doctor diagnostics, retention planning, replay checks, rescue handoff, and
|
|
12
|
+
an import review policy.
|
|
13
|
+
- Hardens Canon source reads.
|
|
14
|
+
|
|
15
|
+
## 0.1.0 — 2026-09-07
|
|
16
|
+
|
|
17
|
+
First GitHub release for Canon.
|
|
18
|
+
|
|
19
|
+
- Keeps the existing read-only MCP surface: `canon.status`, `canon.doctor`,
|
|
20
|
+
`canon.blocks`, `canon.render`, `canon.validate`, and `canon.check`.
|
|
21
|
+
- Adds provider-neutral continuity preview and export from explicit
|
|
22
|
+
`records.jsonl` and `atoms.jsonl` inputs.
|
|
23
|
+
- Exports Canon Markdown, capsule JSON, readiness JSON, or a three-file bundle
|
|
24
|
+
containing `CANON.md`, `canon.capsule.json`, and `readiness-probe.json`.
|
|
25
|
+
- Records source-state hashes, artifact hashes, target tier, omissions, and
|
|
26
|
+
does-not-prove limits in the generated capsule outputs.
|
|
27
|
+
- Uses confined bundle publication or fails closed. On Windows, the final bundle
|
|
28
|
+
directory rename is parent-handle-relative and leaf-only.
|
|
29
|
+
|
|
30
|
+
Limits:
|
|
31
|
+
|
|
32
|
+
- Canon does not import ChatGPT web conversations, Codex task databases, Claude
|
|
33
|
+
web history, Claude Code sessions, provider auth caches, or credentials.
|
|
34
|
+
- The `codex-cli` and `claude-code` targets are native-advisory. App and web
|
|
35
|
+
targets remain guided until their hosts provide stronger startup evidence.
|
|
36
|
+
- Bundle export proves the command's publication boundary, not immutability
|
|
37
|
+
after the command returns.
|
|
38
|
+
- New bundle creation currently requires the supported Windows native backend.
|
|
39
|
+
Linux and macOS refuse new bundle creation without writing. Preview and stdout
|
|
40
|
+
exports remain available there.
|
|
41
|
+
- Release downloads are distributed through GitHub. No PyPI publication claim
|
|
42
|
+
is made.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, MIT Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-MIT
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Zain Dana Harper
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the MIT license that is effective on the second anniversary of the date we make
|
|
91
|
+
the Software available. On or after that date, you may use the Software under
|
|
92
|
+
the MIT license, in which case the following will apply:
|
|
93
|
+
|
|
94
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
95
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
96
|
+
the Software without restriction, including without limitation the rights to
|
|
97
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
98
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
99
|
+
so, subject to the following conditions:
|
|
100
|
+
|
|
101
|
+
The above copyright notice and this permission notice shall be included in all
|
|
102
|
+
copies or substantial portions of the Software.
|
|
103
|
+
|
|
104
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
105
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
106
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
107
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
108
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
109
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
110
|
+
SOFTWARE.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
include CHANGELOG.md
|
|
2
|
+
recursive-include docs/art *.json *.svg
|
|
3
|
+
# Ship format specifications and implementation decisions, not historical audits.
|
|
4
|
+
include project-docs/F*.md
|
|
5
|
+
include project-docs/R*.md
|
|
6
|
+
include project-docs/V*.md
|
|
7
|
+
include project-docs/M*.md
|
|
8
|
+
recursive-include tests/fixtures *
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flywheel-canon
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A provider-neutral memory-bank, personality container, and continuity capsule CLI.
|
|
5
|
+
Author: HarperZ9
|
|
6
|
+
License-Expression: LicenseRef-FSL-1.1-MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# canon
|
|
15
|
+
|
|
16
|
+
One record for your memory bank and your personality, shared across every model
|
|
17
|
+
and every tool.
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
You keep the same working relationship whether you open Claude Code, Claude CLI,
|
|
22
|
+
ChatGPT, Codex, or a web surface: the same authored voice, the same accumulated
|
|
23
|
+
memory, the same decisions. Today that lives in a dozen files with a dozen
|
|
24
|
+
shapes (`CLAUDE.md`, `AGENTS.md`, `SOUL.md`, `GEMINI.md`) plus per-tool memory
|
|
25
|
+
stores that do not talk to each other. canon gives all of them one typed record
|
|
26
|
+
to draw from and write back to, and renders each tool's file from that record.
|
|
27
|
+
|
|
28
|
+
## What it does
|
|
29
|
+
|
|
30
|
+
- **One envelope, five kinds.** An authored personality block, a raw or extracted
|
|
31
|
+
memory, a synthesized persona, a decision record, and a reference to an
|
|
32
|
+
external research artifact all share one record shape with a provenance
|
|
33
|
+
receipt on every entry.
|
|
34
|
+
- **Two scopes that layer.** A `global` block is your default everywhere; a
|
|
35
|
+
`workspace` block with the same id overrides it where that workspace applies.
|
|
36
|
+
A render resolves the effective set for its target, current entries only.
|
|
37
|
+
- **Deterministic by construction.** Ordering uses a clock-free ordinal, so a
|
|
38
|
+
rebuild from the same records is byte-identical. The wall clock is kept only
|
|
39
|
+
as a non-authoritative convenience.
|
|
40
|
+
- **An assembly, not a rewrite.** canon aims at proven engines rather than
|
|
41
|
+
replacing them: a memory fact-engine, an authored-block store, and a
|
|
42
|
+
cross-provider transport. It adds the one record they share and the renderer
|
|
43
|
+
that projects each surface.
|
|
44
|
+
|
|
45
|
+
## How one record becomes the file each tool reads
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
canon writes four paths and no others, and inside those four it rewrites only
|
|
50
|
+
the span between its own markers. A file with no canon region is left alone.
|
|
51
|
+
|
|
52
|
+
## How a rendered file is checked back against the record
|
|
53
|
+
|
|
54
|
+

|
|
55
|
+
|
|
56
|
+
A round-trip that loses a field passes only when the adapter declared that loss
|
|
57
|
+
in advance. Anything else fails the gate rather than logging a warning.
|
|
58
|
+
|
|
59
|
+
## What canon carries
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
Every count is asserted against the module that defines it in
|
|
64
|
+
`tests/test_repo_art.py`.
|
|
65
|
+
|
|
66
|
+
## Status
|
|
67
|
+
|
|
68
|
+
F0 is the record of record: the canonical schema, its validator, and the
|
|
69
|
+
per-scope layering. F1 adds the storage seam: a `MemoryBackend` protocol with
|
|
70
|
+
capability tokens and four adapters, among them a zero-drop SQLite reference and
|
|
71
|
+
injected-handle adapters for a memory fact-engine and an authored-block store.
|
|
72
|
+
R0 adds the block round-trip gate: a byte-exact region boundary inside a managed
|
|
73
|
+
file, a record-to-text renderer and its inverse, and a go/no-go verdict that
|
|
74
|
+
proves a block set round-trips to its canonical form with every dropped field
|
|
75
|
+
declared.
|
|
76
|
+
|
|
77
|
+
R1 renders your files from the record. It resolves the block set for a file's
|
|
78
|
+
scope and rewrites only the region canon owns, every byte outside it preserved.
|
|
79
|
+
It writes only a fixed allow-list of files, and only a file you have opted in
|
|
80
|
+
with a canon region. Where a tool reads both a global and a workspace file, the
|
|
81
|
+
workspace file carries just your workspace blocks, so a shared block is never
|
|
82
|
+
duplicated; where a tool reads one file, that file carries the full resolved set.
|
|
83
|
+
|
|
84
|
+
R2 mirrors your whole record set into an Obsidian vault. Each record becomes one
|
|
85
|
+
markdown note you can read, search, and link, and a MEMORY.md index lists them
|
|
86
|
+
all. The full record rides inside every note, so a rebuild is exact and editing a
|
|
87
|
+
note's prose never rewrites the record behind it. canon writes only inside its own
|
|
88
|
+
vault, never touches a file it did not write, and when you drop a record it
|
|
89
|
+
reports the note left behind rather than deleting it. R2 also adds SOUL.md to the
|
|
90
|
+
rendered surfaces.
|
|
91
|
+
|
|
92
|
+
V2 through V4 add the checks and the decision on top of them. A drift check
|
|
93
|
+
re-derives every managed surface and compares only the region canon owns, so
|
|
94
|
+
your own prose outside the markers is never flagged. A persona check reports
|
|
95
|
+
whether the memories behind a synthesized persona still resolve. V4 separates a
|
|
96
|
+
mechanical fast-forward from a conflict, writes the fast-forwards, and raises a
|
|
97
|
+
durable gate for anything a human should adjudicate.
|
|
98
|
+
|
|
99
|
+
A harness reaches all of this over MCP. `canon mcp` serves six read-only tools:
|
|
100
|
+
identity, a readiness diagnostic, the authored record set, the render for a
|
|
101
|
+
scope, the validator, and the aggregate check. Nothing on that server writes a
|
|
102
|
+
file. Reconcile stays a library call, because rewriting your instruction files
|
|
103
|
+
and raising a gate is an action with a person behind it.
|
|
104
|
+
|
|
105
|
+
The CLI can also compile a provider-neutral continuity capsule from two explicit
|
|
106
|
+
inputs: `records.jsonl` and `atoms.jsonl`. Preview reports artifact names,
|
|
107
|
+
target tier, readiness probe data, and source-state hashes without writing.
|
|
108
|
+
Export writes the same capsule as Canon Markdown, capsule JSON, readiness JSON,
|
|
109
|
+
or a three-file bundle. The capsule records omitted state as typed atoms or
|
|
110
|
+
transform omissions and says what the export does not prove, including host
|
|
111
|
+
enforcement. It does not import provider auth, private databases, ChatGPT web
|
|
112
|
+
state, or Claude web state.
|
|
113
|
+
|
|
114
|
+
Installing a region into a fresh file, the first migrator on the version seam,
|
|
115
|
+
and the global SOUL.md and GEMINI.md surfaces are later phases. Everything
|
|
116
|
+
shipped is proven by a full test suite and aims at the one envelope.
|
|
117
|
+
|
|
118
|
+
## Run it
|
|
119
|
+
|
|
120
|
+
Canon 0.1.0 is prepared as a GitHub release candidate. Install from a reviewed
|
|
121
|
+
GitHub release asset after publication, or from a local wheel during review:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
python -m pip install canon-0.1.0-py3-none-any.whl
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
No PyPI package ownership or publication is claimed here.
|
|
128
|
+
|
|
129
|
+
Serve the record set to a harness:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
canon mcp
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Ask canon what it believes, with no transport in the way:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
canon check
|
|
139
|
+
canon blocks
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`canon check` exits non-zero when a wired leg fails or the block pool is not the
|
|
143
|
+
authored set, so a build can key on it. Point it at your records with
|
|
144
|
+
`CANON_BLOCKS_DIR`, and at your files with `CANON_HOME` and `CANON_WORKSPACE`.
|
|
145
|
+
|
|
146
|
+
Preview and export a continuity capsule from explicit local inputs:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
canon --json preview --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli
|
|
150
|
+
canon export --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli --format canon-md
|
|
151
|
+
canon export --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli --format capsule-json
|
|
152
|
+
canon --json export --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli --format bundle --out bundle
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The `codex-cli` and `claude-code` targets are native-advisory surfaces. App and
|
|
156
|
+
web targets remain guided until their hosts provide stronger startup evidence.
|
|
157
|
+
Preview and stdout exports work across supported Python platforms. Creating a
|
|
158
|
+
new bundle currently requires Windows with the confined native writer. On Linux
|
|
159
|
+
and macOS, new bundle creation returns `unsafe_path` without writing; use stdout
|
|
160
|
+
export there. The Windows final directory rename is parent-handle-relative and
|
|
161
|
+
leaf-only. This bounds publication, not immutability after the command returns.
|
|
162
|
+
|
|
163
|
+
Run the suite:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
python -m pytest
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
No runtime dependencies. Python 3.11 or newer.
|
|
170
|
+
|
|
171
|
+
## Layout
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
src/canon/
|
|
175
|
+
schema.py, validator.py, layering.py the record, its rules, per-scope resolve
|
|
176
|
+
backends/ the storage seam and four adapters
|
|
177
|
+
region.py, textblock.py, fidelity.py the byte boundary, the text codec, the gate
|
|
178
|
+
surface.py, registry.py the render composition, the write allow-list
|
|
179
|
+
frontmatter.py, vault.py the note frontmatter codec, the one-record note
|
|
180
|
+
vault_mirror.py, vault_fidelity.py the whole-vault mirror and its round-trip gate
|
|
181
|
+
drift.py, writing_gate.py the surface drift check, the injected prose gate
|
|
182
|
+
persona_thesis.py, canon_check.py the persona basis adapter, the aggregate check
|
|
183
|
+
reconcile*.py the fast-forward decision and its durable gate
|
|
184
|
+
blocks.py, local_mcp.py, cli.py the authored-block loader, the MCP door, the CLI
|
|
185
|
+
capsule*.py, atom.py, adapter.py the continuity capsule, atom and target contract
|
|
186
|
+
cli_compile.py, cli_export.py preview, stdout export and bundle export
|
|
187
|
+
cli_artifacts.py, cli_publish.py source hashes and confined artifact publishing
|
|
188
|
+
tests/ round-trip, validator, layering, backend,
|
|
189
|
+
fidelity, surface, orchestration, vault,
|
|
190
|
+
drift, reconcile, continuity, and artwork proofs
|
|
191
|
+
docs/art/ the drawings above and the spec they render from
|
|
192
|
+
project-docs/ the F0, F1, R0, R1, R2, V2, V3, V4, MCP decisions
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
See `project-docs/` for the schema reference, the layering derivation, the
|
|
196
|
+
section-ownership contract, the declared drops each storage backend must
|
|
197
|
+
announce, and the decisions behind the round-trip, vault, drift and reconcile
|
|
198
|
+
gates.
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
FSL-1.1-MIT. Functional Source License, source-available now for any purpose
|
|
203
|
+
other than a competing product, and it converts to the MIT license two years
|
|
204
|
+
after each version is released. See `LICENSE`.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# canon
|
|
2
|
+
|
|
3
|
+
One record for your memory bank and your personality, shared across every model
|
|
4
|
+
and every tool.
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
You keep the same working relationship whether you open Claude Code, Claude CLI,
|
|
9
|
+
ChatGPT, Codex, or a web surface: the same authored voice, the same accumulated
|
|
10
|
+
memory, the same decisions. Today that lives in a dozen files with a dozen
|
|
11
|
+
shapes (`CLAUDE.md`, `AGENTS.md`, `SOUL.md`, `GEMINI.md`) plus per-tool memory
|
|
12
|
+
stores that do not talk to each other. canon gives all of them one typed record
|
|
13
|
+
to draw from and write back to, and renders each tool's file from that record.
|
|
14
|
+
|
|
15
|
+
## What it does
|
|
16
|
+
|
|
17
|
+
- **One envelope, five kinds.** An authored personality block, a raw or extracted
|
|
18
|
+
memory, a synthesized persona, a decision record, and a reference to an
|
|
19
|
+
external research artifact all share one record shape with a provenance
|
|
20
|
+
receipt on every entry.
|
|
21
|
+
- **Two scopes that layer.** A `global` block is your default everywhere; a
|
|
22
|
+
`workspace` block with the same id overrides it where that workspace applies.
|
|
23
|
+
A render resolves the effective set for its target, current entries only.
|
|
24
|
+
- **Deterministic by construction.** Ordering uses a clock-free ordinal, so a
|
|
25
|
+
rebuild from the same records is byte-identical. The wall clock is kept only
|
|
26
|
+
as a non-authoritative convenience.
|
|
27
|
+
- **An assembly, not a rewrite.** canon aims at proven engines rather than
|
|
28
|
+
replacing them: a memory fact-engine, an authored-block store, and a
|
|
29
|
+
cross-provider transport. It adds the one record they share and the renderer
|
|
30
|
+
that projects each surface.
|
|
31
|
+
|
|
32
|
+
## How one record becomes the file each tool reads
|
|
33
|
+
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
canon writes four paths and no others, and inside those four it rewrites only
|
|
37
|
+
the span between its own markers. A file with no canon region is left alone.
|
|
38
|
+
|
|
39
|
+
## How a rendered file is checked back against the record
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
A round-trip that loses a field passes only when the adapter declared that loss
|
|
44
|
+
in advance. Anything else fails the gate rather than logging a warning.
|
|
45
|
+
|
|
46
|
+
## What canon carries
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+
Every count is asserted against the module that defines it in
|
|
51
|
+
`tests/test_repo_art.py`.
|
|
52
|
+
|
|
53
|
+
## Status
|
|
54
|
+
|
|
55
|
+
F0 is the record of record: the canonical schema, its validator, and the
|
|
56
|
+
per-scope layering. F1 adds the storage seam: a `MemoryBackend` protocol with
|
|
57
|
+
capability tokens and four adapters, among them a zero-drop SQLite reference and
|
|
58
|
+
injected-handle adapters for a memory fact-engine and an authored-block store.
|
|
59
|
+
R0 adds the block round-trip gate: a byte-exact region boundary inside a managed
|
|
60
|
+
file, a record-to-text renderer and its inverse, and a go/no-go verdict that
|
|
61
|
+
proves a block set round-trips to its canonical form with every dropped field
|
|
62
|
+
declared.
|
|
63
|
+
|
|
64
|
+
R1 renders your files from the record. It resolves the block set for a file's
|
|
65
|
+
scope and rewrites only the region canon owns, every byte outside it preserved.
|
|
66
|
+
It writes only a fixed allow-list of files, and only a file you have opted in
|
|
67
|
+
with a canon region. Where a tool reads both a global and a workspace file, the
|
|
68
|
+
workspace file carries just your workspace blocks, so a shared block is never
|
|
69
|
+
duplicated; where a tool reads one file, that file carries the full resolved set.
|
|
70
|
+
|
|
71
|
+
R2 mirrors your whole record set into an Obsidian vault. Each record becomes one
|
|
72
|
+
markdown note you can read, search, and link, and a MEMORY.md index lists them
|
|
73
|
+
all. The full record rides inside every note, so a rebuild is exact and editing a
|
|
74
|
+
note's prose never rewrites the record behind it. canon writes only inside its own
|
|
75
|
+
vault, never touches a file it did not write, and when you drop a record it
|
|
76
|
+
reports the note left behind rather than deleting it. R2 also adds SOUL.md to the
|
|
77
|
+
rendered surfaces.
|
|
78
|
+
|
|
79
|
+
V2 through V4 add the checks and the decision on top of them. A drift check
|
|
80
|
+
re-derives every managed surface and compares only the region canon owns, so
|
|
81
|
+
your own prose outside the markers is never flagged. A persona check reports
|
|
82
|
+
whether the memories behind a synthesized persona still resolve. V4 separates a
|
|
83
|
+
mechanical fast-forward from a conflict, writes the fast-forwards, and raises a
|
|
84
|
+
durable gate for anything a human should adjudicate.
|
|
85
|
+
|
|
86
|
+
A harness reaches all of this over MCP. `canon mcp` serves six read-only tools:
|
|
87
|
+
identity, a readiness diagnostic, the authored record set, the render for a
|
|
88
|
+
scope, the validator, and the aggregate check. Nothing on that server writes a
|
|
89
|
+
file. Reconcile stays a library call, because rewriting your instruction files
|
|
90
|
+
and raising a gate is an action with a person behind it.
|
|
91
|
+
|
|
92
|
+
The CLI can also compile a provider-neutral continuity capsule from two explicit
|
|
93
|
+
inputs: `records.jsonl` and `atoms.jsonl`. Preview reports artifact names,
|
|
94
|
+
target tier, readiness probe data, and source-state hashes without writing.
|
|
95
|
+
Export writes the same capsule as Canon Markdown, capsule JSON, readiness JSON,
|
|
96
|
+
or a three-file bundle. The capsule records omitted state as typed atoms or
|
|
97
|
+
transform omissions and says what the export does not prove, including host
|
|
98
|
+
enforcement. It does not import provider auth, private databases, ChatGPT web
|
|
99
|
+
state, or Claude web state.
|
|
100
|
+
|
|
101
|
+
Installing a region into a fresh file, the first migrator on the version seam,
|
|
102
|
+
and the global SOUL.md and GEMINI.md surfaces are later phases. Everything
|
|
103
|
+
shipped is proven by a full test suite and aims at the one envelope.
|
|
104
|
+
|
|
105
|
+
## Run it
|
|
106
|
+
|
|
107
|
+
Canon 0.1.0 is prepared as a GitHub release candidate. Install from a reviewed
|
|
108
|
+
GitHub release asset after publication, or from a local wheel during review:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
python -m pip install canon-0.1.0-py3-none-any.whl
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
No PyPI package ownership or publication is claimed here.
|
|
115
|
+
|
|
116
|
+
Serve the record set to a harness:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
canon mcp
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Ask canon what it believes, with no transport in the way:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
canon check
|
|
126
|
+
canon blocks
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`canon check` exits non-zero when a wired leg fails or the block pool is not the
|
|
130
|
+
authored set, so a build can key on it. Point it at your records with
|
|
131
|
+
`CANON_BLOCKS_DIR`, and at your files with `CANON_HOME` and `CANON_WORKSPACE`.
|
|
132
|
+
|
|
133
|
+
Preview and export a continuity capsule from explicit local inputs:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
canon --json preview --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli
|
|
137
|
+
canon export --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli --format canon-md
|
|
138
|
+
canon export --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli --format capsule-json
|
|
139
|
+
canon --json export --workspace . --records records.jsonl --atoms atoms.jsonl --target codex-cli --format bundle --out bundle
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The `codex-cli` and `claude-code` targets are native-advisory surfaces. App and
|
|
143
|
+
web targets remain guided until their hosts provide stronger startup evidence.
|
|
144
|
+
Preview and stdout exports work across supported Python platforms. Creating a
|
|
145
|
+
new bundle currently requires Windows with the confined native writer. On Linux
|
|
146
|
+
and macOS, new bundle creation returns `unsafe_path` without writing; use stdout
|
|
147
|
+
export there. The Windows final directory rename is parent-handle-relative and
|
|
148
|
+
leaf-only. This bounds publication, not immutability after the command returns.
|
|
149
|
+
|
|
150
|
+
Run the suite:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
python -m pytest
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
No runtime dependencies. Python 3.11 or newer.
|
|
157
|
+
|
|
158
|
+
## Layout
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
src/canon/
|
|
162
|
+
schema.py, validator.py, layering.py the record, its rules, per-scope resolve
|
|
163
|
+
backends/ the storage seam and four adapters
|
|
164
|
+
region.py, textblock.py, fidelity.py the byte boundary, the text codec, the gate
|
|
165
|
+
surface.py, registry.py the render composition, the write allow-list
|
|
166
|
+
frontmatter.py, vault.py the note frontmatter codec, the one-record note
|
|
167
|
+
vault_mirror.py, vault_fidelity.py the whole-vault mirror and its round-trip gate
|
|
168
|
+
drift.py, writing_gate.py the surface drift check, the injected prose gate
|
|
169
|
+
persona_thesis.py, canon_check.py the persona basis adapter, the aggregate check
|
|
170
|
+
reconcile*.py the fast-forward decision and its durable gate
|
|
171
|
+
blocks.py, local_mcp.py, cli.py the authored-block loader, the MCP door, the CLI
|
|
172
|
+
capsule*.py, atom.py, adapter.py the continuity capsule, atom and target contract
|
|
173
|
+
cli_compile.py, cli_export.py preview, stdout export and bundle export
|
|
174
|
+
cli_artifacts.py, cli_publish.py source hashes and confined artifact publishing
|
|
175
|
+
tests/ round-trip, validator, layering, backend,
|
|
176
|
+
fidelity, surface, orchestration, vault,
|
|
177
|
+
drift, reconcile, continuity, and artwork proofs
|
|
178
|
+
docs/art/ the drawings above and the spec they render from
|
|
179
|
+
project-docs/ the F0, F1, R0, R1, R2, V2, V3, V4, MCP decisions
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
See `project-docs/` for the schema reference, the layering derivation, the
|
|
183
|
+
section-ownership contract, the declared drops each storage backend must
|
|
184
|
+
announce, and the decisions behind the round-trip, vault, drift and reconcile
|
|
185
|
+
gates.
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
FSL-1.1-MIT. Functional Source License, source-available now for any purpose
|
|
190
|
+
other than a competing product, and it converts to the MIT license two years
|
|
191
|
+
after each version is released. See `LICENSE`.
|