embeddings-cli 0.8.1__tar.gz → 0.9.1__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 (157) hide show
  1. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.github/workflows/tests.yml +15 -0
  2. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/CHANGELOG.md +26 -0
  3. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/CLAUDE.md +9 -1
  4. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/PKG-INFO +4 -2
  5. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/README.md +2 -0
  6. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/__init__.py +2 -0
  7. embeddings_cli-0.9.1/embeddings/cli/_commands/export.py +711 -0
  8. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/gaps.py +21 -11
  9. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/learn.py +5 -0
  10. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/map.py +7 -3
  11. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/overview.py +1 -0
  12. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/regions.py +7 -3
  13. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/explain/catalog.py +58 -0
  14. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/pyproject.toml +1 -1
  15. embeddings_cli-0.9.1/scripts/sonar_open_issues.py +147 -0
  16. embeddings_cli-0.9.1/tests/_viewer_contract.py +211 -0
  17. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_backend_client.py +6 -3
  18. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_cli_contract.py +2 -1
  19. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_corpus.py +2 -1
  20. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_directions.py +8 -4
  21. embeddings_cli-0.9.1/tests/test_export.py +888 -0
  22. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_gaps.py +2 -1
  23. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_neighbors.py +2 -1
  24. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_numeric.py +2 -1
  25. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_regions.py +2 -1
  26. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_roadmap_lockstep.py +1 -0
  27. embeddings_cli-0.9.1/tests/test_sonar_gate.py +152 -0
  28. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_stability.py +2 -1
  29. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/uv.lock +1 -1
  30. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/agent-config/SKILL.md +0 -0
  31. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
  32. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/agent-config/scripts/show.sh +0 -0
  33. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/ask-colleague/SKILL.md +0 -0
  34. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
  35. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/ask-colleague/prompts/review.md +0 -0
  36. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/ask-colleague/prompts/write.md +0 -0
  37. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
  38. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
  39. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
  40. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/challenge/SKILL.md +0 -0
  41. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/cicd/SKILL.md +0 -0
  42. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
  43. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
  44. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
  45. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
  46. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/cicd/scripts/workflow.sh +0 -0
  47. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/communicate/SKILL.md +0 -0
  48. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
  49. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
  50. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
  51. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
  52. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
  53. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
  54. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/deviate/SKILL.md +0 -0
  55. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
  56. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
  57. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
  58. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
  59. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/recall/SKILL.md +0 -0
  60. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/recall/scripts/recall.sh +0 -0
  61. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/remember/SKILL.md +0 -0
  62. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/remember/scripts/remember.sh +0 -0
  63. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/run-tests/SKILL.md +0 -0
  64. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/run-tests/scripts/test.sh +0 -0
  65. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/scope/SKILL.md +0 -0
  66. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/sonarclaude/SKILL.md +0 -0
  67. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
  68. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/spec-to-plan/SKILL.md +0 -0
  69. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
  70. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/summarize-delivery/SKILL.md +0 -0
  71. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/think/SKILL.md +0 -0
  72. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/think/scripts/think.sh +0 -0
  73. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/version-bump/SKILL.md +0 -0
  74. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills/version-bump/scripts/bump.py +0 -0
  75. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.claude/skills.local.yaml.example +0 -0
  76. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.devague/current +0 -0
  77. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.devague/current_plan +0 -0
  78. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.devague/frames/embeddings-survey-surface.json +0 -0
  79. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.devague/plans/embeddings-survey-surface.json +0 -0
  80. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.flake8 +0 -0
  81. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.github/workflows/publish.yml +0 -0
  82. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.gitignore +0 -0
  83. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/.markdownlint-cli2.yaml +0 -0
  84. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/AGENTS.colleague.md +0 -0
  85. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/LICENSE +0 -0
  86. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/culture.yaml +0 -0
  87. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/design-notes/semantic-measurement.md +0 -0
  88. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/evidence/2026-07-20-live-end-to-end.md +0 -0
  89. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/evidence/build_corpus.py +0 -0
  90. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/evidence/corpus.jsonl +0 -0
  91. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/evidence/map.html +0 -0
  92. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/evidence/pairs-legal-to-technical.txt +0 -0
  93. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/evidence/probes-legal.txt +0 -0
  94. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/plans/2026-07-20-embeddings-survey-surface.md +0 -0
  95. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/skill-sources.md +0 -0
  96. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/specs/2026-07-20-embeddings-survey-surface.md +0 -0
  97. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/2026-07-20-eidetic-embedder.md +0 -0
  98. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/atlas-instruct/atlas.json +0 -0
  99. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/atlas-instruct/records.jsonl +0 -0
  100. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/atlas-long/atlas.json +0 -0
  101. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/atlas-long/records.jsonl +0 -0
  102. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/atlas-plain/atlas.json +0 -0
  103. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/atlas-plain/records.jsonl +0 -0
  104. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/build_probe_corpus.py +0 -0
  105. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/measure_pairs.py +0 -0
  106. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/pairs-contra-high.txt +0 -0
  107. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/pairs-contra-low.txt +0 -0
  108. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/pairs-negation-contra.txt +0 -0
  109. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/pairs-para-high.txt +0 -0
  110. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/pairs-value-contra.txt +0 -0
  111. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/probe-corpus-instruct.jsonl +0 -0
  112. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/probe-corpus-long.jsonl +0 -0
  113. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/probe-corpus.jsonl +0 -0
  114. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/probes-heldout.txt +0 -0
  115. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/docs/studies/probes.py +0 -0
  116. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/__init__.py +0 -0
  117. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/__main__.py +0 -0
  118. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/_atomic.py +0 -0
  119. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/_numeric.py +0 -0
  120. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/atlas/__init__.py +0 -0
  121. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/atlas/io.py +0 -0
  122. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/atlas/schema.py +0 -0
  123. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/backends/__init__.py +0 -0
  124. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/backends/cache.py +0 -0
  125. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/backends/client.py +0 -0
  126. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/__init__.py +0 -0
  127. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/_atlas_arg.py +0 -0
  128. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/cli.py +0 -0
  129. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/compare.py +0 -0
  130. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/directions.py +0 -0
  131. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/doctor.py +0 -0
  132. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/explain.py +0 -0
  133. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/neighbors.py +0 -0
  134. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/survey.py +0 -0
  135. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_commands/whoami.py +0 -0
  136. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_errors.py +0 -0
  137. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_output.py +0 -0
  138. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/cli/_provenance.py +0 -0
  139. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/corpus.py +0 -0
  140. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/explain/__init__.py +0 -0
  141. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/measure/__init__.py +0 -0
  142. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/embeddings/measure/stability.py +0 -0
  143. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/sonar-project.properties +0 -0
  144. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/__init__.py +0 -0
  145. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/_fakes.py +0 -0
  146. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_atlas_arg.py +0 -0
  147. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_atlas_io.py +0 -0
  148. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_atlas_schema.py +0 -0
  149. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_atomic.py +0 -0
  150. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_backend_cache.py +0 -0
  151. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_cli.py +0 -0
  152. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_cli_introspection.py +0 -0
  153. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_compare.py +0 -0
  154. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_fakes.py +0 -0
  155. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_map.py +0 -0
  156. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_provenance.py +0 -0
  157. {embeddings_cli-0.8.1 → embeddings_cli-0.9.1}/tests/test_survey.py +0 -0
