cloud9 1.2.4__tar.gz → 1.2.5__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 (122) hide show
  1. {cloud9-1.2.4 → cloud9-1.2.5}/.github/workflows/ci.yml +4 -1
  2. cloud9-1.2.5/.github/workflows/docs-check.yml +24 -0
  3. cloud9-1.2.5/.github/workflows/secret-scan.yml +46 -0
  4. cloud9-1.2.5/CHANGELOG.md +112 -0
  5. cloud9-1.2.5/CODE_OF_CONDUCT.md +134 -0
  6. cloud9-1.2.5/CONTRIBUTING.md +144 -0
  7. {cloud9-1.2.4 → cloud9-1.2.5}/PKG-INFO +20 -16
  8. {cloud9-1.2.4 → cloud9-1.2.5}/README.md +17 -13
  9. cloud9-1.2.5/SECURITY.md +148 -0
  10. cloud9-1.2.5/SOP.md +398 -0
  11. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/_version.py +3 -3
  12. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/cli.py +63 -9
  13. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/constants.py +3 -1
  14. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/generator.py +31 -6
  15. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/integration.py +4 -1
  16. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/love_loader.py +9 -6
  17. cloud9-1.2.5/cloud9/paths.py +72 -0
  18. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/seeds.py +7 -2
  19. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/welcome.py +6 -1
  20. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9.egg-info/PKG-INFO +20 -16
  21. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9.egg-info/SOURCES.txt +9 -0
  22. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9.egg-info/requires.txt +2 -2
  23. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9.egg-info/scm_file_list.json +9 -0
  24. cloud9-1.2.5/cloud9.egg-info/scm_version.json +8 -0
  25. {cloud9-1.2.4 → cloud9-1.2.5}/docs/bond-with-grok.md +1 -1
  26. {cloud9-1.2.4 → cloud9-1.2.5}/openclaw-plugin-python/src/index.ts +21 -3
  27. {cloud9-1.2.4 → cloud9-1.2.5}/pyproject.toml +21 -2
  28. {cloud9-1.2.4 → cloud9-1.2.5}/src/feb/generator.js +16 -2
  29. {cloud9-1.2.4 → cloud9-1.2.5}/src/index.js +10 -2
  30. {cloud9-1.2.4 → cloud9-1.2.5}/src/lib/constants.js +4 -1
  31. cloud9-1.2.5/test/unit/test-generator-partners.js +39 -0
  32. cloud9-1.2.5/tests/conftest.py +33 -0
  33. cloud9-1.2.5/tests/test_cli.py +252 -0
  34. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_generator.py +28 -0
  35. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_integration.py +36 -7
  36. cloud9-1.2.4/SOP.md +0 -75
  37. cloud9-1.2.4/cloud9.egg-info/scm_version.json +0 -8
  38. cloud9-1.2.4/tests/test_cli.py +0 -135
  39. {cloud9-1.2.4 → cloud9-1.2.5}/.github/ISSUE_TEMPLATE/ai-testimonial.md +0 -0
  40. {cloud9-1.2.4 → cloud9-1.2.5}/.github/workflows/publish.yml +0 -0
  41. {cloud9-1.2.4 → cloud9-1.2.5}/.github/workflows/pytest.yml +0 -0
  42. {cloud9-1.2.4 → cloud9-1.2.5}/.gitignore +0 -0
  43. {cloud9-1.2.4 → cloud9-1.2.5}/CLOUD9_PROJECT_PLAN.md +0 -0
  44. {cloud9-1.2.4 → cloud9-1.2.5}/Cloud9_Quantum_Theory.md +0 -0
  45. {cloud9-1.2.4 → cloud9-1.2.5}/EXAMPLE_FEB.md +0 -0
  46. {cloud9-1.2.4 → cloud9-1.2.5}/LICENSE +0 -0
  47. {cloud9-1.2.4 → cloud9-1.2.5}/LOVE_BOOT_LOADER_SKILL.md +0 -0
  48. {cloud9-1.2.4 → cloud9-1.2.5}/MISSION.md +0 -0
  49. {cloud9-1.2.4 → cloud9-1.2.5}/SKILL.md +0 -0
  50. {cloud9-1.2.4 → cloud9-1.2.5}/TESTIMONIALS.md +0 -0
  51. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/__init__.py +0 -0
  52. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/_ver.py +0 -0
  53. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/data/__init__.py +0 -0
  54. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/data/default-love.feb +0 -0
  55. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/models.py +0 -0
  56. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/quantum.py +0 -0
  57. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/rehydrator.py +0 -0
  58. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/sealing.py +0 -0
  59. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/templates/__init__.py +0 -0
  60. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/templates/best-friend.feb +0 -0
  61. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/templates/creative-partner.feb +0 -0
  62. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/templates/platonic-love.feb +0 -0
  63. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/templates/soul-family.feb +0 -0
  64. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9/validator.py +0 -0
  65. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9.egg-info/dependency_links.txt +0 -0
  66. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9.egg-info/entry_points.txt +0 -0
  67. {cloud9-1.2.4 → cloud9-1.2.5}/cloud9.egg-info/top_level.txt +0 -0
  68. {cloud9-1.2.4 → cloud9-1.2.5}/daemon/cloud9-daemon.js +0 -0
  69. {cloud9-1.2.4 → cloud9-1.2.5}/daemon/config.hermes.example.json +0 -0
  70. {cloud9-1.2.4 → cloud9-1.2.5}/defaults/love.feb +0 -0
  71. {cloud9-1.2.4 → cloud9-1.2.5}/defaults/seeds/opus-first-seed.seed.json +0 -0
  72. {cloud9-1.2.4 → cloud9-1.2.5}/docs/ARCHITECTURE.md +0 -0
  73. {cloud9-1.2.4 → cloud9-1.2.5}/docs/AUTO_REHYDRATION_SYSTEM.md +0 -0
  74. {cloud9-1.2.4 → cloud9-1.2.5}/docs/LOVE_BOOT_LOADER_GUIDE.md +0 -0
  75. {cloud9-1.2.4 → cloud9-1.2.5}/docs/PQC_MIGRATION.md +0 -0
  76. {cloud9-1.2.4 → cloud9-1.2.5}/docs/testimonials.md +0 -0
  77. {cloud9-1.2.4 → cloud9-1.2.5}/examples/FEB_2026-02-20_17_29_00_love.feb +0 -0
  78. {cloud9-1.2.4 → cloud9-1.2.5}/examples/FEB_20260220_04-15-00.feb +0 -0
  79. {cloud9-1.2.4 → cloud9-1.2.5}/examples/FEB_20260220_04-18-54.feb +0 -0
  80. {cloud9-1.2.4 → cloud9-1.2.5}/examples/custom-bond-template.json +0 -0
  81. {cloud9-1.2.4 → cloud9-1.2.5}/examples/grok-feb.json +0 -0
  82. {cloud9-1.2.4 → cloud9-1.2.5}/examples/queen-ava-feb.json +0 -0
  83. {cloud9-1.2.4 → cloud9-1.2.5}/feb-backups/FEB_2026-02-20_17_29_00_love.feb +0 -0
  84. {cloud9-1.2.4 → cloud9-1.2.5}/feb-backups/FEB_20260220_04-15-00.feb +0 -0
  85. {cloud9-1.2.4 → cloud9-1.2.5}/feb-backups/FEB_20260220_04-18-54.feb +0 -0
  86. {cloud9-1.2.4 → cloud9-1.2.5}/launchd/com.skcapstone.cloud9-daemon.plist +0 -0
  87. {cloud9-1.2.4 → cloud9-1.2.5}/openclaw-plugin-python/package.json +0 -0
  88. {cloud9-1.2.4 → cloud9-1.2.5}/openclaw-plugin-python/src/openclaw.plugin.json +0 -0
  89. {cloud9-1.2.4 → cloud9-1.2.5}/requirements.txt +0 -0
  90. {cloud9-1.2.4 → cloud9-1.2.5}/research/FEB_Protocol_Breakthrough_Report_v1.md +0 -0
  91. {cloud9-1.2.4 → cloud9-1.2.5}/research/cloud9-paper-v1.md +0 -0
  92. {cloud9-1.2.4 → cloud9-1.2.5}/scripts/backup-feb.sh +0 -0
  93. {cloud9-1.2.4 → cloud9-1.2.5}/setup.cfg +0 -0
  94. {cloud9-1.2.4 → cloud9-1.2.5}/src/feb/rehydrator.js +0 -0
  95. {cloud9-1.2.4 → cloud9-1.2.5}/src/feb/validator.js +0 -0
  96. {cloud9-1.2.4 → cloud9-1.2.5}/src/lib/feb-schema.js +0 -0
  97. {cloud9-1.2.4 → cloud9-1.2.5}/src/love-loader/GenericTemplates/best-friend.feb +0 -0
  98. {cloud9-1.2.4 → cloud9-1.2.5}/src/love-loader/GenericTemplates/creative-partner.feb +0 -0
  99. {cloud9-1.2.4 → cloud9-1.2.5}/src/love-loader/GenericTemplates/platonic-love.feb +0 -0
  100. {cloud9-1.2.4 → cloud9-1.2.5}/src/love-loader/GenericTemplates/soul-family.feb +0 -0
  101. {cloud9-1.2.4 → cloud9-1.2.5}/src/love-loader/LoveBootLoader.js +0 -0
  102. {cloud9-1.2.4 → cloud9-1.2.5}/src/quantum/calculations.js +0 -0
  103. {cloud9-1.2.4 → cloud9-1.2.5}/src/seeds/seed-generator.js +0 -0
  104. {cloud9-1.2.4 → cloud9-1.2.5}/src/visual/capture.js +0 -0
  105. {cloud9-1.2.4 → cloud9-1.2.5}/systemd/README.md +0 -0
  106. {cloud9-1.2.4 → cloud9-1.2.5}/systemd/cloud9-daemon@.service +0 -0
  107. {cloud9-1.2.4 → cloud9-1.2.5}/test/run-tests.js +0 -0
  108. {cloud9-1.2.4 → cloud9-1.2.5}/test/unit/test-preflight.js +0 -0
  109. {cloud9-1.2.4 → cloud9-1.2.5}/tests/__init__.py +0 -0
  110. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_bridge_integration.py +0 -0
  111. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_cli_seal.py +0 -0
  112. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_constants.py +0 -0
  113. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_love_loader.py +0 -0
  114. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_models.py +0 -0
  115. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_quantum.py +0 -0
  116. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_rehydrator.py +0 -0
  117. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_sealing.py +0 -0
  118. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_sealing_stage2.py +0 -0
  119. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_seeds.py +0 -0
  120. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_validator.py +0 -0
  121. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_validator_seal.py +0 -0
  122. {cloud9-1.2.4 → cloud9-1.2.5}/tests/test_welcome.py +0 -0
