vinyasar 0.3.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.
Files changed (86) hide show
  1. vinyasar-0.3.0/CHANGELOG.md +126 -0
  2. vinyasar-0.3.0/MANIFEST.in +8 -0
  3. vinyasar-0.3.0/PKG-INFO +115 -0
  4. vinyasar-0.3.0/README.md +92 -0
  5. vinyasar-0.3.0/docs/ARCHITECTURE.md +28 -0
  6. vinyasar-0.3.0/docs/HANDOFF.md +21 -0
  7. vinyasar-0.3.0/docs/SAFETY.md +108 -0
  8. vinyasar-0.3.0/docs/TEST_REPORT.md +6 -0
  9. vinyasar-0.3.0/docs/UPGRADE.md +72 -0
  10. vinyasar-0.3.0/docs/baseline/TEST_REPORT.md +34 -0
  11. vinyasar-0.3.0/docs/baseline/installed-environment.txt +7 -0
  12. vinyasar-0.3.0/docs/baseline/installed-wheel-test-results.txt +1 -0
  13. vinyasar-0.3.0/docs/baseline/installed-wheel-test-results.xml +1 -0
  14. vinyasar-0.3.0/docs/baseline/source-test-results.txt +1 -0
  15. vinyasar-0.3.0/docs/baseline/source-test-results.xml +1 -0
  16. vinyasar-0.3.0/docs/baseline/wheel-smoke.txt +5 -0
  17. vinyasar-0.3.0/pyproject.toml +48 -0
  18. vinyasar-0.3.0/setup.cfg +4 -0
  19. vinyasar-0.3.0/src/vinyasar/__init__.py +21 -0
  20. vinyasar-0.3.0/src/vinyasar/__main__.py +3 -0
  21. vinyasar-0.3.0/src/vinyasar/cli.py +181 -0
  22. vinyasar-0.3.0/src/vinyasar/config.py +356 -0
  23. vinyasar-0.3.0/src/vinyasar/controller.py +287 -0
  24. vinyasar-0.3.0/src/vinyasar/diagnostics.py +121 -0
  25. vinyasar-0.3.0/src/vinyasar/errors.py +43 -0
  26. vinyasar-0.3.0/src/vinyasar/events.py +39 -0
  27. vinyasar-0.3.0/src/vinyasar/mcp_server.py +386 -0
  28. vinyasar-0.3.0/src/vinyasar/models.py +220 -0
  29. vinyasar-0.3.0/src/vinyasar/path_diagnostics.py +107 -0
  30. vinyasar-0.3.0/src/vinyasar/paths.py +135 -0
  31. vinyasar-0.3.0/src/vinyasar/playbooks.py +65 -0
  32. vinyasar-0.3.0/src/vinyasar/policy.py +77 -0
  33. vinyasar-0.3.0/src/vinyasar/profile.schema.json +289 -0
  34. vinyasar-0.3.0/src/vinyasar/reporting.py +166 -0
  35. vinyasar-0.3.0/src/vinyasar/run.schema.json +403 -0
  36. vinyasar-0.3.0/src/vinyasar/run.v1.schema.json +381 -0
  37. vinyasar-0.3.0/src/vinyasar/state.py +202 -0
  38. vinyasar-0.3.0/src/vinyasar/storage.py +189 -0
  39. vinyasar-0.3.0/src/vinyasar/util.py +86 -0
  40. vinyasar-0.3.0/src/vinyasar/yasarda_adapter.py +176 -0
  41. vinyasar-0.3.0/src/vinyasar.egg-info/PKG-INFO +115 -0
  42. vinyasar-0.3.0/src/vinyasar.egg-info/SOURCES.txt +84 -0
  43. vinyasar-0.3.0/src/vinyasar.egg-info/dependency_links.txt +1 -0
  44. vinyasar-0.3.0/src/vinyasar.egg-info/entry_points.txt +5 -0
  45. vinyasar-0.3.0/src/vinyasar.egg-info/requires.txt +9 -0
  46. vinyasar-0.3.0/src/vinyasar.egg-info/top_level.txt +2 -0
  47. vinyasar-0.3.0/src/yasarda/__init__.py +11 -0
  48. vinyasar-0.3.0/src/yasarda/__main__.py +2 -0
  49. vinyasar-0.3.0/src/yasarda/capabilities.py +19 -0
  50. vinyasar-0.3.0/src/yasarda/catalog.py +81 -0
  51. vinyasar-0.3.0/src/yasarda/cli.py +153 -0
  52. vinyasar-0.3.0/src/yasarda/engine.py +107 -0
  53. vinyasar-0.3.0/src/yasarda/errors.py +26 -0
  54. vinyasar-0.3.0/src/yasarda/mcp_server.py +247 -0
  55. vinyasar-0.3.0/src/yasarda/models.py +98 -0
  56. vinyasar-0.3.0/src/yasarda/plan.py +169 -0
  57. vinyasar-0.3.0/src/yasarda/policy.py +61 -0
  58. vinyasar-0.3.0/src/yasarda/remediation.py +69 -0
  59. vinyasar-0.3.0/src/yasarda/remediation.schema.json +319 -0
  60. vinyasar-0.3.0/src/yasarda/repository.py +190 -0
  61. vinyasar-0.3.0/src/yasarda/schema.py +47 -0
  62. vinyasar-0.3.0/src/yasarda/service.py +59 -0
  63. vinyasar-0.3.0/src/yasarda/transaction.py +402 -0
  64. vinyasar-0.3.0/src/yasarda/transforms.py +106 -0
  65. vinyasar-0.3.0/src/yasarda/util.py +97 -0
  66. vinyasar-0.3.0/src/yasarda/verification.py +48 -0
  67. vinyasar-0.3.0/tests/__init__.py +0 -0
  68. vinyasar-0.3.0/tests/conftest.py +29 -0
  69. vinyasar-0.3.0/tests/fixtures/yasarda-0.2.0-py3-none-any.whl +0 -0
  70. vinyasar-0.3.0/tests/test_adversarial_assault.py +566 -0
  71. vinyasar-0.3.0/tests/test_cli.py +18 -0
  72. vinyasar-0.3.0/tests/test_config.py +106 -0
  73. vinyasar-0.3.0/tests/test_controller.py +209 -0
  74. vinyasar-0.3.0/tests/test_mcp.py +84 -0
  75. vinyasar-0.3.0/tests/test_paths_revision.py +270 -0
  76. vinyasar-0.3.0/tests/test_policy.py +53 -0
  77. vinyasar-0.3.0/tests/test_review_regressions.py +655 -0
  78. vinyasar-0.3.0/tests/test_state.py +37 -0
  79. vinyasar-0.3.0/tests/yasarda_tests/__init__.py +0 -0
  80. vinyasar-0.3.0/tests/yasarda_tests/conftest.py +5 -0
  81. vinyasar-0.3.0/tests/yasarda_tests/test_audit_regressions.py +85 -0
  82. vinyasar-0.3.0/tests/yasarda_tests/test_cli.py +30 -0
  83. vinyasar-0.3.0/tests/yasarda_tests/test_core.py +180 -0
  84. vinyasar-0.3.0/tests/yasarda_tests/test_hardening.py +502 -0
  85. vinyasar-0.3.0/tests/yasarda_tests/test_interfaces.py +262 -0
  86. vinyasar-0.3.0/tests/yasarda_tests/test_supervisor_recovery_limits.py +59 -0