@@ -37,6 +37,21 @@ jobs:
37
37
  env:
38
38
  SONAR_HOST_URL: https://sonarcloud.io
39
39
 
40
+ # Stricter than the quality gate: any issue left Open or Confirmed fails the run.
41
+ # An issue marked Accepted on SonarCloud does not. The scan step above waits for
42
+ # the analysis (sonar.qualitygate.wait), so the issue list is complete here.
43
+ - name: No open SonarCloud issues
44
+ if: env.SONAR_TOKEN != ''
45
+ env:
46
+ PR_NUMBER: ${{ github.event.pull_request.number }}
47
+ BRANCH_NAME: ${{ github.ref_name }}
48
+ run: |
49
+ if [ -n "$PR_NUMBER" ]; then
50
+ python3 scripts/sonar_open_issues.py --pull-request "$PR_NUMBER"
51
+ else
52
+ python3 scripts/sonar_open_issues.py --branch "$BRANCH_NAME"
53
+ fi
54
+
40
55
  lint:
41
56
  runs-on: ubuntu-latest
42
57
  permissions:
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/). This project
6
6
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.9.1] - 2026-11-14
9
+
10
+ ### Added
11
+
12
+ - CI fails when SonarCloud holds an issue left Open or Confirmed for the pull request or, on main, for the branch (`scripts/sonar_open_issues.py`, run after the scan). An issue marked Accepted does not fail it.
13
+
14
+ ### Fixed
15
+
16
+ - The 28 SonarCloud issues open on main: composite assertions split in the tests, runs of `append` replaced by `extend` in `gaps`, `map` and `regions`, and the redacted parameters of `export` built as a dict.
17
+
18
+ ## [0.9.0] - 2026-11-13
19
+
20
+ ### Added
21
+
22
+ - **`embeddings export`** — the producer step for the sibling embeddings-tumbler viewer. Turns a surveyed Atlas with its `vectors.npy` into the viewer's data contract (schema version 1): `<name>.json` plus a little-endian float32 block `<name>.f32` of exactly points x dimension x 4 bytes. Previews by default, writes only with `--apply`, refuses an existing `.json` or `.f32` without `--force`, writes each file atomically (under `--force` the old `.json` is removed first, then the block, then the new `.json`, so a failure never leaves a `.json` beside a block that is not its own), and refuses an Atlas with no vectors with a hint naming `embeddings survey`. Provenance copies the Atlas's model, seed, `limitations`, `uncertain` and `params`.
23
+ - `--labels-only` leaves the corpus out: labels are the record ids, no metadata is written, and the file states `text_included: false`.
24
+ - `--group-by <key>` writes each point's `group` from that metadata key (a non-empty string or an integer), so the viewer can colour and name points by group. Records without the key stay ungrouped; a key no record carries is refused; not combinable with `--labels-only`. Without the option no group is written.
25
+ - `provenance.params.corpus` carries only the corpus file's name, never the local path the survey recorded.
26
+ - Endpoint redaction also covers the bare host, `host:port` without credentials and a scheme-less address, ignores case, and no longer replaces a short host name inside a longer word.
27
+ - Both files are staged in full, at their final mode, before anything is removed: a failed forced re-export keeps the old pair, and a failed first export leaves nothing behind.
28
+ - Refused with a plain message instead of writing a file the viewer rejects: NaN or Infinity in metadata or parameters, a seed beyond 2^53 - 1, an empty or non-string record id, an empty model id, and a vector value that overflows float32.
29
+ - `--rotate` is an exact orthogonal rotation onto the set's principal directions (every pairwise distance kept); `--top-k <k>` keeps the first k of them and records `source_dimension`, `directions_kept` and `variance_dropped`. Neither is on unless asked for.
30
+ - `--endpoint-name <name>` writes a route name as `provenance.endpoint`. The Atlas's endpoint URL is never copied — the viewer never lets a gateway address reach a page — and the name must match the contract's allowlist `^[A-Za-z0-9][A-Za-z0-9 _-]{0,63}$` (no dots, colons or slashes, so no hostname, URL or port) or it is refused. Without the flag the field is omitted; an endpoint URL found inside copied provenance strings is replaced with `<embedding endpoint>`.
31
+ - `provenance.source` is `atlas: <folder name>`, never the path as given, so no local absolute path reaches a page; both files get mode 0644 reduced by the umask (never group or other write) instead of `write_atomic`'s 0600, so a static web server running as another user can read them.
32
+ - `tests/_viewer_contract.py` — an independent checker of the viewer's data contract, written in this repo from the contract document.
33
+
8
34
  ## [0.8.1] - 2026-07-20
