feat: FlightDeck 1.0.1 package and v1 rollout readiness#1
Conversation
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>
PR SummaryMedium Risk Overview It also tightens release integrity and local-ledger health checks by committing generated Reviewed by Cursor Bugbot for commit 295db21. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Non-atomic audit_seq in
insert_promotion_recordrisks integrityinsert_promotion_recordnow uses the same immediate transaction path as promotion commits, with a regression test covering lock acquisition.
- ✅ Fixed: Duplicate
utc_nowdefined in two modules- Removed the storage-local duplicate and imported the canonical
utc_nowfrommodelsin both storage and CLI usage.
- Removed the storage-local duplicate and imported the canonical
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.
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>


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.