shkit 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. shkit-1.2.0/.github/workflows/build-wheel.yml +154 -0
  2. shkit-1.2.0/.github/workflows/ci.yml +23 -0
  3. shkit-1.2.0/.github/workflows/deploy-prod.yml +36 -0
  4. shkit-1.2.0/.github/workflows/incident-dispatch.yml +33 -0
  5. shkit-1.2.0/.github/workflows/publish-tenant.yml +70 -0
  6. shkit-1.2.0/.github/workflows/pull-antibodies.yml +68 -0
  7. shkit-1.2.0/.github/workflows/push-antibodies.yml +86 -0
  8. shkit-1.2.0/.github/workflows/release-pypi.yml +75 -0
  9. shkit-1.2.0/.gitignore +15 -0
  10. shkit-1.2.0/PKG-INFO +239 -0
  11. shkit-1.2.0/README.md +209 -0
  12. shkit-1.2.0/config/dev.yml +24 -0
  13. shkit-1.2.0/config/prod.yml +24 -0
  14. shkit-1.2.0/config/staging.yml +24 -0
  15. shkit-1.2.0/config/workspace.yml +26 -0
  16. shkit-1.2.0/databricks.yml +46 -0
  17. shkit-1.2.0/dbt_project/.user.yml +1 -0
  18. shkit-1.2.0/dbt_project/dbt_project.yml +17 -0
  19. shkit-1.2.0/dbt_project/models/ai_accuracy_metrics.sql +26 -0
  20. shkit-1.2.0/dbt_project/models/healing_audit_log.sql +33 -0
  21. shkit-1.2.0/dbt_project/models/healing_config.sql +12 -0
  22. shkit-1.2.0/dbt_project/models/healing_state.sql +30 -0
  23. shkit-1.2.0/dbt_project/models/resolution_cache.sql +27 -0
  24. shkit-1.2.0/dbt_project/models/schema.yml +60 -0
  25. shkit-1.2.0/dbt_project/models/token_budget.sql +24 -0
  26. shkit-1.2.0/dbt_project/profiles.yml +24 -0
  27. shkit-1.2.0/dbt_project/seeds/healing_config_defaults.csv +9 -0
  28. shkit-1.2.0/dbt_project/tests/assert_valid_action_ids.sql +7 -0
  29. shkit-1.2.0/dbt_project/tests/assert_valid_healing_modes.sql +5 -0
  30. shkit-1.2.0/deploy/init_scripts/iic_agent.sh +23 -0
  31. shkit-1.2.0/docs/ANTIBODIES.md +162 -0
  32. shkit-1.2.0/docs/ARCHITECTURE.md +743 -0
  33. shkit-1.2.0/docs/AUTOMATION.md +226 -0
  34. shkit-1.2.0/docs/INSTALL.md +81 -0
  35. shkit-1.2.0/docs/MIGRATION.md +64 -0
  36. shkit-1.2.0/docs/SELF_ARMING.md +73 -0
  37. shkit-1.2.0/docs/V4_ARCHITECTURE.md +139 -0
  38. shkit-1.2.0/docs/architecture.svg +368 -0
  39. shkit-1.2.0/iic_autoload.pth +1 -0
  40. shkit-1.2.0/notebooks/approval_handler.py +34 -0
  41. shkit-1.2.0/notebooks/audit_retention.py +33 -0
  42. shkit-1.2.0/notebooks/incident_engine.py +34 -0
  43. shkit-1.2.0/notebooks/weekly_accuracy_job.py +122 -0
  44. shkit-1.2.0/onboarding/__init__.py +1 -0
  45. shkit-1.2.0/onboarding/cli.py +168 -0
  46. shkit-1.2.0/onboarding/config_schema.py +62 -0
  47. shkit-1.2.0/onboarding/manifest.py +27 -0
  48. shkit-1.2.0/onboarding/preflight.py +129 -0
  49. shkit-1.2.0/onboarding/provisioner.py +573 -0
  50. shkit-1.2.0/onboarding/rollback.py +81 -0
  51. shkit-1.2.0/pyproject.toml +81 -0
  52. shkit-1.2.0/requirements.txt +7 -0
  53. shkit-1.2.0/resources/incident_workflows.yml +42 -0
  54. shkit-1.2.0/scripts/publish_tenant.py +200 -0
  55. shkit-1.2.0/scripts/smoke_databricks.md +87 -0
  56. shkit-1.2.0/scripts/smoke_local.py +97 -0
  57. shkit-1.2.0/scripts/sync_antibodies.py +322 -0
  58. shkit-1.2.0/setup.py +83 -0
  59. shkit-1.2.0/src/healing_kit/__init__.py +3 -0
  60. shkit-1.2.0/src/healing_kit/auth.py +79 -0
  61. shkit-1.2.0/src/healing_kit/clients/__init__.py +1 -0
  62. shkit-1.2.0/src/healing_kit/clients/databricks_client.py +183 -0
  63. shkit-1.2.0/src/healing_kit/clients/teams_client.py +128 -0
  64. shkit-1.2.0/src/healing_kit/models/__init__.py +1 -0
  65. shkit-1.2.0/src/healing_kit/models/diagnosis.py +45 -0
  66. shkit-1.2.0/src/healing_kit/models/events.py +30 -0
  67. shkit-1.2.0/src/healing_kit/models/evidence.py +83 -0
  68. shkit-1.2.0/src/healing_kit/runtime/__init__.py +6 -0
  69. shkit-1.2.0/src/healing_kit/runtime/approval.py +141 -0
  70. shkit-1.2.0/src/healing_kit/runtime/maintenance.py +52 -0
  71. shkit-1.2.0/src/healing_kit/services/__init__.py +1 -0
  72. shkit-1.2.0/src/healing_kit/services/cache_service.py +120 -0
  73. shkit-1.2.0/src/healing_kit/services/circuit_breaker.py +114 -0
  74. shkit-1.2.0/src/healing_kit/services/context_agent.py +127 -0
  75. shkit-1.2.0/src/healing_kit/services/dependency_graph.py +141 -0
  76. shkit-1.2.0/src/healing_kit/services/diagnosis_engine.py +165 -0
  77. shkit-1.2.0/src/healing_kit/services/identity.py +61 -0
  78. shkit-1.2.0/src/healing_kit/services/model_router.py +52 -0
  79. shkit-1.2.0/src/healing_kit/services/query_guard.py +168 -0
  80. shkit-1.2.0/src/healing_kit/services/resolution_verifier.py +100 -0
  81. shkit-1.2.0/src/healing_kit/services/token_budget.py +137 -0
  82. shkit-1.2.0/src/healing_kit/utils/__init__.py +1 -0
  83. shkit-1.2.0/src/healing_kit/utils/error_hash.py +15 -0
  84. shkit-1.2.0/src/healing_kit/utils/hmac_tokens.py +86 -0
  85. shkit-1.2.0/src/healing_kit/utils/sql_safety.py +84 -0
  86. shkit-1.2.0/src/iic/__init__.py +51 -0
  87. shkit-1.2.0/src/iic/__main__.py +18 -0
  88. shkit-1.2.0/src/iic/_console.py +235 -0
  89. shkit-1.2.0/src/iic/_doctor.py +143 -0
  90. shkit-1.2.0/src/iic/change/__init__.py +7 -0
  91. shkit-1.2.0/src/iic/change/change_detector.py +154 -0
  92. shkit-1.2.0/src/iic/context/__init__.py +7 -0
  93. shkit-1.2.0/src/iic/context/context_builder.py +117 -0
  94. shkit-1.2.0/src/iic/dependency/__init__.py +7 -0
  95. shkit-1.2.0/src/iic/dependency/dependency_analyzer.py +93 -0
  96. shkit-1.2.0/src/iic/diagnosis/__init__.py +7 -0
  97. shkit-1.2.0/src/iic/diagnosis/diagnosis_engine.py +183 -0
  98. shkit-1.2.0/src/iic/dna/__init__.py +7 -0
  99. shkit-1.2.0/src/iic/dna/dna_builder.py +184 -0
  100. shkit-1.2.0/src/iic/impact/__init__.py +7 -0
  101. shkit-1.2.0/src/iic/impact/impact_engine.py +102 -0
  102. shkit-1.2.0/src/iic/ingestion/__init__.py +14 -0
  103. shkit-1.2.0/src/iic/ingestion/base.py +21 -0
  104. shkit-1.2.0/src/iic/ingestion/databricks_source.py +98 -0
  105. shkit-1.2.0/src/iic/ingestion/static_source.py +23 -0
  106. shkit-1.2.0/src/iic/ingestion/webhook_source.py +39 -0
  107. shkit-1.2.0/src/iic/models/__init__.py +44 -0
  108. shkit-1.2.0/src/iic/models/change.py +77 -0
  109. shkit-1.2.0/src/iic/models/context.py +46 -0
  110. shkit-1.2.0/src/iic/models/diagnosis.py +37 -0
  111. shkit-1.2.0/src/iic/models/dna.py +77 -0
  112. shkit-1.2.0/src/iic/models/event.py +78 -0
  113. shkit-1.2.0/src/iic/models/impact.py +60 -0
  114. shkit-1.2.0/src/iic/models/report.py +88 -0
  115. shkit-1.2.0/src/iic/models/routing.py +41 -0
  116. shkit-1.2.0/src/iic/notify/__init__.py +7 -0
  117. shkit-1.2.0/src/iic/notify/teams_notifier.py +112 -0
  118. shkit-1.2.0/src/iic/report/__init__.py +7 -0
  119. shkit-1.2.0/src/iic/report/report_generator.py +67 -0
  120. shkit-1.2.0/src/iic/routing/__init__.py +7 -0
  121. shkit-1.2.0/src/iic/routing/router.py +42 -0
  122. shkit-1.2.0/src/iic/runtime/__init__.py +10 -0
  123. shkit-1.2.0/src/iic/runtime/_sql.py +11 -0
  124. shkit-1.2.0/src/iic/runtime/agent_config.py +48 -0
  125. shkit-1.2.0/src/iic/runtime/agent_runtime.py +70 -0
  126. shkit-1.2.0/src/iic/runtime/antibodies.py +100 -0
  127. shkit-1.2.0/src/iic/runtime/bootstrap.py +157 -0
  128. shkit-1.2.0/src/iic/runtime/constants.py +40 -0
  129. shkit-1.2.0/src/iic/runtime/context.py +46 -0
  130. shkit-1.2.0/src/iic/runtime/detective.py +72 -0
  131. shkit-1.2.0/src/iic/runtime/hooks.py +85 -0
  132. shkit-1.2.0/src/iic/runtime/incident_engine.py +207 -0
  133. shkit-1.2.0/src/iic/runtime/inprocess.py +350 -0
  134. shkit-1.2.0/src/iic/runtime/ledger.py +120 -0
  135. shkit-1.2.0/src/iic/runtime/monitor.py +155 -0
  136. shkit-1.2.0/src/iic/runtime/pattern_store.py +53 -0
  137. shkit-1.2.0/src/iic/runtime/reconciler.py +139 -0
  138. shkit-1.2.0/src/iic/runtime/scope_config.py +127 -0
  139. shkit-1.2.0/src/iic/runtime/store.py +150 -0
  140. shkit-1.2.0/src/iic/runtime/wrapper.py +28 -0
  141. shkit-1.2.0/tests/__init__.py +1 -0
  142. shkit-1.2.0/tests/integration/__init__.py +1 -0
  143. shkit-1.2.0/tests/integration/check_agent_run.py +44 -0
  144. shkit-1.2.0/tests/integration/check_job_params.py +18 -0
  145. shkit-1.2.0/tests/integration/check_task_output.py +27 -0
  146. shkit-1.2.0/tests/integration/deploy_consolidated_agent.py +57 -0
  147. shkit-1.2.0/tests/integration/fix_job_add_aggregator.py +82 -0
  148. shkit-1.2.0/tests/integration/test_v2_live_validation.py +189 -0
  149. shkit-1.2.0/tests/property/__init__.py +1 -0
  150. shkit-1.2.0/tests/unit/__init__.py +1 -0
  151. shkit-1.2.0/tests/unit/test_circuit_breaker.py +58 -0
  152. shkit-1.2.0/tests/unit/test_error_hash.py +43 -0
  153. shkit-1.2.0/tests/unit/test_identity.py +53 -0
  154. shkit-1.2.0/tests/unit/test_iic_change_detector.py +55 -0
  155. shkit-1.2.0/tests/unit/test_iic_context_builder.py +58 -0
  156. shkit-1.2.0/tests/unit/test_iic_dependency_analyzer.py +42 -0
  157. shkit-1.2.0/tests/unit/test_iic_diagnosis_engine.py +81 -0
  158. shkit-1.2.0/tests/unit/test_iic_dna_builder.py +79 -0
  159. shkit-1.2.0/tests/unit/test_iic_engine.py +97 -0
  160. shkit-1.2.0/tests/unit/test_iic_event.py +59 -0
  161. shkit-1.2.0/tests/unit/test_iic_impact_engine.py +63 -0
  162. shkit-1.2.0/tests/unit/test_iic_report_and_notify.py +71 -0
  163. shkit-1.2.0/tests/unit/test_iic_router.py +47 -0
  164. shkit-1.2.0/tests/unit/test_model_router.py +48 -0
  165. shkit-1.2.0/tests/unit/test_query_guard.py +74 -0
  166. shkit-1.2.0/tests/unit/test_resolution_verifier.py +72 -0
  167. shkit-1.2.0/tests/unit/test_sql_safety.py +72 -0
  168. shkit-1.2.0/tests/unit/test_v4_antibodies.py +288 -0
  169. shkit-1.2.0/tests/unit/test_v4_console_doctor.py +148 -0
  170. shkit-1.2.0/tests/unit/test_v4_context_cache.py +44 -0
  171. shkit-1.2.0/tests/unit/test_v4_detective.py +135 -0
  172. shkit-1.2.0/tests/unit/test_v4_monitor.py +109 -0
  173. shkit-1.2.0/tests/unit/test_v4_reconciler.py +78 -0
  174. shkit-1.2.0/tests/unit/test_v4_scope_config.py +145 -0
  175. shkit-1.2.0/tests/unit/test_v4_self_arming.py +201 -0
