Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 13 additions & 22 deletions HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,31 @@

## Finished

- Basic CLI commands and local/PostgreSQL imports keep Google SDKs unloaded; generic OAuth JWT signing uses the existing PyJWT dependency.
- Base and PostgreSQL installations omit Google SDKs. Existing BigQuery/GCP and full-runtime extras retain their provider dependencies; selected BigQuery commands explain missing extras.
- Distribution CI exercises five fresh installation profiles outside the checkout, including actual PostgreSQL adapter imports.
- PostgreSQL recovery queries an index of unfinished runs; conditional writes maintain its eligibility flag atomically and public run history stays complete.
- Schema v4 backfills from validated canonical records without changing their bytes or revisions; migration failures roll back.
- Reconciled retained August 27–28 Control/Fargate/Spark successes and corrected the obsolete DANDER-251 non-execution claim.
- Updated five completed tickets, Druff hosted-mode documentation, and Salesforce plugin write-command boundaries.
- Prepared Salesforce 0.3.2, ServiceNow 0.2.3, and Dander catalog/install-check patches outside this documentation change.

## Try It

For development, run `uv sync --frozen --extra dev --extra postgres --extra bigquery --extra gcp`.
For a lean PostgreSQL checkout, use `uv sync --frozen --extra postgres`.
Try `uv run dander control serve --profile examples/control/local.yaml` and stop with Ctrl-C.
See README installation profiles and `docs/control-profiles.md` before upgrading an existing database.
Read `docs/control-execution-history.md`, then `docs/support-status.md`. Prepared package and catalog patches are in `/tmp/dander-curated-compat-20260930/`.

## Checks

- Final integrated suite: 2,416 tests passed with disposable PostgreSQL 15. Focused Control suite also passed 398 tests on PostgreSQL 17. Test containers were removed.
- Canonical strict typing passed for 507 files; Ruff lint/format, Control contract drift, release metadata, and diff checks passed.
- Wheel/source archive validation and all five fresh-install profiles passed after the dependency split. Base and PostgreSQL profiles contained no Google SDKs.
- Migration tests cover backfill/reopen, bytes/revisions, rollback on corruption, conditional-write conflicts, pending-page continuation, complete history, and recovery readiness/fallback.
- Fresh base installation: 97 to 60 distributions; package-file metadata totals 290.1 to 52.3 MiB on this Mac. These are local installation measurements, not deployment memory or cloud cost.
- Documentation: relative links, retained output equality, source/image identities, and `git diff --check` passed.
- Prepared fixes: 93 Salesforce and 23 ServiceNow tests passed on public Dander 0.7.1 and 0.9.0rc20, current 0.9.0rc32, and each package's locked environment. Package lint, format, and typing passed.
- Prepared Dander patch: 37 focused tests, full Ruff lint/format, canonical strict typing (507 files), contract drift, and outside-checkout wheel resolution/metadata/entry-point checks passed using local candidate wheels.

## Decisions

- Keep provider SDK imports and optional-dependency errors at selected provider boundaries; no package versions changed in the lockfile.
- A run needs recovery until execution, outcome, results, and cleanup are resolved; readiness checks recovery, not completed-history integrity.
- Stop the single Control process for the v4 migration. Backfill holds table locks; older binaries reject v4, so mixed-version operation is unsupported.
- Retained live evidence qualifies only its named revisions and workloads; no new cloud runs or support promotion.
- Do not publish catalog pins until the corresponding packages exist on PyPI.

## Remaining

- No live database upgrade or provider qualification was performed. Existing provider support boundaries and public RC20 remain unchanged.
- A future deployed upgrade needs a maintenance window sized for its saved history and the documented single-process restart.
- Await the requested narrow exception to AGENTS.md's single-writable-repository rule for the two existing connector repositories.
- Then apply the prepared connector patches, complete protected CI/publication, verify PyPI, apply the Dander catalog patch, and merge with exact-main CI.

## Review First

- `src/dander/control/postgresql_control_database.py` and `postgresql_run_store.py`
- `src/dander/control/run_lifecycle.py` and `tests/control/test_postgresql_run_store.py`
- `pyproject.toml`, `scripts/check_provider_installations.py`, and README installation profiles
- `docs/control-execution-history.md` and corrected support boundaries.
- `/tmp/dander-curated-compat-20260930/*-compatibility.patch` for the pending package work.
36 changes: 36 additions & 0 deletions docs/control-execution-history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Retained Control execution history

Reconciled September 30, 2026 against the operator's retained status records, provider result
files, runtime events, output comparisons, and cleanup records. This corrects the former claim
that DANDER-251 was never executed. It does not rerun cloud workloads or qualify current source.