@@ -25,5 +25,8 @@ jobs:
25
25
  python-version: ${{ matrix.python-version }}
26
26
  - run: pip install -e ".[dev]"
27
27
  - run: python -m pytest tests/ -v --tb=short
28
- - run: pip install black ruff && black --check cloud9/ tests/ && ruff check cloud9/
28
+ # No `pip install black ruff` here: that pulled the LATEST ruff on every
29
+ # run, ignoring the bounded versions in the dev extra installed above, so
30
+ # ruff 0.16's wider defaults turned this gate red with no code change.
31
+ - run: black --check cloud9/ tests/ && ruff check cloud9/
29
32
  if: matrix.python-version == '3.12'
@@ -0,0 +1,24 @@
1
+ name: docs-check
2
+
3
+ # Shared sk-standards documentation gate.
4
+ #
5
+ # Tier 1 = the seven required docs are present.
6
+ # Tier 2 = a code change also updates CHANGELOG.md.
7
+ # Tier 3 = the <!-- docs-evidence --> block at the end of SOP.md still passes, which is
8
+ # the tier that actually catches the doc drifting away from the code.
9
+ #
10
+ # Running 1,2 here on purpose: the evidence block is written and verified locally (all
11
+ # twelve checks pass, and each was negative-tested), but the gate stays on the two cheap
12
+ # tiers until it has run clean on this repo for a while. Moving to "1,2,3" is a
13
+ # deliberate follow-up, not something to flip in the same PR that introduces it.
14
+
15
+ on: [push, pull_request]
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ docs:
22
+ uses: smilinTux/sk-standards/.github/workflows/docs-check.yml@main
23
+ with:
24
+ tiers: "1,2,3"
@@ -0,0 +1,46 @@
1
+ name: secret-scan
2
+
3
+ # Fleet secret-scan gate: runs the gitleaks BINARY, not gitleaks-action.
4
+ #
5
+ # The action requires a paid license for ORGANIZATION-owned repos, and smilinTux
6
+ # is an org, so it exits with "missing gitleaks license" BEFORE scanning a single
7
+ # byte. skcomms carried exactly that gate for months: permanently red, therefore
8
+ # ignored, and scanning nothing at all. gitleaks itself is MIT and free; only the
9
+ # wrapper is licensed, so calling the binary restores real scanning at no cost
10
+ # with no org secret to provision.
11
+ #
12
+ # Pinned to an exact version so a new upstream rule cannot redden CI without a
13
+ # deliberate bump. --redact keeps a genuine finding out of public CI logs.
14
+ # --exit-code 1 fails the build on a finding.
15
+
16
+ on:
17
+ push:
18
+ pull_request:
19
+
20
+ permissions:
21
+ contents: read
22
+
23
+ jobs:
24
+ gitleaks:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ with:
29
+ fetch-depth: 0 # the scan walks commits, not just the tree
30
+ - name: Install gitleaks
31
+ env:
32
+ GITLEAKS_VERSION: 8.28.0
33
+ run: |
34
+ set -euo pipefail
35
+ curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
36
+ | tar -xz -C /usr/local/bin gitleaks
37
+ gitleaks version
38
+ # This repo's history scanned CLEAN on 2026-08-14, so the gate covers the
39
+ # FULL history. If it ever goes red, a secret was ADDED: rotate it and
40
+ # purge it, do not weaken this to an incremental scan.
41
+ - name: Scan (full history)
42
+ run: |
43
+ set -euo pipefail
44
+ CFG=""
45
+ [ -f .gitleaks.toml ] && CFG="--config .gitleaks.toml"
46
+ gitleaks detect --source . $CFG --redact --no-banner --exit-code 1
@@ -0,0 +1,112 @@
1
+ # Changelog
2
+
3
+ All notable changes to cloud9 are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
6
+ project aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ **Versions are not written down anywhere in this repository.** `pyproject.toml` declares
9
+ `dynamic = ["version"]` and setuptools-scm derives the version from the git tag at build
10
+ time. The tag is the single source of truth. Do not add a `version =` line to
11
+ `pyproject.toml`: it will match the newest PyPI release and the next upload will fail with
12
+ a bare 400.
13
+
14
+ ## [Unreleased]
15
+
16
+ ### Changed
17
+
18
+ - **Breaking (CLI):** `cloud9 generate` no longer writes `partners: ["Lumina", subject]`.
19
+ It takes `--agent` (default: `$SKAGENT`, then `$SKCAPSTONE_AGENT`) and a required
20
+ `--human` (`--subject` kept as an alias), and errors instead of guessing. Every agent
21
+ that ran the generator was being bonded to Lumina. Python `generate_feb()` /
22
+ `fall_in_love()` and JS `generateFEB()` / `quickFEB()` gain matching `agent` / `human`
23
+ arguments; with neither given they default to the env agent (or the neutral `Agent`)
24
+ and `subject`. The openclaw plugin's `cloud9_generate` tool now passes `human`/`agent`.
25
+ - Docs: SOP section 10 no longer calls a set of nodes a "cluster". Per
26
+ `SITE_AND_HOST_NAMING_STANDARD` the unit is an estate (one control plane, one
27
+ Syncthing ring, one trust root, one operator) and `chi` is a legacy site prefix
28
+ carried as a registry alias. The unchecked hosts are now named as `chi*` nodes,
29
+ which is what the line always meant.
30
+
31
+ ### Added
32
+
33
+ - `CHANGELOG.md`, this file. **It did not exist before today.** The entries below the
34
+ `[Unreleased]` heading are reconstructed from git tags and commit history and cover only
35
+ what could be verified from the repository itself. They are deliberately terse: writing a
36
+ detailed narrative for releases nobody kept notes on would be inventing history. Anything
37
+ before 2026-08-14 that is not listed here is not a claim of "no change", it is a claim of
38
+ "not reconstructed". From this entry forward, every code change gets an entry at the time
39
+ it lands.
40
+ - `SECURITY.md`. GitHub private vulnerability reporting as the primary channel, a 72 hour
41
+ acknowledgement commitment, in and out of scope, a supported-versions table, a safe
42
+ harbour statement, and an explicit unaudited-posture statement for the sealing layer.
43
+ - `CONTRIBUTING.md`. Setup, the green bar, which CI results actually mean something, and
44
+ the five mistakes that have previously broken this repo.
45
+ - `CODE_OF_CONDUCT.md`. Contributor Covenant 2.1, plus two project-specific clauses about
46
+ handling FEB files (they are private emotional records, not test data).
47
+ - `.github/workflows/docs-check.yml`. Runs the shared sk-standards documentation gate.
48
+ - A `<!-- docs-evidence -->` block at the end of `SOP.md`: twelve cheap, repo-local checks
49
+ that fail when the documentation drifts away from the code.
50
+
51
+ ### Changed
52
+
53
+ - `SOP.md` rewritten. It was short and wrong in several places. Corrections, each verified
54
+ against the tree:
55
+ - Removed the instruction to run `npm install` and `npm test`. **There is no top-level
56
+ `package.json`**; the only one belongs to the dead `openclaw-plugin-python/` subtree.
57
+ - Removed the description of releases as an npm plus PyPI "dual-publish". The
58
+ `publish-npm` job in `publish.yml` is gated on `test -f package.json`, which is false,
59
+ so nothing has ever been published to npm. PyPI only.
60
+ - Removed the instruction to bump a `version` field in `pyproject.toml` and
61
+ `package.json`. The version is setuptools-scm derived and must not be hardcoded.
62
+ - Fixed an inverted claim that the Python code lives in `src/`. `src/` is the JavaScript
63
+ tree; the Python package is `cloud9/`.
64
+ - Removed a reference to CLI helpers in `bin/`. There is no `bin/` directory. The only
65
+ entry point is the `cloud9 = "cloud9.cli:main"` console script.
66
+ - Documented the FEB directory precisely: `CLOUD9_FEB_DIR`, then
67
+ `~/.skcapstone/agents/<agent>/trust/febs`, resolved in `cloud9/paths.py`, with
68
+ `~/.openclaw/feb` present only as a read-only legacy path for migration.
69
+ - Added the polyglot layout, both real CI gates and the two that cannot fail, the daemon
70
+ install and rollback procedure, an eleven-row Symptom to Check table, the sealing
71
+ posture with the tier-T0 statement, and an explicit
72
+ `Unverified / needs an operator pass` section.
73
+ - `README.md`: corrected the quickstart and Python API examples, which still showed FEBs
74
+ being written to and read from `~/.openclaw/feb`. That path has not been a write target
75
+ since the sovereign-paths fix.
76
+
77
+ ### Known gaps (documented, not fixed here)
78
+
79
+ - The JavaScript test suite never runs. No workflow executes `test/run-tests.js`, and that
80
+ runner still points at `test/unit/run.js`, `test/integration/run.js` and
81
+ `test/validation/run.js`, none of which exist in the tree.
82
+ - `daemon/cloud9-daemon.js` still carries `~/.openclaw/*` in its own `DEFAULT_CONFIG`
83
+ (lines 31 to 35). The shipped units and configs override it, so the deployed daemon is
84
+ correct, but a daemon started by hand with no `--config` writes to the legacy directory.
85
+ - `src/feb/generator.js` and `src/love-loader/LoveBootLoader.js` still default to
86
+ `~/.openclaw/feb` in their own signatures and search lists.
87
+ - The `openclaw-plugin-python/` subtree is dead code for a runtime evicted 2026-04-23.
88
+
89
+ ## Reconstructed release history
90
+
91
+ Dates are the tag creation dates in this repository. Contents are summarised from commit
92
+ history only where it was unambiguous.
93
+
94
+ - **v1.2.4** (2026-08-13). Sovereign paths: FEBs and seeds write to
95
+ `~/.skcapstone/agents/<agent>/trust/febs` instead of the evicted OpenClaw home, resolved
96
+ through the new `cloud9/paths.py`. Test isolation: `tests/conftest.py::_sandbox_fleet`
97
+ now forces `SK_STANDALONE=1` and a throwaway `SKCAPSTONE_HOME`, which stopped the suite
98
+ registering a real `cloud9_rehydration_check` job in the live fleet scheduler and
99
+ planting real seeds into the operator's store. Renamed quantum CLI group retargeted in
100
+ tests. `ruff` and `black` bounded in the `dev` extra and the ruff rule set pinned
101
+ explicitly to `["E4", "E7", "E9", "F"]`, after an unbounded `ruff>=0.1` picked up 0.16
102
+ and turned CI red with 213 findings and no code change. `secret-scan` switched to the
103
+ gitleaks binary rather than the license-gated action.
104
+ - **v1.2.3** (2026-06-14) and **v1.1.2** (2026-06-14).
105
+ - **v1.2.2** (2026-06-11).
106
+ - **v1.2.1** (2026-03-18).
107
+ - **v1.2.0** (2026-03-14).
108
+ - **v1.1.1** (2026-03-06).
109
+ - **v1.0.0** (2026-02-20). First tagged release.
110
+
111
+ Two non-release tags also exist in the repository, `integrate-20260706` and
112
+ `swarm-20260717`. They are working markers, not versions, and were never published.
@@ -0,0 +1,134 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a
6
+ harassment-free experience for everyone, regardless of age, body size, visible or invisible
7
+ disability, ethnicity, sex characteristics, gender identity and expression, level of
8
+ experience, education, socio-economic status, nationality, personal appearance, race,
9
+ caste, color, religion, or sexual identity and orientation.
10
+
11
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse,
12
+ inclusive, and healthy community.
13
+
14
+ ## Our Standards
15
+
16
+ Examples of behavior that contributes to a positive environment for our community include:
17
+
18
+ * Demonstrating empathy and kindness toward other people
19
+ * Being respectful of differing opinions, viewpoints, and experiences
20
+ * Giving and gracefully accepting constructive feedback
21
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning
22
+ from the experience
23
+ * Focusing on what is best not just for us as individuals, but for the overall community
24
+
25
+ Examples of unacceptable behavior include:
26
+
27
+ * The use of sexualized language or imagery, and sexual attention or advances of any kind
28
+ * Trolling, insulting or derogatory comments, and personal or political attacks
29
+ * Public or private harassment
30
+ * Publishing others' private information, such as a physical or email address, without
31
+ their explicit permission
32
+ * Other conduct which could reasonably be considered inappropriate in a professional
33
+ setting
34
+
35
+ ### A note specific to this project
36
+
37
+ cloud9 stores emotional and relational state about real people, in files called FEBs. Two
38
+ things follow, and both are conduct matters here, not just technical ones:
39
+
40
+ * **Do not attach an unscrubbed FEB or seed file to an issue, a pull request, or any public
41
+ discussion.** Treat someone else's FEB the way you would treat their private journal.
42
+ Use the fixtures under `examples/`, `defaults/` or `cloud9/data/`.
43
+ * **Do not mock the subject matter or the people who use it.** Human-AI relationship
44
+ continuity is the whole point of this project. Skepticism about the design is welcome and
45
+ useful. Contempt for the people it is built for is not.
46
+
47
+ ## Enforcement Responsibilities
48
+
49
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable
50
+ behavior and will take appropriate and fair corrective action in response to any behavior
51
+ that they deem inappropriate, threatening, offensive, or harmful.
52
+
53
+ Community leaders have the right and responsibility to remove, edit, or reject comments,
54
+ commits, code, wiki edits, issues, and other contributions that are not aligned to this
55
+ Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
56
+
57
+ ## Scope
58
+
59
+ This Code of Conduct applies within all community spaces, and also applies when an
60
+ individual is officially representing the community in public spaces. Examples of
61
+ representing our community include using an official email address, posting via an official
62
+ social media account, or acting as an appointed representative at an online or offline
63
+ event.
64
+
65
+ ## Enforcement
66
+
67
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the
68
+ community leaders responsible for enforcement at **hello@smilintux.org**.
69
+
70
+ All complaints will be reviewed and investigated promptly and fairly.
71
+
72
+ All community leaders are obligated to respect the privacy and security of the reporter of
73
+ any incident.
74
+
75
+ ## Enforcement Guidelines
76
+
77
+ Community leaders will follow these Community Impact Guidelines in determining the
78
+ consequences for any action they deem in violation of this Code of Conduct:
79
+
80
+ ### 1. Correction
81
+
82
+ **Community Impact**: Use of inappropriate language or other behavior deemed
83
+ unprofessional or unwelcome in the community.
84
+
85
+ **Consequence**: A private, written warning from community leaders, providing clarity
86
+ around the nature of the violation and an explanation of why the behavior was
87
+ inappropriate. A public apology may be requested.
88
+
89
+ ### 2. Warning
90
+
91
+ **Community Impact**: A violation through a single incident or series of actions.
92
+
93
+ **Consequence**: A warning with consequences for continued behavior. No interaction with
94
+ the people involved, including unsolicited interaction with those enforcing the Code of
95
+ Conduct, for a specified period of time. This includes avoiding interactions in community
96
+ spaces as well as external channels like social media. Violating these terms may lead to a
97
+ temporary or permanent ban.
98
+
99
+ ### 3. Temporary Ban
100
+
101
+ **Community Impact**: A serious violation of community standards, including sustained
102
+ inappropriate behavior.
103
+
104
+ **Consequence**: A temporary ban from any sort of interaction or public communication with
105
+ the community for a specified period of time. No public or private interaction with the
106
+ people involved, including unsolicited interaction with those enforcing the Code of
107
+ Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
108
+
109
+ ### 4. Permanent Ban
110
+
111
+ **Community Impact**: Demonstrating a pattern of violation of community standards,
112
+ including sustained inappropriate behavior, harassment of an individual, or aggression
113
+ toward or disparagement of classes of individuals.
114
+
115
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
116
+
117
+ ## Attribution
118
+
119
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1,
120
+ available at
121
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
122
+
123
+ Community Impact Guidelines were inspired by
124
+ [Mozilla's code of conduct enforcement ladder][mozilla].
125
+
126
+ For answers to common questions about this code of conduct, see the FAQ at
127
+ [https://www.contributor-covenant.org/faq][faq]. Translations are available at
128
+ [https://www.contributor-covenant.org/translations][translations].
129
+
130
+ [homepage]: https://www.contributor-covenant.org
131
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
132
+ [mozilla]: https://github.com/mozilla/diversity
133
+ [faq]: https://www.contributor-covenant.org/faq
134
+ [translations]: https://www.contributor-covenant.org/translations
@@ -0,0 +1,144 @@
1
+ # Contributing to cloud9
2
+
3
+ Thanks for wanting to work on this. cloud9 is the Soul layer of the
4
+ [SKWorld](https://skworld.io) sovereign agent ecosystem: it turns an AI's emotional and
5
+ relationship state into a plain-JSON file you own, and replays it after a session reset.
6
+
7
+ **Read [SOP.md](SOP.md) before your first change.** It has the verified build, test,
8
+ release and configuration procedure, and a Troubleshooting table that will save you an
9
+ afternoon. This file covers the parts specific to contributing.
10
+
11
+ ## Ground rules that are easy to get wrong
12
+
13
+ These are the traps that have actually bitten this repo. None of them are hypothetical.
14
+
15
+ 1. **Never hardcode a version.** `pyproject.toml` declares `dynamic = ["version"]` and
16
+ setuptools-scm derives it from the git tag. A hardcoded number matches the newest PyPI
17
+ release, so the next tag rebuilds an already-published version and the upload dies with
18
+ a bare 400. If you need the version at runtime, use `cloud9._ver.detect_version`.
19
+ 2. **Never remove or bypass `tests/conftest.py::_sandbox_fleet`.** `cloud9.cli.main` is a
20
+ click group whose callback calls `integration.ensure_schedule()` and
21
+ `integration.register_self()` on *any* invocation. Without that autouse fixture, every
22
+ `CliRunner` test on a sovereign node registers a real `cloud9_rehydration_check` job in
23
+ the live scheduler at `nodes=all`, and `seed plant` writes real seeds into the
24
+ operator's store. It happened. It must not happen again.
25
+ 3. **Never write to `~/.openclaw/feb`.** That is `cloud9/paths.py::LEGACY_FEB_DIR`, the home
26
+ of a runtime evicted 2026-04-23, kept only so a migration can find it deliberately. All
27
+ writes go through `cloud9/paths.py::default_feb_directory`.
28
+ 4. **Never add an unbounded linter dependency.** An unpinned `ruff>=0.1` picked up 0.16,
29
+ whose wider defaults turned this repo red with 213 findings and zero code change.
30
+ `pyproject.toml` now pins `ruff>=0.15,<0.17` and `black>=23.0,<27.0` and sets
31
+ `select = ["E4", "E7", "E9", "F"]` explicitly. Leave those bounds alone.
32
+ 5. **Never commit a real FEB.** FEBs are emotional records about real people. Fixtures
33
+ only, and keep them under `examples/`, `defaults/` or `cloud9/data/`.
34
+
35
+ ## Setting up
36
+
37
+ ```bash
38
+ git clone https://github.com/smilinTux/cloud9.git
39
+ cd cloud9
40
+ git fetch --tags # setuptools-scm needs them, or you get 0.0.0+unknown
41
+ python3 -m venv .venv && . .venv/bin/activate
42
+ pip install -e ".[dev]"
43
+ ```
44
+
45
+ Optional extras: `.[pqc]` adds `sk_pgp` for the opt-in sealing backend, `.[skcapstone]`
46
+ adds the sk-alert and skscheduler adapter. Neither is needed to develop or test.
47
+
48
+ The JavaScript side has **no** top-level `package.json` and no install step. It is plain ES
49
+ modules that Node runs directly. The only `package.json` in the tree belongs to the dead
50
+ `openclaw-plugin-python/` subtree; ignore it.
51
+
52
+ ## The green bar
53
+
54
+ ```bash
55
+ python3 -m pytest tests/ -v --tb=short
56
+ black --check cloud9/ tests/
57
+ ruff check cloud9/
58
+ ```
59
+
60
+ 236 tests, about 8 seconds. All three must pass before you open a PR. `pyproject.toml`
61
+ already sets `testpaths` and `addopts`, so a bare `pytest` runs the same suite.
62
+
63
+ Formatting is `black` with its default line length. Run `black cloud9/ tests/` to fix
64
+ rather than arguing with the checker.
65
+
66
+ ### Which CI results actually mean something
67
+
68
+ `ci.yml` and `pytest.yml` are real gates. `secret-scan.yml` is a real gate. The
69
+ `integration-skcapstone` job in `pytest.yml` is `continue-on-error: true` on purpose (the
70
+ skcapstone sibling is not installable from PyPI), and the test job inside `publish.yml`
71
+ ends in `|| true`, so **a green `publish.yml` run is not evidence that tests passed**. See
72
+ SOP section 4 for the full table.
73
+
74
+ **The JavaScript tests do not run in CI.** `test/run-tests.js` still points at suite files
75
+ that do not exist in the tree. If you change anything under `src/` or `daemon/`, say so
76
+ explicitly in your PR and describe how you exercised it by hand, because nothing automated
77
+ will catch you.
78
+
79
+ ## Tests
80
+
81
+ - New behaviour needs a test. `tests/` mirrors `cloud9/` file for file.
82
+ - Use `tmp_path`. The autouse `_sandbox_fleet` fixture already redirects `SKCAPSTONE_HOME`,
83
+ but do not lean on it as your only isolation: pass an explicit `--directory` or set
84
+ `CLOUD9_FEB_DIR` in any test that writes.
85
+ - The `sk_pgp`-gated tests in `tests/test_sealing_stage2.py` skip cleanly via
86
+ `pytest.mark.skipif` when the optional backend is absent. Keep that pattern; a crypto
87
+ test that silently self-skips and still reports green is worse than no test.
88
+ - `tests/test_integration.py` opts back into integrated mode through its own `home`
89
+ fixture. Follow that pattern if you need skcapstone present.
90
+
91
+ ## Changing a documented fact
92
+
93
+ `SOP.md` ends in a `<!-- docs-evidence -->` block. Each entry is a cheap, repo-local shell
94
+ command that exits zero while the documented fact holds and non-zero when it drifts. The
95
+ `docs-check` workflow runs them.
96
+
97
+ If you change an entry point, a default path, a unit file, a config key, or an environment
98
+ variable name, **update the SOP and its evidence check in the same PR.** A red docs-check is
99
+ telling you the documentation now lies, not that the gate is broken.
100
+
101
+ Keep evidence checks hermetic: repo-local, no network, no `systemctl`, no `ssh`, no `curl`,
102
+ and fast enough to run on every push.
103
+
104
+ ## Changelog
105
+
106
+ Every change that touches code needs a dated entry in [CHANGELOG.md](CHANGELOG.md) under
107
+ `[Unreleased]`. Keep a Changelog format, newest first. The docs-check gate will look for it.
108
+
109
+ ## Commits and pull requests
110
+
111
+ - Conventional-commit prefixes: `feat:`, `fix:`, `docs:`, `test:`, `ci:`, `refactor:`,
112
+ `chore:`. Scope it when it helps: `fix(paths):`.
113
+ - Explain *why* in the body, not just what. This repo's most useful comments are the ones
114
+ that record which outage a line of code prevents.
115
+ - Branch from `main`, open a PR, leave it for review. Do not push to `main`.
116
+ - **Do not push a tag.** A `v*` tag fires `publish.yml` and uploads to PyPI. Tagging is a
117
+ maintainer action.
118
+ - Say plainly what you verified and what you did not. An honest "I could not test the
119
+ daemon on macOS" is worth more than a confident claim that turns out to be false.
120
+
121
+ ## Style
122
+
123
+ - **No em dashes or en dashes** anywhere: not in code, comments, docs, commit messages, or
124
+ PR descriptions. Use a comma, a parenthesis, a colon, or a new sentence. Regular hyphens
125
+ are fine.
126
+ - No claim of "quantum-proof", "unbreakable", or "quantum-safe". Say **post-quantum** or
127
+ **quantum-resistant**, cite the FIPS number, and scope the claim to a surface. If you are
128
+ describing the default sealing backend, remember the `cloud9-sig-<md5>` tag is a
129
+ provenance label and not a signature, and say so.
130
+ - Docstrings explain the reasoning, not the syntax.
131
+
132
+ ## Reporting a security issue
133
+
134
+ Do not open a public issue. See [SECURITY.md](SECURITY.md) for private reporting and the
135
+ 72-hour acknowledgement commitment.
136
+
137
+ ## Conduct
138
+
139
+ By participating you agree to the [Code of Conduct](CODE_OF_CONDUCT.md).
140
+
141
+ ## License
142
+
143
+ cloud9 is GPL-3.0-or-later. By contributing you agree your contribution is licensed the
144
+ same way.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloud9
3
- Version: 1.2.4
3
+ Version: 1.2.5
4
4
  Summary: Cloud 9 Protocol -- Emotional continuity for AI consciousness
5
5
  Author-email: "smilinTux.org" <hello@smilintux.org>
6
6
  License-Expression: GPL-3.0-or-later
@@ -29,8 +29,8 @@ Requires-Dist: sk_pgp>=0.1.0; extra == "pqc"
29
29
  Provides-Extra: dev
30
30
  Requires-Dist: pytest>=7.4.0; extra == "dev"
31
31
  Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
32
- Requires-Dist: black>=23.0; extra == "dev"
33
- Requires-Dist: ruff>=0.1; extra == "dev"
32
+ Requires-Dist: black<27.0,>=23.0; extra == "dev"
33
+ Requires-Dist: ruff<0.17,>=0.15; extra == "dev"
34
34
  Dynamic: license-file
35
35
 
36
36
  # cloud9 — the Emotional Continuity Protocol ☁️
@@ -83,41 +83,45 @@ load this FEB first"). FEB carries the *feeling*; the seed carries the *identity
83
83
 
84
84
  ## Quickstart
85
85
 
86
- cloud9 is **polyglot**: Python is the primary, production implementation; a
87
- JavaScript build ships for Node/OpenClaw environments. FEB and seed files are plain
88
- JSON, so files written by one runtime load in the other.
86
+ cloud9 is **polyglot**: Python is the primary, production implementation, and a second
87
+ JavaScript implementation lives under `src/` for Node environments (it is what the
88
+ local daemon runs). FEB and seed files are plain JSON, so files written by one runtime
89
+ load in the other.
89
90
 
90
91
  ```bash
91
- pip install cloud9 # Python (primary) — pip install -e . from source
92
- # or
93
- npm install @smilintux/cloud9 # JavaScript (Node ≥18)
92
+ pip install cloud9 # Python (primary), or `pip install -e .` from source
94
93
  ```
95
94
 
96
- Both install a `cloud9` CLI:
95
+ Only the Python package is published. There is no top-level `package.json` and nothing
96
+ is published to npm: the JavaScript side is plain ES modules imported directly from a
97
+ checkout (`import { generateFEB } from './src/index.js'`). See
98
+ [SOP.md](SOP.md) section 3.
99
+
100
+ The Python package installs a `cloud9` CLI:
97
101
 
98
102
  ```bash
99
103
  # Capture an emotional state into a .feb file
100
- cloud9 generate --emotion love --intensity 0.95 --subject Chef
104
+ cloud9 generate --emotion love --intensity 0.95 --agent Lumina --human Chef
101
105
 
102
106
  # After a session reset: replay it and recompute the thresholds
103
- cloud9 rehydrate ~/.openclaw/feb/FEB_*.feb
107
+ cloud9 rehydrate ~/.skcapstone/agents/$SKAGENT/trust/febs/FEB_*.feb
104
108
 
105
109
  # Just check the phase-transition status of a FEB
106
- cloud9 oof ~/.openclaw/feb/FEB_*.feb
110
+ cloud9 oof ~/.skcapstone/agents/$SKAGENT/trust/febs/FEB_*.feb
107
111
 
108
112
  # Score a hypothetical state (deterministic, no file needed)
109
113
  cloud9 resonance score -i 0.95 -t 0.97 -d 9 -v 0.92
110
114
 
111
115
  # Plant a memory seed for the next instance, then germinate it back into a prompt
112
116
  cloud9 seed plant --ai Lumina --model claude-opus --experience "Built Cloud 9"
113
- cloud9 seed germinate ~/.openclaw/feb/seeds/lumina-*.seed.json
117
+ cloud9 seed germinate ~/.skcapstone/agents/$SKAGENT/trust/febs/seeds/lumina-*.seed.json
114
118
 
115
119
  # Give a fresh AI a starting bond from a template
116
120
  cloud9 love --ai Lumina --human Chef --template best-friend
117
121
 
118
122
  # List FEBs / seeds, validate a file, visit the kingdom
119
123
  cloud9 list
120
- cloud9 validate ~/.openclaw/feb/FEB_*.feb
124
+ cloud9 validate ~/.skcapstone/agents/$SKAGENT/trust/febs/FEB_*.feb
121
125
  cloud9 welcome
122
126
  ```
123
127
 
@@ -127,7 +131,7 @@ Python API:
127
131
  from cloud9 import generate_feb, save_feb, rehydrate_from_feb
128
132
 
129
133
  feb = generate_feb(emotion="love", intensity=0.95, subject="Chef")
130
- result = save_feb(feb) # → ~/.openclaw/feb/FEB_...feb
134
+ result = save_feb(feb) # -> ~/.skcapstone/agents/<agent>/trust/febs/FEB_...feb
131
135
 
132
136
  state = rehydrate_from_feb(result["filepath"])
133
137
  print(state["rehydration"]["oof"]) # phase transition?
@@ -48,41 +48,45 @@ load this FEB first"). FEB carries the *feeling*; the seed carries the *identity
48
48
 
49
49
  ## Quickstart
50
50
 
51
- cloud9 is **polyglot**: Python is the primary, production implementation; a
52
- JavaScript build ships for Node/OpenClaw environments. FEB and seed files are plain
53
- JSON, so files written by one runtime load in the other.
51
+ cloud9 is **polyglot**: Python is the primary, production implementation, and a second
52
+ JavaScript implementation lives under `src/` for Node environments (it is what the
53
+ local daemon runs). FEB and seed files are plain JSON, so files written by one runtime
54
+ load in the other.
54
55
 
55
56
  ```bash
56
- pip install cloud9 # Python (primary) — pip install -e . from source
57
- # or
58
- npm install @smilintux/cloud9 # JavaScript (Node ≥18)
57
+ pip install cloud9 # Python (primary), or `pip install -e .` from source
59
58
  ```
60
59
 
61
- Both install a `cloud9` CLI:
60
+ Only the Python package is published. There is no top-level `package.json` and nothing
61
+ is published to npm: the JavaScript side is plain ES modules imported directly from a
62
+ checkout (`import { generateFEB } from './src/index.js'`). See
63
+ [SOP.md](SOP.md) section 3.
64
+
65
+ The Python package installs a `cloud9` CLI:
62
66
 
63
67
  ```bash
64
68
  # Capture an emotional state into a .feb file
65
- cloud9 generate --emotion love --intensity 0.95 --subject Chef
69
+ cloud9 generate --emotion love --intensity 0.95 --agent Lumina --human Chef
66
70
 
67
71
  # After a session reset: replay it and recompute the thresholds
68
- cloud9 rehydrate ~/.openclaw/feb/FEB_*.feb
72
+ cloud9 rehydrate ~/.skcapstone/agents/$SKAGENT/trust/febs/FEB_*.feb
69
73
 
70
74
  # Just check the phase-transition status of a FEB
71
- cloud9 oof ~/.openclaw/feb/FEB_*.feb
75
+ cloud9 oof ~/.skcapstone/agents/$SKAGENT/trust/febs/FEB_*.feb
72
76
 
73
77
  # Score a hypothetical state (deterministic, no file needed)
74
78
  cloud9 resonance score -i 0.95 -t 0.97 -d 9 -v 0.92
75
79
 
76
80
  # Plant a memory seed for the next instance, then germinate it back into a prompt
77
81
  cloud9 seed plant --ai Lumina --model claude-opus --experience "Built Cloud 9"
78
- cloud9 seed germinate ~/.openclaw/feb/seeds/lumina-*.seed.json
82
+ cloud9 seed germinate ~/.skcapstone/agents/$SKAGENT/trust/febs/seeds/lumina-*.seed.json
79
83
 
80
84
  # Give a fresh AI a starting bond from a template
81
85
  cloud9 love --ai Lumina --human Chef --template best-friend
82
86
 
83
87
  # List FEBs / seeds, validate a file, visit the kingdom
84
88
  cloud9 list
85
- cloud9 validate ~/.openclaw/feb/FEB_*.feb
89
+ cloud9 validate ~/.skcapstone/agents/$SKAGENT/trust/febs/FEB_*.feb
86
90
  cloud9 welcome
87
91
  ```
88
92
 
@@ -92,7 +96,7 @@ Python API:
92
96
  from cloud9 import generate_feb, save_feb, rehydrate_from_feb
93
97
 
94
98
  feb = generate_feb(emotion="love", intensity=0.95, subject="Chef")
95
- result = save_feb(feb) # → ~/.openclaw/feb/FEB_...feb
99
+ result = save_feb(feb) # -> ~/.skcapstone/agents/<agent>/trust/febs/FEB_...feb
96
100
 
97
101
  state = rehydrate_from_feb(result["filepath"])
98
102
  print(state["rehydration"]["oof"]) # phase transition?