@@ -0,0 +1,154 @@
1
+ name: Build & publish IIC wheel
2
+
3
+ # v4 distribution: on merge to main, build the wheel and upload it to DBFS as the
4
+ # "latest" agent artifact that clusters install via the init script.
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ tags: ["v*"]
9
+
10
+ permissions:
11
+ contents: write # needed to attach the wheel to a GitHub Release on tags
12
+
13
+ jobs:
14
+ build-and-publish:
15
+ runs-on: ubuntu-latest
16
+ # Job-level env IS available to a step's `if:` (step-level env is not — that was
17
+ # the bug). Empty strings when the secrets aren't configured → publish is skipped.
18
+ env:
19
+ DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
20
+ DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - uses: actions/setup-python@v5
24
+ with:
25
+ python-version: "3.11"
26
+
27
+ - name: Build wheel
28
+ run: |
29
+ pip install build
30
+ python -m build --wheel
31
+ ls -l dist/
32
+
33
+ - name: Verify self-arming packaging (.pth at wheel root + arms on install)
34
+ run: |
35
+ set -e
36
+ WHEEL=$(ls dist/*.whl | head -1)
37
+ echo "Checking $WHEEL for iic_autoload.pth at archive root..."
38
+ python -m zipfile -l "$WHEEL" | awk '{print $1}' | grep -qxE 'iic_autoload\.pth' \
39
+ || { echo "FAIL: iic_autoload.pth not at wheel root"; exit 1; }
40
+ echo "OK: .pth at wheel root"
41
+ python -m venv /tmp/iic_smoke_venv
42
+ /tmp/iic_smoke_venv/bin/pip install --quiet "$WHEEL"
43
+ echo "Confirming the .pth arms the tripwire at interpreter startup..."
44
+ /tmp/iic_smoke_venv/bin/python -c "import sys; assert 'iic.runtime.bootstrap' in sys.modules, 'bootstrap not auto-imported'; print('OK: tripwire armed at startup')"
45
+
46
+ - name: Self-arming integration smoke (failure → mock webhook gets one card)
47
+ run: |
48
+ WHEEL=$(ls dist/*.whl | head -1)
49
+ python scripts/smoke_local.py "$WHEEL"
50
+
51
+ - name: Upload wheel artifact (always)
52
+ uses: actions/upload-artifact@v4
53
+ with:
54
+ name: iic-wheel
55
+ path: dist/*.whl
56
+
57
+ # On every push to main: refresh a rolling "latest" pre-release with the new
58
+ # wheel and emit the copyable install URL — auto-publish, no tag needed.
59
+ - name: Publish rolling "latest" release
60
+ if: github.ref == 'refs/heads/main'
61
+ uses: softprops/action-gh-release@v2
62
+ with:
63
+ tag_name: latest
64
+ name: "Latest (rolling — auto-published from main)"
65
+ prerelease: true
66
+ files: dist/*.whl
67
+
68
+ - name: Latest install URL → summary
69
+ if: github.ref == 'refs/heads/main'
70
+ run: |
71
+ WHEEL=$(ls dist/*.whl | head -1)
72
+ NAME=$(basename "$WHEEL")
73
+ URL="https://github.com/${{ github.repository }}/releases/download/latest/${NAME}"
74
+ echo "==========================================="
75
+ echo "DATABRICKS INSTALL URL (latest, copy this):"
76
+ echo "$URL"
77
+ echo "==========================================="
78
+ {
79
+ echo "## 🚀 IIC SDK (latest) — auto-published from main"
80
+ echo ""
81
+ echo "**Wheel:** \`${NAME}\`"
82
+ echo ""
83
+ echo "### Databricks install URL (copy this):"
84
+ echo '```'
85
+ echo "$URL"
86
+ echo '```'
87
+ echo ""
88
+ echo "_Always points at the most recent main build. Install via a cluster"
89
+ echo "init script \`pip install <url>\` or a notebook \`%pip install <url>\`._"
90
+ } >> "$GITHUB_STEP_SUMMARY"
91
+
92
+ # On a version tag (e.g. v1.0.0): publish the wheel to a GitHub Release and
93
+ # emit a copyable Databricks install URL — no Databricks dependency, no secrets.
94
+ - name: Generate Databricks install URL
95
+ id: url
96
+ if: startsWith(github.ref, 'refs/tags/')
97
+ run: |
98
+ WHEEL=$(ls dist/*.whl | head -1)
99
+ NAME=$(basename "$WHEEL")
100
+ URL="https://github.com/${{ github.repository }}/releases/download/${GITHUB_REF_NAME}/${NAME}"
101
+ {
102
+ echo "install_url=$URL"
103
+ echo "wheel_name=$NAME"
104
+ } >> "$GITHUB_OUTPUT"
105
+ echo "==========================================="
106
+ echo "DATABRICKS INSTALL URL (copy this):"
107
+ echo "$URL"
108
+ echo "==========================================="
109
+
110
+ - name: Publish to GitHub Release
111
+ if: startsWith(github.ref, 'refs/tags/')
112
+ uses: softprops/action-gh-release@v2
113
+ with:
114
+ files: dist/*.whl
115
+ body: |
116
+ ## 🚀 IIC SDK ${{ github.ref_name }}
117
+
118
+ **Databricks install URL — copy this:**
119
+
120
+ ```
121
+ ${{ steps.url.outputs.install_url }}
122
+ ```
123
+
124
+ Install on a cluster via a notebook `%pip install <url>` or a cluster
125
+ init script `pip install <url>`, then restart — the agent
126
+ auto-bootstraps on import. See `docs/V4_ARCHITECTURE.md`.
127
+
128
+ - name: Write job summary
129
+ if: startsWith(github.ref, 'refs/tags/')
130
+ run: |
131
+ {
132
+ echo "## 🚀 IIC SDK Published — ${GITHUB_REF_NAME}"
133
+ echo ""
134
+ echo "**Wheel:** \`${{ steps.url.outputs.wheel_name }}\`"
135
+ echo ""
136
+ echo "### Databricks install URL (copy this):"
137
+ echo '```'
138
+ echo "${{ steps.url.outputs.install_url }}"
139
+ echo '```'
140
+ } >> "$GITHUB_STEP_SUMMARY"
141
+
142
+ # Publish to DBFS only when Databricks credentials are configured as repo
143
+ # secrets. Skipped (not failed) otherwise, so forks/PRs still build cleanly.
144
+ - name: Set up Databricks CLI
145
+ if: ${{ env.DATABRICKS_HOST != '' && env.DATABRICKS_TOKEN != '' }}
146
+ uses: databricks/setup-cli@main
147
+
148
+ - name: Publish to DBFS as latest
149
+ if: ${{ env.DATABRICKS_HOST != '' && env.DATABRICKS_TOKEN != '' }}
150
+ run: |
151
+ WHEEL=$(ls dist/*.whl | head -1)
152
+ echo "Uploading $WHEEL -> dbfs:/libs/iic/latest.whl"
153
+ databricks fs cp --overwrite "$WHEEL" dbfs:/libs/iic/latest.whl
154
+ databricks fs cp --overwrite "$WHEEL" "dbfs:/libs/iic/$(basename "$WHEEL")"
@@ -0,0 +1,23 @@
1
+ name: CI
2
+ on:
3
+ pull_request:
4
+ branches: [main]
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ lint-and-test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.11"
16
+ - name: Install package
17
+ run: pip install -e ".[dev]"
18
+ - name: Lint source code
19
+ run: ruff check src/ onboarding/ --ignore E501
20
+ - name: Lint unit tests
21
+ run: ruff check tests/unit/ --ignore E501
22
+ - name: Run unit tests
23
+ run: pytest tests/unit/ -v --tb=short
@@ -0,0 +1,36 @@
1
+ name: Deploy Production
2
+ on:
3
+ workflow_dispatch:
4
+ inputs:
5
+ confirm:
6
+ description: 'Type "deploy-prod" to confirm'
7
+ required: true
8
+
9
+ jobs:
10
+ deploy:
11
+ runs-on: ubuntu-latest
12
+ if: github.event.inputs.confirm == 'deploy-prod'
13
+ environment: production
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: databricks/setup-cli@main
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.11"
20
+
21
+ - name: Install dbt
22
+ run: pip install dbt-databricks
23
+
24
+ - name: Run dbt build (create/update tables)
25
+ run: cd dbt_project && dbt build --target prod
26
+ env:
27
+ DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST_PROD }}
28
+ DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN_PROD }}
29
+ DATABRICKS_HTTP_PATH: ${{ secrets.DATABRICKS_HTTP_PATH_PROD }}
30
+ DATABRICKS_CATALOG: prod_catalog
31
+
32
+ - name: Deploy bundle
33
+ run: databricks bundle deploy --target prod
34
+ env:
35
+ DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST_PROD }}
36
+ DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN_PROD }}
@@ -0,0 +1,33 @@
1
+ name: IIC incident detective
2
+
3
+ # Event-driven ONLY — fires when the in-process agent sends a repository_dispatch
4
+ # after a failure. No schedule, no polling. PAYLOAD-ONLY: the issue is rendered
5
+ # entirely from the self-contained client_payload — GitHub never touches the
6
+ # customer's Databricks workspace, so there are no tenant tokens here.
7
+ on:
8
+ repository_dispatch:
9
+ types: [iic_incident]
10
+
11
+ permissions:
12
+ contents: read
13
+ issues: write # to archive the incident as an issue
14
+
15
+ jobs:
16
+ investigate:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.11"
24
+
25
+ - name: Install IIC
26
+ run: pip install .
27
+
28
+ - name: Archive incident (from payload only)
29
+ env:
30
+ IIC_PAYLOAD: ${{ toJSON(github.event.client_payload) }}
31
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32
+ GITHUB_REPOSITORY: ${{ github.repository }}
33
+ run: python -m iic.runtime.detective
@@ -0,0 +1,70 @@
1
+ name: "[DEPRECATED] Publish IIC to tenant (manual)"
2
+
3
+ # ⚠️ DEPRECATED (product-model): distribution moved to PyPI (release-pypi.yml) and
4
+ # config moved to a Databricks secret scope (see docs/INSTALL.md + docs/MIGRATION.md).
5
+ # Kept functional for ONE release for migration; will be deleted. This is the only
6
+ # remaining workflow that references the DBX_TOKENS secret.
7
+ #
8
+ # MANUAL ONLY — never auto-runs. You pick a tenant from the dropdown and the wheel
9
+ # is published to THAT tenant's Databricks Volume only. Tenant config (host/volume)
10
+ # comes from the private Access-private repo; the Databricks token comes from the
11
+ # DBX_TOKENS secret (never from the config repo).
12
+ on:
13
+ workflow_dispatch:
14
+ inputs:
15
+ tenant:
16
+ description: "Tenant to publish for"
17
+ type: choice
18
+ required: true
19
+ options:
20
+ - zeb
21
+ # add tenants here as you add folders under Access-private/tenants/
22
+
23
+ permissions:
24
+ contents: read
25
+
26
+ jobs:
27
+ publish:
28
+ runs-on: ubuntu-latest
29
+ # Optional: require an approval before publishing.
30
+ # environment: production
31
+ steps:
32
+ - name: Checkout code
33
+ uses: actions/checkout@v4
34
+
35
+ - name: Checkout tenant config (Access-private)
36
+ uses: actions/checkout@v4
37
+ with:
38
+ repository: yogasathyandrun/Access-private
39
+ path: _tenants
40
+ token: ${{ secrets.CONFIG_REPO_TOKEN }}
41
+
42
+ - uses: actions/setup-python@v5
43
+ with:
44
+ python-version: "3.11"
45
+
46
+ - name: Build wheel
47
+ run: |
48
+ pip install build databricks-sdk pyyaml
49
+ python -m build --wheel
50
+ ls -l dist/
51
+
52
+ - name: Publish to selected tenant
53
+ env:
54
+ TENANT: ${{ inputs.tenant }}
55
+ DBX_TOKENS: ${{ secrets.DBX_TOKENS }}
56
+ run: python scripts/publish_tenant.py
57
+
58
+ - name: Summary
59
+ if: always()
60
+ run: |
61
+ echo "## 📦 IIC published to tenant: \`${{ inputs.tenant }}\`" >> "$GITHUB_STEP_SUMMARY"
62
+ echo "" >> "$GITHUB_STEP_SUMMARY"
63
+ echo "Uploaded: **wheel + base_environment.yml → Workspace** (base-env builder can't read Volumes)," >> "$GITHUB_STEP_SUMMARY"
64
+ echo "and **config.yaml → Volume** (read by the agent at runtime). See job log for exact paths." >> "$GITHUB_STEP_SUMMARY"
65
+ echo "" >> "$GITHUB_STEP_SUMMARY"
66
+ echo "➡️ One-time per workspace: **Admin Settings → Workspace base environments for serverless** →" >> "$GITHUB_STEP_SUMMARY"
67
+ echo "set **Base environment file path** to the uploaded \`/Workspace/.../base_environment.yml\`" >> "$GITHUB_STEP_SUMMARY"
68
+ echo "(✅ default for new notebooks). It references the Workspace wheel → new serverless" >> "$GITHUB_STEP_SUMMARY"
69
+ echo "notebooks self-arm automatically. See docs/SELF_ARMING.md. Mute via a \`DISABLED\` file" >> "$GITHUB_STEP_SUMMARY"
70
+ echo "next to config.yaml in the Volume." >> "$GITHUB_STEP_SUMMARY"
@@ -0,0 +1,68 @@
1
+ name: "[DEPRECATED] Pull antibodies from tenant (manual)"
2
+
3
+ # ⚠️ DEPRECATED (product-model): the antibody ledger is now workspace-local and is
4
+ # folded by the in-workspace console notebook (iic.console()); there is no git
5
+ # mirror and no operator sync. Kept one release for migration; will be deleted.
6
+ #
7
+ # MANUAL ONLY. Downloads the tenant's Antibody Ledger + pending occurrence markers
8
+ # from its Databricks Volume, folds the occurrences into the git ledger
9
+ # (Access-private/tenants/<tenant>/antibodies.yaml), commits it, and uploads the
10
+ # merged ledger back to the Volume. A human then fills in `resolution:` values in
11
+ # the committed file via the GitHub web editor; push-antibodies.yml ships them back.
12
+ #
13
+ # NOTE: this commits to the PRIVATE Access-private repo, so CONFIG_REPO_TOKEN must
14
+ # have WRITE (contents) scope on that repo (publish-tenant.yml only needs read).
15
+ on:
16
+ workflow_dispatch:
17
+ inputs:
18
+ tenant:
19
+ description: "Tenant to pull antibodies from"
20
+ type: choice
21
+ required: true
22
+ options:
23
+ - zeb
24
+ # add tenants here as you add folders under Access-private/tenants/
25
+
26
+ permissions:
27
+ contents: read
28
+
29
+ jobs:
30
+ pull:
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - name: Checkout code
34
+ uses: actions/checkout@v4
35
+
36
+ - name: Checkout tenant config (Access-private, write scope)
37
+ uses: actions/checkout@v4
38
+ with:
39
+ repository: yogasathyandrun/Access-private
40
+ path: _tenants
41
+ token: ${{ secrets.CONFIG_REPO_TOKEN }}
42
+
43
+ - uses: actions/setup-python@v5
44
+ with:
45
+ python-version: "3.11"
46
+
47
+ - name: Install
48
+ run: pip install . databricks-sdk pyyaml
49
+
50
+ - name: Pull + fold pending occurrences
51
+ env:
52
+ TENANT: ${{ inputs.tenant }}
53
+ DBX_TOKENS: ${{ secrets.DBX_TOKENS }}
54
+ CONFIG_DIR: _tenants
55
+ run: python scripts/sync_antibodies.py --mode pull
56
+
57
+ - name: Commit updated ledger to Access-private
58
+ run: |
59
+ cd _tenants
60
+ git config user.name "iic-antibodies-bot"
61
+ git config user.email "iic-antibodies-bot@users.noreply.github.com"
62
+ git add "tenants/${{ inputs.tenant }}/antibodies.yaml"
63
+ if git diff --cached --quiet; then
64
+ echo "No ledger changes to commit."
65
+ else
66
+ git commit -m "antibodies(${{ inputs.tenant }}): fold pending occurrence(s)"
67
+ git push
68
+ fi
@@ -0,0 +1,86 @@
1
+ name: "[DEPRECATED] Push antibodies to tenant"
2
+
3
+ # ⚠️ DEPRECATED (product-model): the antibody ledger is now workspace-local (edited
4
+ # in the workspace via iic.console()), with no git mirror and no operator sync.
5
+ # Kept one release for migration; will be deleted.
6
+ #
7
+ # Ships the human-edited Antibody Ledger from git back to the tenant's Databricks
8
+ # Volume. Runs the merge rule against the CURRENT Volume copy first (so counters
9
+ # that accumulated since the last pull are not clobbered — git only wins on
10
+ # `resolution`), then uploads the result to {volume}/antibodies.yaml.
11
+ #
12
+ # Triggers:
13
+ # * workflow_dispatch — manual, pick a tenant.
14
+ # * repository_dispatch — fired by a tiny companion workflow in the
15
+ # (type: antibodies_push) Access-private repo whenever someone edits
16
+ # tenants/<t>/antibodies.yaml. Cross-repo `push`
17
+ # path filters can't reach this repo directly, so
18
+ # the edit side sends a repository_dispatch.
19
+ #
20
+ # Companion workflow to paste into Access-private (.github/workflows/notify-antibodies.yml):
21
+ #
22
+ # on:
23
+ # push:
24
+ # paths: ["tenants/*/antibodies.yaml"]
25
+ # jobs:
26
+ # notify:
27
+ # runs-on: ubuntu-latest
28
+ # steps:
29
+ # - uses: actions/checkout@v4
30
+ # - name: Fire push for each changed tenant
31
+ # env:
32
+ # GH_TOKEN: ${{ secrets.KIT_DISPATCH_TOKEN }} # repo scope on Self-healing-kit
33
+ # run: |
34
+ # for f in $(git diff --name-only HEAD~1 HEAD | grep 'tenants/.*/antibodies.yaml'); do
35
+ # t=$(echo "$f" | cut -d/ -f2)
36
+ # gh api repos/yogasathyandrun/Self-healing-kit/dispatches \
37
+ # -f event_type=antibodies_push -F client_payload[tenant]="$t"
38
+ # done
39
+
40
+ on:
41
+ workflow_dispatch:
42
+ inputs:
43
+ tenant:
44
+ description: "Tenant to push antibodies to"
45
+ type: choice
46
+ required: true
47
+ options:
48
+ - zeb
49
+ # add tenants here as you add folders under Access-private/tenants/
50
+ repository_dispatch:
51
+ types: [antibodies_push]
52
+
53
+ permissions:
54
+ contents: read
55
+
56
+ jobs:
57
+ push:
58
+ runs-on: ubuntu-latest
59
+ steps:
60
+ - name: Resolve tenant
61
+ id: t
62
+ run: echo "tenant=${{ inputs.tenant || github.event.client_payload.tenant }}" >> "$GITHUB_OUTPUT"
63
+
64
+ - name: Checkout code
65
+ uses: actions/checkout@v4
66
+
67
+ - name: Checkout tenant config (Access-private)
68
+ uses: actions/checkout@v4
69
+ with:
70
+ repository: yogasathyandrun/Access-private
71
+ path: _tenants
72
+ token: ${{ secrets.CONFIG_REPO_TOKEN }}
73
+
74
+ - uses: actions/setup-python@v5
75
+ with:
76
+ python-version: "3.11"
77
+
78
+ - name: Install
79
+ run: pip install . databricks-sdk pyyaml
80
+
81
+ - name: Push ledger to the Volume
82
+ env:
83
+ TENANT: ${{ steps.t.outputs.tenant }}
84
+ DBX_TOKENS: ${{ secrets.DBX_TOKENS }}
85
+ CONFIG_DIR: _tenants
86
+ run: python scripts/sync_antibodies.py --mode push
@@ -0,0 +1,75 @@
1
+ name: Release to PyPI
2
+
3
+ # On a version tag (v*): build sdist+wheel, run the FULL gate (lint + unit tests +
4
+ # the .pth-at-wheel-root assertion + the fresh-venv arms-on-install + the
5
+ # self-arming smoke), then publish to PyPI via TRUSTED PUBLISHING (OIDC). No PyPI
6
+ # API token is stored anywhere.
7
+ #
8
+ # ONE-TIME MAINTAINER SETUP (on PyPI, before the first release):
9
+ # 1. Claim the distribution name in pyproject.toml [project].name. `iic` may be
10
+ # taken — if so, change [project].name (the ONLY place the dist name lives;
11
+ # the import name stays `iic`) and re-run the grep check in docs/INSTALL.md.
12
+ # 2. Add a PyPI "Trusted Publisher": this repo, workflow `release-pypi.yml`,
13
+ # environment `pypi`. See https://docs.pypi.org/trusted-publishers/.
14
+ on:
15
+ push:
16
+ tags: ["v*"]
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ gate:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.11"
29
+
30
+ - name: Install + lint + unit tests
31
+ run: |
32
+ pip install -e ".[dev]"
33
+ ruff check src/ onboarding/ --ignore E501
34
+ pytest tests/unit/ -q
35
+
36
+ - name: Build sdist + wheel
37
+ run: |
38
+ pip install build
39
+ python -m build
40
+ ls -l dist/
41
+
42
+ - name: Gate — .pth at wheel root + arms on install
43
+ run: |
44
+ set -e
45
+ WHEEL=$(ls dist/*.whl | head -1)
46
+ python -m zipfile -l "$WHEEL" | awk '{print $1}' | grep -qxE 'iic_autoload\.pth' \
47
+ || { echo "FAIL: iic_autoload.pth not at wheel root"; exit 1; }
48
+ python -m venv /tmp/relvenv
49
+ /tmp/relvenv/bin/pip install --quiet "$WHEEL" 2>/dev/null || /tmp/relvenv/bin/pip install --quiet "$WHEEL"
50
+ /tmp/relvenv/bin/python -c "import sys; assert 'iic.runtime.bootstrap' in sys.modules, 'bootstrap not auto-imported'; print('OK: tripwire armed at startup')"
51
+
52
+ - name: Gate — self-arming smoke (failure → one card)
53
+ run: |
54
+ WHEEL=$(ls dist/*.whl | head -1)
55
+ python scripts/smoke_local.py "$WHEEL"
56
+
57
+ - name: Upload dist
58
+ uses: actions/upload-artifact@v4
59
+ with:
60
+ name: dist
61
+ path: dist/*
62
+
63
+ publish:
64
+ needs: gate
65
+ runs-on: ubuntu-latest
66
+ environment: pypi
67
+ permissions:
68
+ id-token: write # OIDC for PyPI Trusted Publishing — no API token stored
69
+ steps:
70
+ - uses: actions/download-artifact@v4
71
+ with:
72
+ name: dist
73
+ path: dist
74
+ - name: Publish to PyPI (Trusted Publishing / OIDC)
75
+ uses: pypa/gh-action-pypi-publish@release/v1
shkit-1.2.0/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ *.egg-info/
8
+ .env
9
+ config.json
10
+ deployment_manifest.json
11
+ dbt_project/target/
12
+ dbt_project/logs/
13
+ dbt_project/dbt_packages/
14
+ .venv/
15
+ venv/