The original records remain operator-local under `~/.codex/operator/<record>/evidence/`.
They contain infrastructure coordinates and provider output, so this page publishes only a
reviewed summary. These are retained observations, not current cloud inventories. Dates use UTC.

| Gate | Accepted date and record | Source revision | Observed result |
|---|---|---|---|
| DANDER-235 | August 27; `dander-235-3aec709` | `3aec7096d1f5e0967344e6fabd57d5d182679709`; final verifier `9a5e5363b22352c11e03ab44f459ec86d3bfe8e0` | Corrected S3-backed Control/Fargate API and scheduled runs, each 3 rows and 3 assertions; restart adoption, cancellation, result persistence, and cleanup passed. The API run succeeded on its second attempt after a transient failure. |
| [DANDER-243](../tickets/DANDER-243-immutable-spark-pair-qualification.md) | August 27; `dander-243-817a06a` | Image/driver `5f66cf5d6c51ba7e54a823f9554b7ce6059a16e4`; Control `1f26be5bb883c6c28bacbba20d6bff96ccbb7fad` | Fixed two-executor Spark pair succeeded through Control: 4 extracted/affected rows, 3 assertions, one model, runtime telemetry, and exchange cleanup. |
| DANDER-246 | August 28; `dander-246-7ebc443` | `7ebc443c58a769e61c1be56aee0bd1565f48d463` | Fargate and Spark linear runs returned the same 36 rows against an unchanged raw snapshot. |
| DANDER-247 | August 28; `dander-247-2cfa287` | `2cfa2872daef984d7e69127111fbf4047505e4cd` | Supplied input estimates selected two static Spark shapes; both completed with identical output. This was not dynamic autoscaling. |
| DANDER-248 | August 28; `dander-248-8d0ac6a` | `8d0ac6a954daf24f6a875f98b3bfbec5054fed0a` | Fargate and Spark keyed joins returned the same two expected rows. |
| DANDER-249 | August 28; `dander-249-b024a58` | `b024a5882b0948169f75a1ccaa7a3372cf3fad5e` | Warehouse metadata selected small and large static Spark shapes; both returned the same two rows, with durable attempt history and restart recovery. |
| [DANDER-251](../tickets/DANDER-251-static-multistage-linear-execution.md) | August 28; `dander-251-d00bdbc` | `d00bdbc854b344247feb3a37c59ae93085a0f5af` | Fargate and Spark two-transform chains returned the same 36 rows. Spark reported three stages, two exchanges, and seven telemetry operations. |

Each accepted record includes cleanup of its owned temporary resources. Accepted artifacts were
retained; DANDER-247 also explicitly retained its raw/target tables. Earlier failed attempts remain
historical records and are not overwritten by these later successes.

## DANDER-251 immutable pair

- Main image index: `sha256:faa4599b7bfac723890bd54acee62b5759bca6812e29b13955b1f65f73570040`.
- Spark image index: `sha256:530a25c426e4c9e60183b3d5c1811f0e1bfc7c55a45558f7ddc6adab4994ca2c`.
- Fargate run: `run-0da5ab2c67ca710c80c3f5e1`; Spark run: `run-a7500d05403df21ead0d6b0a`.
- Retained equal-output SHA-256: `d95068c56a68f41fc59b52e7795652e29c40c939260a81a5b12fb699fc193553`.
- Cleanup recorded no remaining owned run objects, exchanges, batch, target, running tasks, or
disposable Spark network/identity resources; the retained Fargate schedule was disabled.

These narrow proofs do not close arbitrary DAG execution, dynamic scaling, production HA,
enterprise Hadoop, or DANDER-207's broader scale/cost/soak/release gates. See
[current support status](support-status.md) for the release and topology boundaries.
25 changes: 17 additions & 8 deletions docs/known-limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ Hosted Control registers Fargate, Cloud Run, and bounded Dataproc Serverless exe
Typed startup selects PostgreSQL or S3 run storage; scheduling selects PostgreSQL or the existing
AWS EventBridge/SQS composition. PostgreSQL uses one dedicated Control schema and removes the
mandatory AWS storage dependency. This integration supports one Control process per run-store
schema and does not qualify a hosted topology. The August 26 DANDER-235 attempt stopped at a missing queue-tag permission; that
dated attempt is not a current infrastructure inspection or a qualification of later source.
schema and does not qualify a hosted PostgreSQL topology. The August 26 DANDER-235 attempt
stopped at a missing queue-tag permission; the corrected August 27 S3-backed Control/Fargate
qualification subsequently passed. See the [dated execution history](control-execution-history.md)
for this and the later bounded Spark runs; neither qualifies a different topology or candidate.
Direct CLI execution remains available independently of Control.