9
35
 
10
36
  Review triage for PR #3 — Qodo and SonarCloud.
@@ -32,7 +32,15 @@ interpretation of the space, not the space itself.
32
32
  **The survey surface ships.** All seven verbs are implemented, registered, and
33
33
  callable — `survey`, `regions`, `neighbors`, `directions discover` /
34
34
  `directions overview`, `compare`, `gaps`, `map` — alongside the introspection
35
- verbs `whoami`, `learn`, `explain`, `overview`, `doctor`, `cli overview`. The
35
+ verbs `whoami`, `learn`, `explain`, `overview`, `doctor`, `cli overview`.
36
+ `export` is the producer step for the sibling
37
+ [`embeddings-tumbler`](https://github.com/agentculture/embeddings-tumbler)
38
+ viewer: it writes an Atlas with its vectors as the viewer's data contract
39
+ (schema version 1, `<name>.json` + float32 `<name>.f32`). It never copies the
40
+ Atlas's endpoint URL — `provenance.endpoint` is a route name from
41
+ `--endpoint-name` or is omitted — and `tests/_viewer_contract.py` is an
42
+ independent checker of that contract written in this repo, not imported from
43
+ the viewer. The
36
44
  package persists an Atlas (`embeddings/atlas/`), talks to an embedding gateway
37
45
  (`embeddings/backends/`), and measures stability (`embeddings/measure/`).
38
46
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: embeddings-cli
3
- Version: 0.8.1
3
+ Version: 0.9.1
4
4
  Summary: Maps the geometry of meaning produced by embedding models — survey a corpus into a semantic landscape, then inspect its regions, neighborhoods, directions, and gaps, and compare models. Backs a Surveyor agent that runs measured experiments against the space and records an evidence-backed Atlas.
5
5
  Project-URL: Homepage, https://github.com/agentculture/embeddings-cli
6
6
  Project-URL: Issues, https://github.com/agentculture/embeddings-cli/issues
@@ -56,6 +56,7 @@ embeddings directions discover
56
56
  embeddings gaps
57
57
  embeddings compare model-a model-b
58
58
  embeddings map --html
59
+ embeddings export --out view.json
59
60
  ```
60
61
 
61
62
  The goal is not to assign a human-readable meaning to every dimension. That is
@@ -166,6 +167,7 @@ Shipping today:
166
167
  | `compare` | Compare two atlases' k-NN overlap and rank agreement on a shared probe set — never by coordinates. |
167
168
  | `gaps` | Report corpus-coverage gaps, and (with `--probe`) what active probing shows about the model. |
168
169
  | `map` | PCA-project an atlas to 2-D; `--html` writes a self-contained map artifact. |
170
+ | `export` | Write an atlas and its vectors as an [embeddings-tumbler](https://github.com/agentculture/embeddings-tumbler) viewer data file (`<name>.json` + float32 `<name>.f32`); `--labels-only` leaves the corpus text out, `--group-by <key>` writes each point's group from a metadata key (the viewer colours by group), `--rotate` / `--top-k <k>` rotate onto principal directions. The atlas's endpoint URL is never copied — `--endpoint-name` supplies a route name. Dry-run by default; `--apply` commits. |
169
171
 
170
172
  All originally planned survey-surface verbs are now implemented and listed
171
173
  above; nothing remains planned on this surface.
@@ -38,6 +38,7 @@ embeddings directions discover
38
38
  embeddings gaps
39
39
  embeddings compare model-a model-b
40
40
  embeddings map --html
41
+ embeddings export --out view.json
41
42
  ```
42
43
 
43
44
  The goal is not to assign a human-readable meaning to every dimension. That is
@@ -148,6 +149,7 @@ Shipping today:
148
149
  | `compare` | Compare two atlases' k-NN overlap and rank agreement on a shared probe set — never by coordinates. |
149
150
  | `gaps` | Report corpus-coverage gaps, and (with `--probe`) what active probing shows about the model. |
150
151
  | `map` | PCA-project an atlas to 2-D; `--html` writes a self-contained map artifact. |
152
+ | `export` | Write an atlas and its vectors as an [embeddings-tumbler](https://github.com/agentculture/embeddings-tumbler) viewer data file (`<name>.json` + float32 `<name>.f32`); `--labels-only` leaves the corpus text out, `--group-by <key>` writes each point's group from a metadata key (the viewer colours by group), `--rotate` / `--top-k <k>` rotate onto principal directions. The atlas's endpoint URL is never copied — `--endpoint-name` supplies a route name. Dry-run by default; `--apply` commits. |
151
153
 
152
154
  All originally planned survey-surface verbs are now implemented and listed
153
155
  above; nothing remains planned on this surface.
@@ -67,6 +67,7 @@ def _build_parser() -> argparse.ArgumentParser:
67
67
  from embeddings.cli._commands import directions as _directions_group
68
68
  from embeddings.cli._commands import doctor as _doctor_cmd
69
69
  from embeddings.cli._commands import explain as _explain_cmd
70
+ from embeddings.cli._commands import export as _export_cmd
70
71
  from embeddings.cli._commands import gaps as _gaps_cmd
71
72
  from embeddings.cli._commands import learn as _learn_cmd
72
73
  from embeddings.cli._commands import map as _map_cmd
@@ -107,6 +108,7 @@ def _build_parser() -> argparse.ArgumentParser:
107
108
  _compare_cmd.register(sub)
108
109
  _gaps_cmd.register(sub)
109
110
  _map_cmd.register(sub)
111
+ _export_cmd.register(sub)
110
112
  # Register your own noun groups here:
111
113
  # from embeddings.cli._commands import my_noun as _my_noun_group
112
114
  # _my_noun_group.register(sub)