You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
Deterministic tracker verb surface (flowctl tracker ..., fn-140, spec B of the tracker-determinism batch). The tracker-sync prose workflows now have a deterministic Python backend in flowctl_tracker/: locator-addressed wire verbs (read/update/comment/label/assign/attach/list-open), lifecycle verbs (create, create-first, persist-external), status (fn-66 merge-evidence gate decides; --to is a request), relate (two-phase depRelations ledger, additive-only), sync-body (server readback is the canonical tracker half; paired merge base committed atomically), and the sync facade (push|pull|reconcile|comment as one unit with create-if-unlinked, native-title projection on push/reconcile, marker dedup, and one aggregate receipt). All four adapters (GitHub, GitLab, Linear, Jira) run behind a never-raises boundary with structured degraded evidence, honest pagination (truncated, never silent absence), per-spec operation claims under the shared writer lock, and identity guards that refuse to persist across a mid-flight relink. Verified by a cross-adapter conformance matrix with fault injection plus a live smoke against all four trackers.
Changed
Tracker determinism batch completed (fn-139, fn-140, fn-141). Provider request execution moved from skill prose into the zero-dependency flowctl_tracker/ package, with injected transport boundaries, bounded responses, deterministic error classification, scoped tracker.resolved destination and capability snapshots, and distribution parity across bundled installs. flowctl tracker now owns normalized wire verbs, lifecycle verbs, and the composed sync facade; lifecycle callers retain their bridge-active and perEvent gates, compose semantic content in private input files, and make one facade call with one aggregate receipt. The tracker-sync skill is reduced to five named judgment surfaces: host MCP continuation, discovery choices, semantic 3-way body conflict adjudication, comment content synthesis, and recovery routing from structured classes. The retired tracker-runner and runtime transport-selection recipes are gone. The immutable fn-130 B1 baseline remains untouched; the post-teardown candidate records 452,552 to 137,920 reached-path characters across all 15 tracker fixtures, a 69.52% reduction by design. This deliberately supersedes fn-57 R3's prohibition on tracker mutations in flowctl.
Autonomous skill seams now continue explicitly instead of reading like terminal handoffs. Pilot and Work forced-reference gates, review backend returns, and post-task dispatches direct the host to continue the same invocation. Work recognizes all four headless-autonomy markers before delegation consent, while interactive consent still asks and persists normally. Plan Review keeps host-only mechanics cold until the host backend is selected. Genuine terminal verdicts, receipts, sandbox authority, and non-host backend behavior are unchanged.
/flow-next:resolve-pr now audits confirmed bot findings for sibling instances in the same cycle. After proving an automated-review finding valid, the resolver states the violated invariant, inspects adjacent call sites that perform the same operation/state transition/shared-helper path, and fixes plus regression-tests every confirmed sibling before returning. The scan stops at evidence — no speculative search-and-replace or unrelated refactor — and complements rather than weakens the existing cross-round cluster gate.
Fixed
Make PR tracker links survive the deterministic tracker rewrite. The
lifecycle reconcile facade now accepts the explicit PR URL for makePr and
projects the provider-native non-closing link in the same claim and receipt:
GitHub PR-body reference, deduplicated GitLab note, Jira remote-link upsert
with comment fallback, or Linear rich URL attachment. The reached-path
candidate utility also reports relative and out-of-repository --output
paths without failing after a successful write.
Worktree Kit no longer exposes nested worktrees to git add -A as broken
gitlinks.create initializes a self-contained, non-clobbering .worktrees/.gitignore (* plus !.gitignore) before adding the worktree,
preserving an existing custom ignore file and leaving the repository root .gitignore untouched. Thanks @sn-furali for reporting #266.
Backlog-mode tracker operations are executable after the tracker prose teardown.flowctl tracker wire relation-list now returns normalized directed dependency rows for Linear, GitHub, GitLab, and Jira, including GitHub's explicit hierarchy degradation and GitLab block/link provenance; capped pagination fails closed instead of exposing a partial graph. flowctl tracker wire question computes a stable question id from semantic identity fields, reads comments before writing, and idempotently parks tracker-only questions without requiring a Flow spec.
Tracker status recovery and review-attempt finalization. A native-open GitHub or GitLab issue now wins over a stale terminal status:* label left by a manual reopen. GitHub status writes make one bounded cleanup pass when separate label operations leave an ambiguous namespace; persistent ambiguity remains retryable without advancing durable sync state, and a later invocation re-enters the ordinary policy and merge-evidence gates before replaying the idempotent label repair. GitLab readiness validation drains every bounded label-search page before declaring tracker.readyState stale. Host and RepoPrompt review workflows now stop on attempt-recorder or completion-status write failures; the same recorder-exit guard covers Plan Review and Implementation Review sibling paths.
Tracker lifecycle and relation edge cases found during PR review. Jira relation projection now resolves tracker.perTracker.blocksLinkType (or discovers a blocks-semantics type) once and uses it for both dedup and creation; sites with no matching type queue instead of forcing stock Blocks. Jira create checks createmeta and omits Description only when the selected create screen positively excludes it, seeds both base halves from the actual empty write so the local body remains pending, and carries the structured degradation through facade receipts. Create and update readbacks must still match the provider's mutation acknowledgement before they can become a paired ancestor, preventing a concurrent remote edit from being recorded as synchronized. persist-external refuses a concurrent durable relink even when the display identifier is unchanged and now holds its spec claim through receipt creation and idempotent retry. Create and create-first release owned claims after unexpected adapter exceptions instead of wedging retries. Pull holds its facade identity claim through aggregate receipt creation, and sync set-tracker-id promotes identifier-only links to linked when a durable ID is installed. Converged retries now recreate missing event receipts across status, sync-body, and relate without repeating provider mutations or advancing lastSyncedAt. Facade push now accepts the exact local flow body and the agent-rendered tracker body separately, preserving a comparable mergeBaseFlow while writing tracker-form content. Every legacy sync-state setter now shares the writer lock and refuses live deterministic-operation claims, preventing stale whole-sidecar writes from erasing a committed transaction. GitHub status reasons now pair with their normalized slots: not_planned only with cancelled, completed/duplicate only with done; GitHub/GitLab active-status writes preserve the canonical hyphenated labels. Source-repository PR evidence no longer inherits tracker-specific TLS policy. Linear attachment-create failures retain evidence for the already-landed asset upload. sync clear shares the config writer lock and refuses every live spec operation claim, matching relink safety. Merge evidence probes the current code checkout rather than an out-of-tree GitHub issue destination. Sync-body rejects multiple or unbalanced flow:deps regions before pull/base-seeding or push rewriting. Canonical Jira direction docs now match the live-measured wire shape: blocker B is inwardIssue, blocked A is outwardIssue.
Repeatable tracker comments keep distinct lifecycle evidence. Every
synthesized facade comment now requires a stable, caller-owned evidence=<token> first line; missing or placeholder evidence fails before
provider I/O instead of collapsing later task/review/QA occurrences onto one
shared marker. GitLab relation reads also preserve a native is_blocked_by row when the same edge appears in Flow's body block, rather
than relabeling the native link as a degraded relates_to fallback.
--validate silently stopped reading validate-pass.md (regression from 3.4.x). The fn-112 prompt-to-template extraction deleted the VALIDATOR_TEMPLATE_REL constant but left its use site in load_validator_template(). The lookup raised NameError straight into a bare except Exception: pass, so the repo-root branch never resolved and copy-mode installs fell through to the embedded condensed fallback. Review at the time caught the sibling VALIDATOR_TEMPLATE_FALLBACK deletion and restored it; this one went unnoticed. The constant is restored, so copy-mode installs read the full on-disk prompt again, exactly as they did before the extraction. Plugin-mode installs were never affected. No prompt text changed.
Two further undefined names: Iterator used in a string annotation but never imported, and a test base class expression that always fell through to unittest.TestCase.
Added
Ruff gate in CI (ruff.toml, pinned ruff==0.16.0). Correctness-only ruleset - pyflakes, bugbear, pylint errors, a few security and bug-pattern rules. Ruff 0.16 enables 413 rules by default where 0.15 enabled 59; the pin is deliberate, since an unpinned ruff turns that into an unannounced CI break. Style rules are out of scope on purpose, and ruff.toml records why each excluded rule was excluded. The install copy under .flow/, the generated Codex mirror, and the test fixtures are excluded so --fix can never write into them. CI path filters cover every path the gate lints.
test_prompt_text_pinned.py - SHA-256 tripwire over every embedded prompt constant and on-disk prompt template. Lint, format, and refactor passes must not alter prompt text as a side effect; if one does, this fails loudly instead of hiding in a large diff. Deliberate prompt edits update the hash in the same commit.