The Phase 5 warehouse implementations and the
Expand Down Expand Up @@ -134,9 +136,13 @@ remain Phase 8 work.
- ServiceNow incidents extraction performs a stably ordered full endpoint read. It does not use a
timestamp watermark with offset paging because that combination can skip moving records.
- Source hard deletes are not propagated by the first ServiceNow incidents slice.
- Salesforce reads Accounts, Contacts, Opportunities, and Users only. QueryAll preserves visible
soft-deletion tombstones, but hard-deleted or purged records cannot be recovered and provider
write-back is not supported. ServiceNow remains one read-only incident slice.
- The built-in Salesforce source reads Accounts, Contacts, Opportunities, and Users only.
QueryAll preserves visible soft-deletion tombstones, but hard-deleted or purged records cannot
be recovered from that feed. The separate Salesforce plugin also implements explicit deleted
lookups and operator-invoked create/update/delete, plus upsert when an External ID field is
configured and verified. These optional commands do not make `dander run` a write-back workflow
or establish live qualification of provider writes. ServiceNow remains one read-only incident
slice. See [connector plugins](connector-plugins.md) for package compatibility and activation.
- NetSuite customers are simulator-validated only. The first SuiteQL slice performs a full read,
is capped by NetSuite's 100,000-result SuiteQL REST limit, and has not passed tenant-specific
role, field-availability, or authentication acceptance. It is not in the current public support
Expand All @@ -158,9 +164,12 @@ remain Phase 8 work.
chain and numeric provider status without exception text or sensitive values. Earlier
undiagnosable ServiceNow failures remain historical evidence; the retained trial subsequently
completed its final clean window and closed. See the [operator-trial closure](operator-soak.md).
- Druff is a public static interface, not a hosted control plane. Saving, validation, execution,
status, and deployment preview require an operator-started Dander loopback service. Druff does
not write `dander.yaml` or apply Terraform.
- Druff is the browser interface to Dander Control. Its local mode uses an operator-started
loopback service; its hosted mode uses an explicit Control endpoint and OIDC authorization-code
login with PKCE. Hosted graph persistence and run/status/log/cancel/replay controls are
implemented. Retained browser acceptance used synthetic OIDC, not a production identity-provider
or HA proof. Druff does not write `dander.yaml` or apply Terraform. See the
[reviewed Druff revision](https://github.com/harrisonoconnorhover/druff/tree/62879d5f865fe8ee2473beb18538f30a218caf40).

## Platform and cost

Expand Down
16 changes: 9 additions & 7 deletions docs/support-status.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Current implementation and support status

Updated September 7, 2026. This page is the current overview; dated decisions and acceptance
Updated September 30, 2026. This page is the current overview; dated decisions and acceptance
records preserve what happened on their named revisions. Update this page when a capability is
integrated or a named release/profile changes status.

Expand All @@ -25,7 +25,8 @@ the final paused/no-drift state. These are dated observations, not a continuous
| Direct single-container execution | Existing default path | Does not require hosted Control, Spark, Kubernetes, or Hadoop. |
| Hosted Control API, graph persistence, OIDC | Implemented with named local/cloud acceptance records | Experimental; each profile keeps its own identity, storage, and lifecycle evidence. |
| Control execution through Fargate, Cloud Run, or Dataproc | Implemented with typed PostgreSQL or S3 run storage | Experimental; one Control process per run-store schema. AWS compatibility flags remain available. |
| Distributed Spark graphs | Bounded linear, keyed-join, and two-transform shapes implemented | Experimental; DANDER-251 has no accepted immutable paired Fargate/Dataproc parity record. |
| Distributed Spark graphs | Bounded linear, keyed-join, and two-transform shapes implemented; retained August 27–28 runs include exact Fargate/Dataproc output parity | Experimental; the [execution history](control-execution-history.md) identifies each tested revision and bounded shape. |
| Druff hosted authoring | Hosted Control connections, OIDC/PKCE, persisted graphs, and run lifecycle controls implemented | Experimental; retained browser checks used synthetic OIDC. They do not establish production identity-provider or HA qualification. |
| PostgreSQL, Snowflake, Redshift warehouse adapters | Local conformance and named bounded live evidence | Experimental; the runtime compatibility matrix determines allowed state/warehouse pairs. |
| Azure, OCI, Kubernetes profiles | Named lifecycle/qualification records | No general support promotion; consult each exact profile's evidence. |
| PostgreSQL Control graphs/runs/schedules | Database conformance plus one real Cloud Run graph with crash recovery, cancellation, output, and history checks | Experimental; one local Control process, no supported hosted or multiple-replica topology. |
Expand All @@ -44,9 +45,9 @@ The [profile preparation example](control-profiles.md) now registers an existing
and writes its plan and startup files together. S3/Azure/OCI graph records and journals also share
one definition; further operation consolidation is optional.

1. Attribute existing AWS account costs and remove confirmed idle Dander resources before the next
paid qualification phase. The conservative monthly reservation is close to the USD 25 ceiling;
account-wide billing alone does not identify which resources belong to Dander.
1. Reconcile current Dander costs and reservations before the next paid qualification phase.
The September 7 snapshot was close to the USD 25 monthly cash ceiling; it is not a current
balance. Account-wide billing alone does not identify which resources belong to Dander.
2. Fill the legacy graph's operation-level telemetry gap before relying on its byte counters for
cost comparisons. The successful workflow exposed row metrics but no recorded operations.
3. Identify an existing secure Hadoop environment and its owner before live enterprise tests.
Expand All @@ -61,5 +62,6 @@ broader qualification gates still determine enterprise support.

[DANDER-207](../tickets/DANDER-207-phase8-soak-release.md) remains open. Its broader scale/cost,
pairwise, other-profile soak, audit, and release gates are not closed by the GCP observation or
the enterprise branch. Historical DANDER-251 parity work was left unexecuted; future execution
needs a current objective and does not rewrite the old evidence.
the enterprise branch. The completed historical DANDER-251 parity run qualifies its recorded
immutable pair and bounded graph only. A future candidate needs its own current objective and
verification; the [historical evidence](control-execution-history.md) does not qualify it.
13 changes: 10 additions & 3 deletions tickets/DANDER-243-immutable-spark-pair-qualification.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
id: DANDER-243
title: Publish and qualify one immutable Spark driver and image pair
status: in-review
status: done
component: python
epic: control-orchestration
depends_on: [DANDER-242]
Expand All @@ -23,9 +23,9 @@ particular driver and image. This slice supplies exactly one narrow pair and one
- [x] Build an amd64 Debian 12 custom image with Spark's required UID/GID and utilities, without
bundling Spark or a JRE.
- [x] Contract-test the plan, Control handoff, driver/image identity, and Control result parser.
- [ ] Publish one tag-immutable image whose tag resolves to the recorded digest and one same-region
- [x] Publish one tag-immutable image whose tag resolves to the recorded digest and one same-region
GCS driver object from exact main.
- [ ] Run one two-executor Managed Spark/BigQuery qualification through Control and clean up its
- [x] Run one two-executor Managed Spark/BigQuery qualification through Control and clean up its
disposable dataset, bucket contents, batch metadata where supported, and temporary IAM.

## Boundaries
Expand All @@ -34,3 +34,10 @@ particular driver and image. This slice supplies exactly one narrow pair and one
cluster creation, or reusable arbitrary-operator runtime is introduced.
- This qualifies one fixed driver/image pair, not every distributed Dander pipeline.
- C27, RC32, Phase 8, releases, and the existing main runtime image remain untouched.

## Retained acceptance reconciliation — September 30, 2026

The August 27–28 operator records confirm the immutable publication and bounded execution
criteria above. See the [reviewed execution history](../docs/control-execution-history.md) for
the exact source revision, result, cleanup boundary, and retained record identifier. Earlier
failed attempts remain historical evidence; no new cloud execution was performed for this update.
13 changes: 10 additions & 3 deletions tickets/DANDER-246-reusable-linear-spark-runtime.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
id: DANDER-246
title: Execute one reusable linear graph through Managed Spark
status: in-review
status: done
component: python
epic: control-orchestration
depends_on: [DANDER-245]
Expand All @@ -28,9 +28,9 @@ hard-coded its BigQuery output. This slice replaces that fixture with one graph-
writer modes, cross-project relations, mutable configuration, and changed executor shape.
- [x] Preserve byte-identical driver/image identity, canonical Control results, verified exchange
cleanup, and the existing single-container graph execution path.
- [ ] Publish one immutable main runtime image and one immutable Spark image/driver from the same
- [x] Publish one immutable main runtime image and one immutable Spark image/driver from the same
exact-main commit, with their digests recorded.
- [ ] Run exactly one fused Fargate cell followed by one Dataproc cell against the same raw BigQuery
- [x] Run exactly one fused Fargate cell followed by one Dataproc cell against the same raw BigQuery
snapshot, prove exact output parity, capture Control evidence, and clean disposable resources.

## Boundaries
Expand All @@ -39,3 +39,10 @@ hard-coded its BigQuery output. This slice replaces that fixture with one graph-
allocation, autotuning, Kubernetes, cluster management, or new reconciler.
- No extra acceptance cells, soak, status-only PR, evidence framework, release, C27, RC32, or
Phase 8 work.

## Retained acceptance reconciliation — September 30, 2026

The August 27–28 operator records confirm the immutable publication and bounded execution
criteria above. See the [reviewed execution history](../docs/control-execution-history.md) for
the exact source revision, result, cleanup boundary, and retained record identifier. Earlier
failed attempts remain historical evidence; no new cloud execution was performed for this update.
Loading
Loading