sediment-api 0.4.0__tar.gz → 0.5.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 (72) hide show
  1. {sediment_api-0.4.0 → sediment_api-0.5.0}/PKG-INFO +5 -5
  2. {sediment_api-0.4.0 → sediment_api-0.5.0}/pyproject.toml +5 -5
  3. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/__init__.py +1 -1
  4. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_e2e_smoke.py +59 -0
  5. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_v1.py +1 -1
  6. {sediment_api-0.4.0 → sediment_api-0.5.0}/.gitignore +0 -0
  7. {sediment_api-0.4.0 → sediment_api-0.5.0}/LICENSE +0 -0
  8. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/config.py +0 -0
  9. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/database.py +0 -0
  10. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/deps.py +0 -0
  11. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/main.py +0 -0
  12. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/mirror_gc.py +0 -0
  13. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/__init__.py +0 -0
  14. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/abandonment_report.py +0 -0
  15. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/attribution_share_report.py +0 -0
  16. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/dataset_diagnostics.py +0 -0
  17. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/label_confidence_inspection.py +0 -0
  18. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/lifecycle_report.py +0 -0
  19. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/merge_retention_report.py +0 -0
  20. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/model_report.py +0 -0
  21. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/precision_report.py +0 -0
  22. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/reports/recovery_yield_report.py +0 -0
  23. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/__init__.py +0 -0
  24. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/ci_vendor.py +0 -0
  25. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/forge.py +0 -0
  26. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/gateway.py +0 -0
  27. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/otlp.py +0 -0
  28. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/query.py +0 -0
  29. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/reports.py +0 -0
  30. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/routers/v1.py +0 -0
  31. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/services/__init__.py +0 -0
  32. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/services/operational_reports.py +0 -0
  33. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/worker.py +0 -0
  34. {sediment_api-0.4.0 → sediment_api-0.5.0}/sediment_api/workers.py +0 -0
  35. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/conftest.py +0 -0
  36. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_attribution_share_report.py +0 -0
  37. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_baseline_gap_repro.py +0 -0
  38. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_bug_repro_offset.py +0 -0
  39. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_capture_record_isolation.py +0 -0
  40. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_ci_vendor.py +0 -0
  41. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_config.py +0 -0
  42. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_context_discovery_authority.py +0 -0
  43. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_context_discovery_query.py +0 -0
  44. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_context_discovery_workers.py +0 -0
  45. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_context_evidence_query.py +0 -0
  46. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_context_query.py +0 -0
  47. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_credential_authorities.py +0 -0
  48. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_database_lifecycle.py +0 -0
  49. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_database_outage.py +0 -0
  50. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_database_role_startup.py +0 -0
  51. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_dataset_diagnostics_report.py +0 -0
  52. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_evidence_query.py +0 -0
  53. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_evidence_worker_imports.py +0 -0
  54. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_evidence_workers.py +0 -0
  55. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_gateway_capture_receipt.py +0 -0
  56. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_gateway_identity.py +0 -0
  57. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_lifecycle_report_cli.py +0 -0
  58. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_merge_retention_cli.py +0 -0
  59. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_one_shot_database.py +0 -0
  60. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_operational_reports.py +0 -0
  61. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_operational_reports_service.py +0 -0
  62. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_postgres_gateway_tracer.py +0 -0
  63. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_push_mirror.py +0 -0
  64. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_query.py +0 -0
  65. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_report_attachment_scope.py +0 -0
  66. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_report_routes.py +0 -0
  67. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_repository_identity_ingest.py +0 -0
  68. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_repository_identity_model_service.py +0 -0
  69. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_repository_identity_queries.py +0 -0
  70. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_retrieval_authority.py +0 -0
  71. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_worker_processes.py +0 -0
  72. {sediment_api-0.4.0 → sediment_api-0.5.0}/tests/test_worker_routes.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sediment-api
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Sediment ingest API: facts in through three doors
5
5
  Project-URL: Source, https://github.com/sediment-ai/sediment
6
6
  Project-URL: Documentation, https://github.com/sediment-ai/sediment/tree/main/docs
@@ -13,8 +13,8 @@ Requires-Dist: anyio>=4.15.1
13
13
  Requires-Dist: fastapi>=0.141.1
14
14
  Requires-Dist: httpx>=0.27
15
15
  Requires-Dist: pydantic-settings>=2.15.0
16
- Requires-Dist: sediment-capture==0.4.0
17
- Requires-Dist: sediment-core==0.4.0
18
- Requires-Dist: sediment-derive==0.4.0
19
- Requires-Dist: sediment-export==0.4.0
16
+ Requires-Dist: sediment-capture==0.5.0
17
+ Requires-Dist: sediment-core==0.5.0
18
+ Requires-Dist: sediment-derive==0.5.0
19
+ Requires-Dist: sediment-export==0.5.0
20
20
  Requires-Dist: uvicorn>=0.54.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sediment-api"