@@ -0,0 +1,126 @@
1
+ # Changelog
2
+
3
+ ## 0.2.2
4
+
5
+ Consolidated native macOS Darwin arm64 adversarial qualification suite (18 attack
6
+ vectors covering path symlink boundaries, multi-process races, reservation crash
7
+ semantics, staged publication healing, digest tampering, payload fuzzing, and MCP
8
+ argument containment). Total Vinyasar test count expanded to 123 tests (257 total tests
9
+ with Yasarda 0.3.1). Confirmed clean Darwin arm64 platform qualification with zero runtime
10
+ regressions. No changes to Yasarda 0.3.1 or transaction/profile/run schemas.
11
+
12
+ ## 0.2.1
13
+
14
+ Canonicalize host-supplied repository, state, report and environment/default
15
+ paths during init only; canonicalize the output parent without following its
16
+ leaf or overwriting existing files. Existing JSON/YAML profiles and their source
17
+ paths remain link-strict. Add read-only SDK/CLI path diagnostics. Bound profile
18
+ reads and reject nonregular files before reading. Add alias, link-loop, race and
19
+ no-write tests. No changes to Yasarda 0.3.1 or transaction/profile/run schemas.
20
+
21
+ ## 0.2.0
22
+
23
+ Review-driven hardening: exact receipt plus fresh complete verification; host
24
+ recovery file/byte limits; cooperative deadlines and bounded locks; whole-target
25
+ serialization; durable run/action identity; conservative crash reconstruction;
26
+ stable retry budgets and explicit host-only legacy adoption; bounded/redacted
27
+ diagnostics; schema-v2 canonical integrity and references; staged no-overwrite
28
+ report publication; parent-link/read guards; accurate MCP error/replay behavior;
29
+ correct CloudEvents payload schema handling. No new mutation capability.
30
+
31
+ ## 0.1.0
32
+
33
+ Original bounded supervisor over Yasarda 0.3.0. Original test evidence is retained
34
+ under docs/baseline and is not evidence for this release.
35
+
36
+
37
+ # Historical Yasarda Changelog
38
+
39
+
40
+ # Changelog
41
+
42
+ ## 0.3.1
43
+
44
+ Preflight file count, per-file byte size and total bytes on each snapshot side
45
+ before recovery or explicit rollback can restore any file. Existing exact-byte,
46
+ mode, path, policy, journal and divergence guards are unchanged. The plan
47
+ compatibility marker remains 0.2.1; original 0.2.0 journals remain incompatible.
48
+
49
+ # Changelog
50
+
51
+ ## 0.3.0 - 2026-09-09
52
+
53
+ Public supervisor boundary for the separately packaged Vinyasar 0.1.0 release.
54
+
55
+ - Add `Engine.pending_operations()` as the supported read-only recovery-status
56
+ API; callers no longer need to inspect transaction journals directly.
57
+ - Add `Repository.mutation_filesystem_issue()` so supervisors can explain a
58
+ storage refusal without attempting mutation.
59
+ - Add `Service.operations()` and advertise `inspect_operations` in capability
60
+ metadata.
61
+ - Apply the same known cloud/remote filesystem refusal to Yasarda's journal state
62
+ directory; local repository bytes are not mutated when durable recovery state
63
+ is configured on unsupported storage.
64
+ - Keep all transaction serialization, staging, rollback, and conditional restore
65
+ behavior private and unchanged.
66
+
67
+ ## 0.2.1 - 2026-09-09
68
+
69
+ Patch hardening release; local artifacts only.
70
+
71
+ - Refuse mutation and recovery in known iCloud/macOS cloud-storage paths and
72
+ known Linux remote/FUSE mounts unless the host explicitly opts in.
73
+ - Reject a `build_server(repo=Repository(...), policy=...)` configuration when
74
+ the supplied policy conflicts with the policy already bound to the repository.
75
+ - Deprecate the legacy `allow_commands=True` SDK argument visibly; it still never
76
+ enables command execution.
77
+ - Add Python 3.14 metadata and regression tests for filesystem detection, host
78
+ override behavior, MCP policy conflicts, and the deprecated command flag.
79
+
80
+ ## 0.2.0 - 2026-09-09
81
+
82
+ Hardening of the supplied 0.1.0 package. Local artifacts only; not published.
83
+
84
+ ### Correctness
85
+
86
+ - Fixed the eight supplied audit cases: repeated replacement, conflicting edits,
87
+ missing desired-state verification, direct SDK dependency bypass, invalid
88
+ counts, contradictory hashes, newline rewriting, and symlink-target deletion.
89
+ - Enforced the packaged JSON Schema, duplicate-key checks, strict field types,
90
+ path validation, graph validation, output-size bounds, and final-state checks.
91
+ - Kept transforms pure; only the shared execution engine writes destination files.
92
+
93
+ ### Execution
94
+
95
+ - Added immutable saved plans and exact-digest approval, whole-file input/output
96
+ fingerprints, branch/HEAD binding, scoped dependency snapshots, and mode guards.
97
+ - Added external private state, cooperative writer locks, output staging, journals,
98
+ verified retries, guarded rollback, and interrupted-operation recovery.
99
+ - Refuses unknown third-party changes, pending recovery, protected paths, bare Git
100
+ object stores, links, case-fold collisions, and unsupported file types.
101
+
102
+ ### Interfaces
103
+
104
+ - SDK, CLI, and MCP share Engine and Service; no interface-specific transforms.
105
+ - CLI supports saved-plan execution, receipts, recovery, rollback, and operating
106
+ modes. Immediate local `apply --yes` remains for trusted callers.
107
+ - MCP is now built into the base distribution as a small stdio tools/resources
108
+ adapter. No external `mcp` package is needed. Root scope and approval are set by
109
+ the host; tool callers cannot widen them. MCP defaults to read-only.
110
+
111
+ ### Deliberate compatibility changes
112
+
113
+ - Multiple transformations of one file are rejected, not sequentially guessed.
114
+ - Unrecognized manifest fields/types fail rather than being ignored/coerced.
115
+ - Arbitrary command verification is unsupported, including when the old SDK
116
+ `allow_commands=True` argument is passed. Such checks fail before publication.
117
+ - The old MCP `apply_remediation(execute=True, repo_path=..., allow_commands=...)`
118
+ surface is replaced by saved-plan execution with independent host authorization.
119
+ - `init --force` and implicit catalog overwrites are removed. Author catalogs as
120
+ explicit files or copy the example into a disposable directory.
121
+ - Mutation is currently restricted to POSIX local filesystems. No cross-platform
122
+ or network-filesystem guarantees were inferred from the Linux test run.
123
+
124
+ No product service, marketplace, automatic model decisions, or DUD3-specific
125
+ remediation catalog was added. No publication license was selected on the user's
126
+ behalf; choose one before any public distribution.
@@ -0,0 +1,8 @@
1
+ include src/vinyasar/profile.schema.json
2
+ include src/vinyasar/run.schema.json
3
+ include CHANGELOG.md
4
+ recursive-include tests *.py
5
+ recursive-include docs *.md *.txt *.xml
6
+
7
+ include src/vinyasar/run.v1.schema.json
8
+ recursive-include tests/fixtures *.whl
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: vinyasar
3
+ Version: 0.3.0
4
+ Summary: Policy-driven, evidence-bound self-healing supervision for Yasarda (unified engine).
5
+ Keywords: automation,self-healing,agents,yasarda,mcp,codemod,remediation,repository
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Environment :: Console
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Classifier: Topic :: Software Development :: Version Control :: Git
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: jsonschema<5,>=4.23
18
+ Provides-Extra: yaml
19
+ Requires-Dist: PyYAML<7,>=6.0.2; extra == "yaml"
20
+ Provides-Extra: mcp
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest<10,>=8; extra == "dev"
23
+
24
+ # Vinyasar 0.2.1
25
+
26
+ A bounded policy-driven supervisor for Yasarda, not an autonomous code writer.
27
+ It has one mutating playbook: recover an interrupted Yasarda transaction to its
28
+ original file state. Recovery does not finish applying the interrupted patch.
29
+
30
+ The same Controller serves Python SDK, CLI and MCP. Models can propose changes,
31
+ but cannot create playbooks, change pinned roots or grant authority through MCP.
32
+
33
+ ## Install
34
+
35
+ Install the supplied Yasarda 0.3.1 and Vinyasar 0.2.1 wheels into a dedicated
36
+ virtual environment. This delivery is local; it has not been published to PyPI.
37
+
38
+ ```sh
39
+ python -m pip install ./yasarda-0.3.1-py3-none-any.whl ./vinyasar-0.2.0-py3-none-any.whl
40
+ vinyasar --version
41
+ vinyasar validate /private/profile.json
42
+ vinyasar inspect /private/profile.json --trigger-id review-001
43
+ ```
44
+
45
+ CLI `inspect` produces a dry-run record in the configured state/report storage;
46
+ it does not repair the target. MCP `inspect_target` only inspects, without writing
47
+ reports. Review the profile's authority before invoking `vinyasar run`: a generated
48
+ profile can enable automatic recovery when setup checks consider storage eligible.
49
+
50
+ ```sh
51
+ vinyasar run /private/profile.json --trigger manual --trigger-id event-001
52
+ vinyasar-mcp --config /private/profile.json
53
+ ```
54
+
55
+ Reusing the same trigger replays the same run. Use a new trigger for a new health
56
+ check. All cooperating processes must share the same canonical state roots.
57
+
58
+ ## Changed in this version
59
+
60
+ Fresh verification requires complete detector coverage and an exact rolled-back
61
+ receipt. Recovery preflights file counts and byte limits in Yasarda itself.
62
+ Durable run intent precedes attempt reservation; reserved uncertain actions are
63
+ not blindly reissued after a crash. Whole-target locks serialize local workers.
64
+
65
+ Retry budgets survive cosmetic profile edits. Report storage is checked before
66
+ actions. Canonical reports are staged, fsynced and published without replacement,
67
+ with recovery for recognized staging/link crash windows. Report schema v2 adds
68
+ record integrity, final issues, inspection completeness and deadline status.
69
+ Diagnostics are bounded/redacted before durable serialization. Failed MCP
70
+ reconciliation returns isError=true; replay serialization is deterministic.
71
+
72
+ ## Upgrades and limits
73
+
74
+ Read [docs/UPGRADE.md](docs/UPGRADE.md) before replacing a running installation.
75
+ V1 reports are historical only. Legacy ledgers require host-only explicit
76
+ adoption. Original Yasarda 0.2.0 journals require matching-engine recovery first.
77
+
78
+ Linux/Python 3.13.5 was exercised for this iteration. Local POSIX mutation only;
79
+ no Windows mutation, macOS validation, distributed lock or same-user sandbox is
80
+ claimed. Timing is a cooperative deadline, not preemption of blocking filesystem
81
+ calls. Redaction is bounded allowlisting, not universal secret detection.
82
+
83
+ No scheduler installation, AST repair, network exporter, shell playbook, MCP
84
+ Tasks or A2A adapter was added. Builds and application performance require their
85
+ own independently authorized workers and evidence. See SAFETY.md for the boundary.
86
+
87
+
88
+ ## Host initialization and pinned paths (0.2.1)
89
+
90
+ `vinyasar init` is the explicit host setup boundary. It resolves supplied path
91
+ aliases once and writes canonical absolute repository, Yasarda-state,
92
+ Vinyasar-state and report paths into a **new** profile. This includes home and
93
+ YASARDA_STATE_DIR defaults. Missing state directories are not created; the nearest
94
+ existing prefix is resolved strictly so dangling links and loops are refused.
95
+ The profile output parent must already exist and be private. Its final component
96
+ is never followed if linked and existing files are never overwritten.
97
+
98
+ Loading an existing profile does not canonicalize links away. Both the profile
99
+ file path and its configured paths must be link-free; relative configured entries
100
+ remain compatible and are interpreted relative to the canonical profile parent.
101
+ A linked `/var/...` source profile must be supplied explicitly as its canonical
102
+ `/private/var/...` path. YAML uses the same bounded regular-file loader.
103
+
104
+ `vinyasar doctor paths PROFILE` (or `vinyasar.doctor_paths(PROFILE)`) reports supplied
105
+ and canonical path names, missing locations, and private-directory permission
106
+ issues as JSON. It writes nothing, does not instantiate Controller, and never
107
+ changes modes or follows a linked profile to read it. Exit 0 means these path and
108
+ configuration checks passed; exit 2 reports a problem. The diagnostic explicitly
109
+ sets `mutation_authorized: false` and `storage_eligibility: not_assessed`.
110
+ It is not a sandbox, lock, filesystem certification, or approval to repair.
111
+
112
+ Python path semantics reference: https://docs.python.org/3.13/library/pathlib.html
113
+ (`Path.resolve(strict=True)`, strict loop and missing-path handling). Descriptor
114
+ read guards reference: https://docs.python.org/3/library/os.html (`dir_fd`,
115
+ `O_NOFOLLOW`, `O_NONBLOCK`, `fstat`). Runtime mutation/storage guards are unchanged.
@@ -0,0 +1,92 @@
1
+ # Vinyasar 0.2.1
2
+
3
+ A bounded policy-driven supervisor for Yasarda, not an autonomous code writer.
4
+ It has one mutating playbook: recover an interrupted Yasarda transaction to its
5
+ original file state. Recovery does not finish applying the interrupted patch.
6
+
7
+ The same Controller serves Python SDK, CLI and MCP. Models can propose changes,
8
+ but cannot create playbooks, change pinned roots or grant authority through MCP.
9
+
10
+ ## Install
11
+
12
+ Install the supplied Yasarda 0.3.1 and Vinyasar 0.2.1 wheels into a dedicated
13
+ virtual environment. This delivery is local; it has not been published to PyPI.
14
+
15
+ ```sh
16
+ python -m pip install ./yasarda-0.3.1-py3-none-any.whl ./vinyasar-0.2.0-py3-none-any.whl
17
+ vinyasar --version
18
+ vinyasar validate /private/profile.json
19
+ vinyasar inspect /private/profile.json --trigger-id review-001
20
+ ```
21
+
22
+ CLI `inspect` produces a dry-run record in the configured state/report storage;
23
+ it does not repair the target. MCP `inspect_target` only inspects, without writing
24
+ reports. Review the profile's authority before invoking `vinyasar run`: a generated
25
+ profile can enable automatic recovery when setup checks consider storage eligible.
26
+
27
+ ```sh
28
+ vinyasar run /private/profile.json --trigger manual --trigger-id event-001
29
+ vinyasar-mcp --config /private/profile.json
30
+ ```
31
+
32
+ Reusing the same trigger replays the same run. Use a new trigger for a new health
33
+ check. All cooperating processes must share the same canonical state roots.
34
+
35
+ ## Changed in this version
36
+
37
+ Fresh verification requires complete detector coverage and an exact rolled-back
38
+ receipt. Recovery preflights file counts and byte limits in Yasarda itself.
39
+ Durable run intent precedes attempt reservation; reserved uncertain actions are
40
+ not blindly reissued after a crash. Whole-target locks serialize local workers.
41
+
42
+ Retry budgets survive cosmetic profile edits. Report storage is checked before
43
+ actions. Canonical reports are staged, fsynced and published without replacement,
44
+ with recovery for recognized staging/link crash windows. Report schema v2 adds
45
+ record integrity, final issues, inspection completeness and deadline status.
46
+ Diagnostics are bounded/redacted before durable serialization. Failed MCP
47
+ reconciliation returns isError=true; replay serialization is deterministic.
48
+
49
+ ## Upgrades and limits
50
+
51
+ Read [docs/UPGRADE.md](docs/UPGRADE.md) before replacing a running installation.
52
+ V1 reports are historical only. Legacy ledgers require host-only explicit
53
+ adoption. Original Yasarda 0.2.0 journals require matching-engine recovery first.
54
+
55
+ Linux/Python 3.13.5 was exercised for this iteration. Local POSIX mutation only;
56
+ no Windows mutation, macOS validation, distributed lock or same-user sandbox is
57
+ claimed. Timing is a cooperative deadline, not preemption of blocking filesystem
58
+ calls. Redaction is bounded allowlisting, not universal secret detection.
59
+
60
+ No scheduler installation, AST repair, network exporter, shell playbook, MCP
61
+ Tasks or A2A adapter was added. Builds and application performance require their
62
+ own independently authorized workers and evidence. See SAFETY.md for the boundary.
63
+
64
+
65
+ ## Host initialization and pinned paths (0.2.1)
66
+
67
+ `vinyasar init` is the explicit host setup boundary. It resolves supplied path
68
+ aliases once and writes canonical absolute repository, Yasarda-state,
69
+ Vinyasar-state and report paths into a **new** profile. This includes home and
70
+ YASARDA_STATE_DIR defaults. Missing state directories are not created; the nearest
71
+ existing prefix is resolved strictly so dangling links and loops are refused.
72
+ The profile output parent must already exist and be private. Its final component
73
+ is never followed if linked and existing files are never overwritten.
74
+
75
+ Loading an existing profile does not canonicalize links away. Both the profile
76
+ file path and its configured paths must be link-free; relative configured entries
77
+ remain compatible and are interpreted relative to the canonical profile parent.
78
+ A linked `/var/...` source profile must be supplied explicitly as its canonical
79
+ `/private/var/...` path. YAML uses the same bounded regular-file loader.
80
+
81
+ `vinyasar doctor paths PROFILE` (or `vinyasar.doctor_paths(PROFILE)`) reports supplied
82
+ and canonical path names, missing locations, and private-directory permission
83
+ issues as JSON. It writes nothing, does not instantiate Controller, and never
84
+ changes modes or follows a linked profile to read it. Exit 0 means these path and
85
+ configuration checks passed; exit 2 reports a problem. The diagnostic explicitly
86
+ sets `mutation_authorized: false` and `storage_eligibility: not_assessed`.
87
+ It is not a sandbox, lock, filesystem certification, or approval to repair.
88
+
89
+ Python path semantics reference: https://docs.python.org/3.13/library/pathlib.html
90
+ (`Path.resolve(strict=True)`, strict loop and missing-path handling). Descriptor
91
+ read guards reference: https://docs.python.org/3/library/os.html (`dir_fd`,
92
+ `O_NOFOLLOW`, `O_NONBLOCK`, `fstat`). Runtime mutation/storage guards are unchanged.
@@ -0,0 +1,28 @@
1
+ # Vinyasar 0.2.0 architecture
2
+
3
+ Validated pinned profile -> target run lock -> canonical replay or durable run
4
+ checkpoint -> complete deterministic inspection -> bounded policy decision ->
5
+ durable action intent -> persistent attempt reservation -> reviewed playbook ->
6
+ public Yasarda action -> matching receipt and fresh inspection -> terminal run
7
+ checkpoint -> canonical JSON -> deterministic Markdown/CloudEvents projection.
8
+
9
+ `Controller` is the only reconciliation implementation. `YasardaTarget` implements
10
+ the typed Target interface. Setup probes and engine calls stay in that adapter.
11
+ `StateStore` owns stable incident budgets and explicit legacy adoption. `RunStore`
12
+ owns request-bound intent and terminal checkpoints. `storage` owns descriptor-
13
+ relative private records, bounded locks and no-overwrite staged publication.
14
+ `diagnostics` bounds and redacts before durable records. `ReportWriter` validates
15
+ schema-v2 identity/digests/references and projects Markdown. CLI/MCP delegate.
16
+
17
+ Yasarda 0.3.1 adds resource enforcement to its existing public recover operation;
18
+ it retains plan compatibility marker 0.2.1. The supervisor does not become a
19
+ second file transformer. Profiles retain the v1alpha1 API with two optional byte
20
+ limits. Reports explicitly version to schema 2 rather than reinterpreting v1.
21
+
22
+ Terminal reports describe history. New trigger IDs request new inspections;
23
+ identical IDs reconstruct or replay existing work. After reservation, replay can
24
+ verify a completed receipt but cannot assume an unreturned action never ran.
25
+
26
+ Only local cooperating workers are coordinated. Protocol adapters and exporters
27
+ are views over records, never evidence authorizing another repair. Scheduler
28
+ planning/exporters/extra playbooks remain future work, not present features.
@@ -0,0 +1,21 @@
1
+ # Vinyasar implementation handoff
2
+
3
+ Version 0.2.1 pairs with Yasarda >=0.3.1,<0.4. Read SAFETY.md and UPGRADE.md first.
4
+ Original test modules are preserved unchanged; new test_review_regressions.py
5
+ contains review reproductions and process/storage failure tests. Its original
6
+ independent review module is retained in the release evidence; four fixture or
7
+ contract adaptations are documented at the bundle root.
8
+
9
+ Keep single Controller/public adapter boundaries, strict profiles, finite attempt
10
+ budgets, durable intent and conservative unknown-state refusal. Do not silently
11
+ promote v1 reports or alter old plan version markers. Models and protocol callers
12
+ cannot supply arbitrary executable playbooks or expand authority.
13
+
14
+ The user supplied Vector's macOS arm64/CPython 3.12.11 validation for the
15
+ exact 0.2.0 baseline: 207 active tests and both MCP smoke tools passed, with a
16
+ canonical-temp-path workaround. This is reported external evidence, not a local
17
+ rerun. The modified 0.2.1 release still needs its own native macOS run.
18
+ Next bounded work: tools/validate_platform.py on macOS and preserved-journal
19
+ upgrade rehearsal. Do not carry baseline platform qualification to changed code. Do not install schedulers,
20
+ publish packages, push repositories, choose licenses or run cloud mutations based
21
+ on this document. The bundle AGENT_HANDOFF.json describes current evidence.
@@ -0,0 +1,108 @@
1
+ # Vinyasar 0.2.1 safety contract
2
+
3
+ ## Authority and verification
4
+
5
+ One Controller owns reconciliation. A validated host profile, built-in playbook
6
+ and runtime capability are all required. The only mutating playbook recovers an
7
+ interrupted Yasarda transaction. Engine calls go through yasarda_adapter; no
8
+ production supervisor imports transaction internals. Test fixtures alone use
9
+ private journal helpers to simulate interrupted publication.
10
+
11
+ MCP retains its four tools; callers cannot choose roots, policy, playbooks or
12
+ approvals. CLI/SDK are privileged host interfaces. The new adopt-ledger command
13
+ requires explicit host confirmation and is not an MCP tool.
14
+
15
+ Verification requires complete fresh pending-operation inspection, absence of
16
+ the original incident, and a matching receipt with state rolled_back. A final
17
+ inspection can revoke provisional success. INSPECTION_FAILED is never absence
18
+ proof. Unresolved IDs have final issue/evidence records. None of this proves
19
+ application health, build success or performance.
20
+
21
+ ## Durable execution
22
+
23
+ Whole-target locks serialize cooperating workers at the same state location.
24
+ Attempts use a stable target/recovery-store namespace, not cosmetic profile
25
+ metadata. Incident/run locks have bounded waits. Digest-checked budget ledgers
26
+ reject accidental counter corruption. Durable intent precedes reservation;
27
+ reservation tokens prevent double accounting. A crash after reservation consumes
28
+ an attempt even when the action has not yet started.
29
+
30
+ Replay never blindly repeats an uncertain action. It checks the public Yasarda
31
+ receipt and current target to reconstruct completed recovery; otherwise it records
32
+ the uncertainty/failure. A new trigger may retry within the remaining budget.
33
+ Completed records are checkpointed before final report publication. Replaying a
34
+ completed report returns historical evidence, not a new health assessment.
35
+
36
+ ## Resources
37
+
38
+ Yasarda preflights the full recovery snapshot: file count, per-file bytes and
39
+ total bytes on each side. Exceeding a limit refuses the entire restoration.
40
+ Observation counts, diagnostic fields, serialized inspections and reports are
41
+ bounded before persistence. Canonical write/read share a 1 MiB record limit.
42
+
43
+ Runtime is a cooperative deadline: bound lock waits, stop admitting work, report
44
+ observed overruns. Blocking target adapters, filesystem calls and final report
45
+ fsync can outlive it. No unsafe mid-transaction kill is used to fake a hard limit.
46
+
47
+ ## Storage and reporting
48
+
49
+ State/report directories are owner-only, same-user, canonical POSIX directories.
50
+ Ancestors are opened without following links. Existing permissions are not
51
+ silently changed. Read guards reject links, nonregular files, unsafe permissions
52
+ and oversized content. The only allowed two-link exception is an exact same-inode
53
+ canonical/staging pair left by the documented publication crash window.
54
+
55
+ Canonical bytes are fsynced in staging, linked to an absent destination, then
56
+ staging is unlinked and the directory synchronized. Only exact bytes or an exact
57
+ prefix in the reserved staging name may be resumed. Unknown bytes are preserved
58
+ and refused. JSON precedes Markdown; missing identical Markdown can be regenerated
59
+ on replay. Conflicting Markdown is not overwritten. No retention/cleanup job was
60
+ added; recognized staging cleanup is part of its own publication protocol.
61
+
62
+ Reports validate record/evidence digests, request binding and internal references.
63
+ Checkpoints are separate from canonical reports. Required storage is preflighted
64
+ before actions, but later disk failure remains possible. Checkpoints and underlying
65
+ receipts retain the information needed for a subsequent same-trigger replay.
66
+
67
+ ## Privacy and explicit non-guarantees
68
+
69
+ Free-form diagnostics and arbitrary facts are redacted/bounded before checkpoints
70
+ or reports. Explicit identifiers remain visible; never put secrets in identifiers.
71
+ This is not a universal secret scanner; hashes can reveal guessable low-entropy
72
+ values. With redaction disabled, only bounded diagnostic content is retained.
73
+
74
+ Digests detect corruption, not a writer able to rewrite content and digests. No
75
+ hostile same-user containment, distributed coordination, power-loss proof,
76
+ cryptographic authenticity or filesystem-wide compare-and-swap is claimed.
77
+ Storage checks identify known unsupported locations but do not certify every
78
+ accepted filesystem. Preserve state and keep external writers out.
79
+
80
+
81
+ ## Host initialization and pinned paths (0.2.1)
82
+
83
+ `vinyasar init` is the explicit host setup boundary. It resolves supplied path
84
+ aliases once and writes canonical absolute repository, Yasarda-state,
85
+ Vinyasar-state and report paths into a **new** profile. This includes home and
86
+ YASARDA_STATE_DIR defaults. Missing state directories are not created; the nearest
87
+ existing prefix is resolved strictly so dangling links and loops are refused.
88
+ The profile output parent must already exist and be private. Its final component
89
+ is never followed if linked and existing files are never overwritten.
90
+
91
+ Loading an existing profile does not canonicalize links away. Both the profile
92
+ file path and its configured paths must be link-free; relative configured entries
93
+ remain compatible and are interpreted relative to the canonical profile parent.
94
+ A linked `/var/...` source profile must be supplied explicitly as its canonical
95
+ `/private/var/...` path. YAML uses the same bounded regular-file loader.
96
+
97
+ `vinyasar doctor paths PROFILE` (or `vinyasar.doctor_paths(PROFILE)`) reports supplied
98
+ and canonical path names, missing locations, and private-directory permission
99
+ issues as JSON. It writes nothing, does not instantiate Controller, and never
100
+ changes modes or follows a linked profile to read it. Exit 0 means these path and
101
+ configuration checks passed; exit 2 reports a problem. The diagnostic explicitly
102
+ sets `mutation_authorized: false` and `storage_eligibility: not_assessed`.
103
+ It is not a sandbox, lock, filesystem certification, or approval to repair.
104
+
105
+ Python path semantics reference: https://docs.python.org/3.13/library/pathlib.html
106
+ (`Path.resolve(strict=True)`, strict loop and missing-path handling). Descriptor
107
+ read guards reference: https://docs.python.org/3/library/os.html (`dir_fd`,
108
+ `O_NOFOLLOW`, `O_NONBLOCK`, `fstat`). Runtime mutation/storage guards are unchanged.
@@ -0,0 +1,6 @@
1
+ # Validation for this source revision
2
+
3
+ 73 source tests pass in the resumed session on Linux/Python 3.13.5. Original
4
+ release evidence is clearly separated under baseline/. See the complete bundle's
5
+ docs/TEST_REPORT.md for final installed-wheel, subprocess, artifact and patch
6
+ checks. This source result is not a claim about any other platform or runtime.
@@ -0,0 +1,72 @@
1
+ # Upgrade without losing recovery history
2
+
3
+ ## Yasarda 0.3.0 to 0.3.1
4
+
5
+ Stop cooperating writers first. Retain the same repository and Yasarda state
6
+ paths. The plan compatibility marker remains 0.2.1; compatible journals retain
7
+ identity. Host file/byte limits can now refuse previously unbounded recovery.
8
+ Review the complete footprint rather than blindly widening limits.
9
+
10
+ ## Original Yasarda 0.2.0
11
+
12
+ The originally delivered 0.2.0 wheel has a different plan identity marker. The
13
+ new engine deliberately refuses those journals. Never edit `engine_version`,
14
+ regenerate a journal digest, or relabel an old plan to make it pass validation.
15
+
16
+ Use an isolated environment with the exact trusted old wheel. Review every
17
+ pending operation with that version's doctor and receipt commands, then invoke
18
+ its guarded recovery with explicit approval. For example:
19
+
20
+ ```sh
21
+ /path/to/old-env/bin/yasarda --repo /canonical/local/repo \
22
+ --state-dir /private/old-yasarda-state doctor
23
+ /path/to/old-env/bin/yasarda --repo /canonical/local/repo \
24
+ --state-dir /private/old-yasarda-state recover OPERATION_ID \
25
+ --approve OPERATION_ID --yes
26
+ ```
27
+
28
+ Verify the returned receipt and repository bytes, including refusal on newer
29
+ edits. Resolve every old pending operation before switching. Retain the old
30
+ journals for the matching engine to read. Only then point the new installation
31
+ at an explicitly chosen, separate new Yasarda journal directory.
32
+
33
+ The regression fixture performs real old-engine recovery, retains its completed
34
+ journal, and observes the restored repository through the new engine and new
35
+ state directory. This is a tested operator procedure, not automatic migration.
36
+
37
+ ## Vinyasar 0.1.0 to 0.2.0
38
+
39
+ Pause callers/schedulers and preserve the original profiles, reports and ledgers.
40
+ Use a distinct report directory for schema-v2 records. Keep the supervisor state
41
+ directory so retry history cannot silently disappear. Authoritative v2 replay
42
+ refuses v1 reports; `run.v1.schema.json` is retained for historical inspection.
43
+
44
+ Legacy retry ledgers lack reliable target identity. The host must identify the
45
+ old profile revisions that belong to this target. Import each exact revision:
46
+
47
+ ```sh
48
+ vinyasar adopt-ledger /private/profile.json \
49
+ --legacy-revision EXACT_64_CHARACTER_REVISION --yes
50
+ ```
51
+
52
+ This preserves the old file, pins its digest, conservatively merges counters,
53
+ and refuses a changed adopted file. Unrecognized legacy ledgers block actions.
54
+ This command is not exposed by MCP. Do not guess ownership when unrelated targets
55
+ shared a legacy state directory; resolve that configuration explicitly first.
56
+
57
+ Use fresh event IDs for new scheduler events. Reusing a completed trigger requests
58
+ historical replay, not a fresh health check. After an interrupted 0.2.0 run, retry
59
+ its identical trigger to reconstruct and finish reporting its actual history.
60
+ An indeterminate reserved action is not reissued by that replay; a separate new
61
+ trigger may attempt recovery within the remaining budget.
62
+
63
+ ## Coordination and scope
64
+
65
+ Cooperating workers must use the same canonical target and state roots. Changing
66
+ those roots changes coordination identity. Do not select empty state merely to
67
+ bypass an exhausted budget or pending operation. Keep unrelated writers out.
68
+
69
+ State/report directories must be private and owned by the executing user. Wrong
70
+ permissions and links are refused rather than silently chmodded or followed.
71
+ Run mutation tests only in disposable local POSIX directories, never a cloud
72
+ synced user checkout. No completed v1 report gains v2 guarantees retroactively.
@@ -0,0 +1,34 @@
1
+ # Vinyasar 0.1.0 verification report
2
+
3
+ Date: 2026-09-09
4
+ Platform: macOS 26.6.2 arm64
5
+ Python: 3.14.6
6
+
7
+ ## Results
8
+
9
+ | Run | Result |
10
+ | --- | --- |
11
+ | Source suite | 20 passed, 0 failed, 0 skipped |
12
+ | Ruff static checks | Passed |
13
+ | Ruff format check | Passed |
14
+ | Wheel and source distribution build | Passed |
15
+ | Installed wheel, Python 3.14 clean environment | 20 passed, 0 failed, 0 skipped |
16
+ | Installed wheel, Python 3.12 clean environment | 20 passed, 0 failed, 0 skipped |
17
+ | Installed `vinyasar --version` | Passed; version 0.1.0 |
18
+ | Installed `vinyasar-mcp --help` | Passed |
19
+ | Installed generated-profile validate/inspect/run smoke | Passed |
20
+ | Installed dependency check | All packages compatible |
21
+
22
+ Coverage includes profile generation/validation, duplicate and overlapping
23
+ configuration rejection, monotonic policy decisions, evidence-bound approvals,
24
+ unknown-issue escalation, persistent cooldown and attempt budgets, dry runs,
25
+ idempotent trigger replay, append-only reports, CloudEvents envelopes, fixed-scope
26
+ MCP arguments, explicit journal-state pinning, three-store filesystem gating, and
27
+ a real guarded recovery through Yasarda's public Engine API.
28
+ The installed suites ran with an empty `PYTHONPATH`; imports resolved from each
29
+ clean virtual environment's `site-packages` directory. A setup probe against the
30
+ actual iCloud Desktop generated escalation-only recovery policy as designed.
31
+
32
+ No test claims hardware power-loss safety, hostile same-user isolation, remote or
33
+ cloud filesystem mutation safety, semantic application correctness, or
34
+ cryptographic receipt authenticity.
@@ -0,0 +1,7 @@
1
+ Platform: macOS 26.6.2 arm64
2
+ Python 3.14: 3.14.6
3
+ Python 3.12: 3.12.13
4
+ Yasarda: 0.3.0
5
+ Vinyasar: 0.1.0
6
+ jsonschema: 4.26.0
7
+ pytest: 9.1.1
@@ -0,0 +1 @@
1
+ 20 passed in 0.26s
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="20" time="0.166" timestamp="2026-09-09T12:26:56.609738-05:00" hostname="centaur-macmini-1"><testcase classname="tests.test_cli" name="test_cli_generates_valid_profile_without_overwrite" time="0.005" /><testcase classname="tests.test_config" name="test_generated_profile_is_normalized_and_revision_pinned" time="0.002" /><testcase classname="tests.test_config" name="test_profile_rejects_overlapping_rules" time="0.002" /><testcase classname="tests.test_config" name="test_profile_rejects_report_storage_inside_target" time="0.002" /><testcase classname="tests.test_config" name="test_load_rejects_duplicate_json_keys" time="0.001" /><testcase classname="tests.test_config" name="test_observe_rule_cannot_smuggle_capability" time="0.002" /><testcase classname="tests.test_config" name="test_profile_requires_a_pinned_yasarda_state_directory" time="0.003" /><testcase classname="tests.test_config" name="test_generated_profile_escalates_when_automation_state_is_cloud_synced" time="0.001" /><testcase classname="tests.test_controller" name="test_healthy_run_writes_append_only_reports" time="0.003" /><testcase classname="tests.test_controller" name="test_exact_approval_can_resume_on_a_new_trigger" time="0.004" /><testcase classname="tests.test_controller" name="test_dry_run_never_invokes_playbook" time="0.002" /><testcase classname="tests.test_controller" name="test_real_yasarda_pending_operation_is_recovered" time="0.099" /><testcase classname="tests.test_controller" name="test_events_are_cloudevents_compatible" time="0.005" /><testcase classname="tests.test_controller" name="test_volatile_evidence_does_not_reset_incident_attempt_budget" time="0.008" /><testcase classname="tests.test_mcp" name="test_mcp_surface_is_fixed_and_reconciles" time="0.003" /><testcase classname="tests.test_mcp" name="test_mcp_rejects_caller_scope_arguments" time="0.001" /><testcase classname="tests.test_policy" name="test_approval_id_is_exact_and_evidence_bound" time="0.002" /><testcase classname="tests.test_policy" name="test_mismatched_capability_escalates" time="0.002" /><testcase classname="tests.test_policy" name="test_unknown_issue_cannot_gain_action_authority" time="0.001" /><testcase classname="tests.test_state" name="test_attempt_budget_and_cooldown_are_persistent" time="0.002" /></testsuite></testsuites>
@@ -0,0 +1 @@
1
+ 20 passed in 0.17s
@@ -0,0 +1 @@
1
+ <?xml version="1.0" encoding="utf-8"?><testsuites><testsuite name="pytest" errors="0" failures="0" skipped="0" tests="20" time="0.171" timestamp="2026-09-09T12:25:50.989915-05:00" hostname="centaur-macmini-1"><testcase classname="tests.test_cli" name="test_cli_generates_valid_profile_without_overwrite" time="0.006" /><testcase classname="tests.test_config" name="test_generated_profile_is_normalized_and_revision_pinned" time="0.001" /><testcase classname="tests.test_config" name="test_profile_rejects_overlapping_rules" time="0.002" /><testcase classname="tests.test_config" name="test_profile_rejects_report_storage_inside_target" time="0.002" /><testcase classname="tests.test_config" name="test_load_rejects_duplicate_json_keys" time="0.001" /><testcase classname="tests.test_config" name="test_observe_rule_cannot_smuggle_capability" time="0.002" /><testcase classname="tests.test_config" name="test_profile_requires_a_pinned_yasarda_state_directory" time="0.002" /><testcase classname="tests.test_config" name="test_generated_profile_escalates_when_automation_state_is_cloud_synced" time="0.001" /><testcase classname="tests.test_controller" name="test_healthy_run_writes_append_only_reports" time="0.004" /><testcase classname="tests.test_controller" name="test_exact_approval_can_resume_on_a_new_trigger" time="0.004" /><testcase classname="tests.test_controller" name="test_dry_run_never_invokes_playbook" time="0.002" /><testcase classname="tests.test_controller" name="test_real_yasarda_pending_operation_is_recovered" time="0.110" /><testcase classname="tests.test_controller" name="test_events_are_cloudevents_compatible" time="0.003" /><testcase classname="tests.test_controller" name="test_volatile_evidence_does_not_reset_incident_attempt_budget" time="0.006" /><testcase classname="tests.test_mcp" name="test_mcp_surface_is_fixed_and_reconciles" time="0.002" /><testcase classname="tests.test_mcp" name="test_mcp_rejects_caller_scope_arguments" time="0.001" /><testcase classname="tests.test_policy" name="test_approval_id_is_exact_and_evidence_bound" time="0.002" /><testcase classname="tests.test_policy" name="test_mismatched_capability_escalates" time="0.002" /><testcase classname="tests.test_policy" name="test_unknown_issue_cannot_gain_action_authority" time="0.001" /><testcase classname="tests.test_state" name="test_attempt_budget_and_cooldown_are_persistent" time="0.002" /></testsuite></testsuites>