Skip to content

feat: FlightDeck 1.0.1 package and v1 rollout readiness#1

Merged
Gsbreddy merged 6 commits into
mainfrom
chore/1.0.1-v1-rollout-readiness
May 1, 2026
Merged

feat: FlightDeck 1.0.1 package and v1 rollout readiness#1
Gsbreddy merged 6 commits into
mainfrom
chore/1.0.1-v1-rollout-readiness

Conversation

@Gsbreddy
Copy link
Copy Markdown
Collaborator

@Gsbreddy Gsbreddy commented May 1, 2026

Ship the local-first CLI, schemas, tests, and CI. Slim-repo docs link to canonical flightdeckdev/flightdeck main. OpenTelemetry is optional-only.

Also: pytest basetemp under .tmp/pytest for Windows, Python 3.13–3.14 in CI, ruff 0.15.12 aligned with ruff-pre-commit, pre-commit-hooks v5, .gitattributes LF for golden bundle, CHANGELOG 1.0.1 section and empty Unreleased, RELEASE_NOTES v1.0.1 patch notes, README quickstart_smoke first.

zendaya and others added 4 commits May 1, 2026 15:35
Ship the local-first CLI, schemas, tests, and CI. Slim-repo docs link to
canonical flightdeckdev/flightdeck main. OpenTelemetry is optional-only.

Also: pytest basetemp under .tmp/pytest for Windows, Python 3.13–3.14 in CI,
ruff 0.15.12 aligned with ruff-pre-commit, pre-commit-hooks v5, .gitattributes
LF for golden bundle, CHANGELOG 1.0.1 section and empty Unreleased,
RELEASE_NOTES v1.0.1 patch notes, README quickstart_smoke first.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
@cursor
Copy link
Copy Markdown

cursor Bot commented May 1, 2026

PR Summary

Medium Risk
Medium risk because it introduces new release automation (tag-driven PyPI publish) and touches core CLI/storage integrity paths (bundle checksum, migrations/audit sequencing) that could affect upgrades and governance invariants.

Overview
This PR packages FlightDeck as flightdeck-ai v1.0.1 (Python 3.14 only), adds uv-based developer workflow, and introduces GitHub Actions for CI (lint/test/schema-drift/quickstart smoke on Linux+Windows) plus a tag-driven PyPI publish pipeline with version/tag consistency checks and GitHub Release creation.

It also tightens release integrity and local-ledger health checks by committing generated schemas/v1 with a generator script + drift guard, enforcing LF checkout for the golden bundle fixture, and expanding the CLI/storage surface with doctor checks (migrations/promoted pointers/audit_seq) and release verify checksum comparisons backed by new golden fixtures and cross-platform smoke/tests.

Reviewed by Cursor Bugbot for commit 295db21. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Non-atomic audit_seq in insert_promotion_record risks integrity
    • insert_promotion_record now uses the same immediate transaction path as promotion commits, with a regression test covering lock acquisition.
  • ✅ Fixed: Duplicate utc_now defined in two modules
    • Removed the storage-local duplicate and imported the canonical utc_now from models in both storage and CLI usage.

Create PR

Or push these changes by commenting:

@cursor push 55972ca243
Preview (55972ca243)
diff --git a/src/flightdeck/cli/main.py b/src/flightdeck/cli/main.py
--- a/src/flightdeck/cli/main.py
+++ b/src/flightdeck/cli/main.py
@@ -16,8 +16,17 @@
 from flightdeck.config import DEFAULT_CONFIG_FILENAME, load_config, write_default_config
 from flightdeck.doctor import run_doctor
 from flightdeck.ledger import diff_releases, parse_window
-from flightdeck.models import Policy, PolicyResult, PricingTable, PromotionRecord, ReleaseArtifact, ReleaseRecord, RunEvent
-from flightdeck.storage import Storage, utc_now
+from flightdeck.models import (
+    Policy,
+    PolicyResult,
+    PricingTable,
+    PromotionRecord,
+    ReleaseArtifact,
+    ReleaseRecord,
+    RunEvent,
+    utc_now,
+)
+from flightdeck.storage import Storage
 
 
 def read_release_artifact(path: Path) -> ReleaseArtifact:

diff --git a/src/flightdeck/storage.py b/src/flightdeck/storage.py
--- a/src/flightdeck/storage.py
+++ b/src/flightdeck/storage.py
@@ -5,18 +5,14 @@
 import sqlite3
 from contextlib import contextmanager
 from dataclasses import dataclass