3
- version = "0.4.0"
3
+ version = "0.5.0"
4
4
  description = "Sediment ingest API: facts in through three doors"
5
5
  requires-python = ">=3.12"
6
6
  license = "AGPL-3.0-or-later"
@@ -12,10 +12,10 @@ dependencies = [
12
12
  "httpx>=0.27",
13
13
  "uvicorn>=0.54.0",
14
14
  "pydantic-settings>=2.15.0",
15
- "sediment-core==0.4.0",
16
- "sediment-capture==0.4.0",
17
- "sediment-derive==0.4.0",
18
- "sediment-export==0.4.0",
15
+ "sediment-core==0.5.0",
16
+ "sediment-capture==0.5.0",
17
+ "sediment-derive==0.5.0",
18
+ "sediment-export==0.5.0",
19
19
  ]
20
20
 
21
21
  [project.urls]
@@ -3,4 +3,4 @@
3
3
 
4
4
  # Single source for the API version string — FastAPI's ``app.version``
5
5
  # (reported by /health) and GET /v1/me both read it, so the two cannot drift.
6
- __version__ = "0.4.0"
6
+ __version__ = "0.5.0"
@@ -194,6 +194,65 @@ def test_otlp_fixtures_to_decision_facts(client: TestClient) -> None:
194
194
  assert len(_store().read_decisions(settings.org_id)) == expected
195
195
 
196
196
 
197
+ def test_claude_code_account_identity_removed_before_storage(
198
+ client: TestClient,
199
+ ) -> None:
200
+ from sediment_core import REDACTION_MARKER
201
+
202
+ payload = _fixture("otlp/claude_code/tool_decision_acceptedits_edit.json")
203
+ records = payload["resourceLogs"][0]["scopeLogs"][0]["logRecords"]
204
+ tool_input = {
205
+ "file_path": "/home/dev/project/target.txt",
206
+ "old_string": "original text",
207
+ "new_string": "Bearer synthetic-credential-1234567890",
208
+ }
209
+ for record in records:
210
+ attrs = record["attributes"]
211
+ attrs.extend(
212
+ [
213
+ {"key": "user.email", "value": {"stringValue": "account@example.test"}},
214
+ {"key": "user.account_id", "value": {"stringValue": "account-123"}},
215
+ {
216
+ "key": "user.account_uuid",
217
+ "value": {"stringValue": "22222222-2222-4222-8222-222222222222"},
218
+ },
219
+ ]
220
+ )
221
+ if any(
222
+ attr["key"] == "tool_name" and attr["value"].get("stringValue") == "Edit"
223
+ for attr in attrs
224
+ ):
225
+ for attr in attrs:
226
+ if attr["key"] == "tool_input":
227
+ attr["value"] = {"stringValue": json.dumps(tool_input)}
228
+
229
+ response = client.post("/v1/logs", json=payload, headers=_auth())
230
+
231
+ assert response.status_code == 200
232
+ assert response.json() == {}
233
+ [decision] = _store().read_decisions(settings.org_id)
234
+ assert "account@example.test" not in decision.model_dump_json()
235
+ assert "account-123" not in decision.model_dump_json()
236
+ assert "22222222-2222-4222-8222-222222222222" not in decision.model_dump_json()
237
+ stored_input = next(
238
+ attr["value"]["stringValue"]
239
+ for attr in decision.raw["result"]["attributes"]
240
+ if attr["key"] == "tool_input"
241
+ )
242
+ assert json.loads(stored_input) == {
243
+ **tool_input,
244
+ "new_string": f"Bearer {REDACTION_MARKER}",
245
+ }
246
+ assert decision.file_path == tool_input["file_path"]
247
+ assert decision.call_id == "toolu_0000000000000002"
248
+ assert decision.session_id == "11111111-1111-1111-1111-111111111111"
249
+ assert decision.user_id == "spike-dev"
250
+ assert decision.accepted is True
251
+ assert decision.explicit is False
252
+ assert client.post("/v1/logs", json=payload, headers=_auth()).status_code == 200
253
+ assert _store().read_decisions(settings.org_id) == [decision]
254
+
255
+
197
256
  def test_otlp_chunked_transfer_body(client: TestClient) -> None:
198
257
  # Real OTLP exporters stream chunked (no Content-Length); the route must
199
258
  # still assemble and parse the body.
@@ -101,7 +101,7 @@ def test_me_happy_path(client: TestClient) -> None:
101
101
  assert resp.status_code == 200
102
102
  assert resp.json() == {
103
103
  "org_id": ORG,
104
- "version": "0.4.0",
104
+ "version": "0.5.0",
105
105
  "authority": "operator",
106
106
  "client_id": "operator",
107
107
  }
File without changes
File without changes