-from datetime import datetime, timezone
+from datetime import datetime
 from pathlib import Path
 from typing import Any, Iterable
 from uuid import uuid4
 
-from flightdeck.models import Policy, PolicyResult, PricingTable, PromotionRecord, ReleaseRecord, RunEvent
+from flightdeck.models import Policy, PolicyResult, PricingTable, PromotionRecord, ReleaseRecord, RunEvent, utc_now
 
 
-def utc_now() -> datetime:
-    return datetime.now(timezone.utc)
-
-
 def ensure_parent_dir(db_path: str) -> None:
     Path(db_path).expanduser().resolve().parent.mkdir(parents=True, exist_ok=True)
 
@@ -506,7 +502,7 @@
         )
 
     def insert_promotion_record(self, record: PromotionRecord) -> None:
-        with self.connect() as conn:
+        with self.transaction() as conn:
             self._insert_release_action_conn(conn, record)
 
     def commit_promotion(self, record: PromotionRecord, *, new_promoted_release_id: str) -> None:

diff --git a/tests/test_doctor.py b/tests/test_doctor.py
--- a/tests/test_doctor.py
+++ b/tests/test_doctor.py
@@ -7,6 +7,8 @@
 from click.testing import CliRunner
 
 from flightdeck.cli.main import cli
+from flightdeck.models import PolicyResult, PromotionRecord
+from flightdeck.storage import Storage
 
 from tests.test_spine import write_events, write_policy, write_pricing, write_release
 
@@ -107,6 +109,45 @@
     assert "audit_seq" in res.output.lower()
 
 
+def test_insert_promotion_record_uses_immediate_transaction(tmp_path: Path) -> None:
+    storage = Storage(str(tmp_path / "flightdeck.db"))
+    storage.migrate()
+    with storage.connect() as conn:
+        conn.execute(
+            """
+            INSERT INTO releases
+              (release_id, agent_id, version, environment, checksum, artifact_json, created_at)
+            VALUES (?, ?, ?, ?, ?, ?, ?)
+            """,
+            ("rel_1", "agent_support", "1", "local", "sha256:abc", "{}", "2026-05-01T00:00:00+00:00"),
+        )
+
+    record = PromotionRecord(
+        action_id="act_1",
+        action="promote",
+        actor="tester",
+        release_id="rel_1",
+        agent_id="agent_support",
+        environment="local",
+        reason="test",
+        policy_result=PolicyResult(passed=True),
+        created_at=datetime.now(tz=timezone.utc),
+    )
+
+    competing_conn = storage.connect()
+    try:
+        competing_conn.execute("BEGIN IMMEDIATE;")
+        try:
+            storage.insert_promotion_record(record)
+        except sqlite3.OperationalError as exc:
+            assert "database is locked" in str(exc)
+        else:
+            raise AssertionError("insert_promotion_record did not request an immediate write lock")
+    finally:
+        competing_conn.rollback()
+        competing_conn.close()
+
+
 def test_doctor_fails_when_promoted_release_missing(tmp_path: Path, monkeypatch) -> None:
     monkeypatch.chdir(tmp_path)
     runner = CliRunner()

You can send follow-ups to the cloud agent here.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 295db21. Configure here.

Comment thread src/flightdeck/storage.py
Comment thread src/flightdeck/storage.py Outdated
Gsbreddy and others added 2 commits May 1, 2026 16:44
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
…cstrings (#4)

- CHANGELOG.md: add Fixed entry under Unreleased for PR #3 (zero policy
  sample thresholds were silently ignored due to falsy 'or' fallback;
  now uses 'is not None' checks)
- ledger.py: add docstrings to confidence_label, evaluate_policy, and
  diff_releases explaining threshold semantics (None vs 0 vs config default),
  confidence label tiers, constraint fields, and agent-id invariant
- models.py: add Policy class docstring explaining the None/0 distinction
  for min_* threshold fields versus constraint (max_*) fields
- schemas/v1/policy.schema.json: regenerated to pick up Policy docstring

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Gottam Sai Bharath <Gsbreddy@users.noreply.github.com>
@Gsbreddy Gsbreddy merged commit 8819ad8 into main May 1, 2026
2 checks passed
@Gsbreddy Gsbreddy deleted the chore/1.0.1-v1-rollout-readiness branch May 1, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants