Skip to content

github-devloop implementation for #47 - #48

Merged
chronoai-fkst[bot] merged 3 commits into
qa-tools-fkst-stagingfrom
devloop/issue/ChronoAIProject/talos/47/ready-github-devloop-issue-ChronoAIProject-talos-47-intake-1700233896-2620819180
Sep 11, 2026
Merged

chronoai-fkst[bot] merged 3 commits into
qa-tools-fkst-stagingfrom
devloop/issue/ChronoAIProject/talos/47/ready-github-devloop-issue-ChronoAIProject-talos-47-intake-1700233896-2620819180

Conversation

@chronoai-fkst

@chronoai-fkst chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

github-devloop implementation PR for issue #47

…nd Task input after post-CAS write failure
@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR child open

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR is ready for review

@chronoai-fkst chronoai-fkst Bot mentioned this pull request Sep 11, 2026
@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR is ready for review

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR review decision: reject
Verdicts: teleology=approve parsimony=approve fidelity=approve natural-ownership=reject proportional-containment=approve
Blocking gap: missing current-claim consumption fence

teleology:
The diff cleanly implements the established transactional-outbox/durable-intent solution to the post-CAS dual-write gap. provideInput() atomically binds pendingInputIntent to the active claim before sidecar materialization and reuses that immutable identity only for the exact reconciliation case (control-plane/src/services/task-service.ts:221). Mongo uses insert-only $setOnInsert materialization and a single conditional consume, while memory storage provides equivalent no-resurrection semantics (control-plane/src/storage/mongo-repository.ts:556, control-plane/src/storage/memory-repository.ts:413). Internal authority is explicitly removed from public Task projection (control-plane/src/services/task-service.ts:1072), and the required HTTP and dual-repository tests verify the specified walking skeleton. No evidenced BEAUTY-GATE smell blocks advancement. The guarantee should continue to be described narrowly as one-time server-side consumption, not unconditional exactly-once worker processing after a lost poll response.

parsimony:
ESSENCE: This is a dual-write failure: the authoritative Task transition can succeed while its worker-readable projection fails. Established transactional-outbox/durable-intent practice governs—persist the obligation atomically with aggregate state, then project idempotently and consume with generation fencing. IDEAL: one Task-owned immutable intent, one insert-once sidecar keyed by operationId, one conditional consume, and best-effort authority cleanup. SIX-SMELL: The diff follows that minimum. No magic number is unjustified: the version literal and positive generation are protocol requirements (control-plane/src/domain/types.ts:59, control-plane/src/services/task-service.ts:230). No proxy-over-truth: the Task CAS persists the exact claim-bound intent before materialization (control-plane/src/services/task-service.ts:238), while both repositories compare complete records and prevent resurrection (control-plane/src/storage/memory-repository.ts:413, control-plane/src/storage/mongo-repository.ts:556). The sole reconciliation branch matches the narrowly authorized status, active claim, lease, generation, and exact payload rather than accumulating symptom cases (control-plane/src/services/task-service.ts:866). Narrative is backed by an HTTP failure/retry/poll test (control-plane/src/http/server.test.ts:487) and a dual-repository contract (control-plane/src/storage/repository-contract.test.ts:373). Inevitability is supplied by the persisted intent, not timing or background machinery; cleanup uses the existing active-claim CAS and cannot resurrect consumed input (control-plane/src/services/task-service.ts:273). Purpose remains bounded, and internal authority is removed from public projection (control-plane/src/services/task-service.ts:1072).

fidelity:
The diff faithfully applies established transactional-outbox/durable-intent and idempotent-consumer practice. The winning active-claim CAS atomically records one opaque, generation-bound pendingInputIntent before sidecar materialization (control-plane/src/services/task-service.ts:230, control-plane/src/services/task-service.ts:238, control-plane/src/services/task-service.ts:254); exact retries reuse that persisted authority rather than inventing new identity (control-plane/src/services/task-service.ts:223, control-plane/src/services/task-service.ts:866). Memory and Mongo enforce insert-once identity, reject conflicting payloads, consume conditionally once, and cannot reset consumption (control-plane/src/storage/memory-repository.ts:413, control-plane/src/storage/memory-repository.ts:422, control-plane/src/storage/mongo-repository.ts:556, control-plane/src/storage/mongo-repository.ts:567). Cleanup uses the active-claim CAS seam after consumption (control-plane/src/services/task-service.ts:278), internal authority is excluded from public projection (control-plane/src/services/task-service.ts:1072), losing CAS attempts are verified to make zero materialization calls (control-plane/src/services/task-service.test.ts:498), and the deterministic HTTP test verifies the required 500→200 reconciliation and one-time worker polling behavior (control-plane/src/http/server.test.ts:556, control-plane/src/http/server.test.ts:579, control-plane/src/http/server.test.ts:598). No evidenced BEAUTY-GATE smell blocks advancement.

natural-ownership:
Reject for evidenced proxy-over-truth: the changed getWorkerInput() treats task.pendingInputIntent as sufficient authority and passes it directly to consumePendingInput() without verifying that its taskId, claimId, and claimGeneration equal the Task’s current active claim (control-plane/src/services/task-service.ts:276, control-plane/src/services/task-service.ts:278). Normal expiry requeues by spreading the Task and retaining that intent (control-plane/src/services/task-service.ts:400), and the next claim again spreads it while assigning a new claim generation (control-plane/src/services/task-service.ts:138). Both changed repositories then return a record matching the passed stale intent, not the current claim (control-plane/src/storage/memory-repository.ts:422; control-plane/src/storage/mongo-repository.ts:567). Consequently, a generation-N input can be delivered to the generation-N+1 worker, violating the explicit requirement that another claim or generation’s record “must never be returned.” The contract test only supplies a deliberately changed argument (control-plane/src/storage/repository-contract.test.ts:394), so it does not verify the service’s ownership boundary. Add a current-Task/intent binding check before consumption, or remove the intent whenever claim ownership changes, plus a focused regression test; this narrow fence does not require implementing the excluded full expiry matrix.

proportional-containment:
The change follows the established transactional-outbox/durable-intent pattern at the natural owner layer rather than hoisting recovery into a universal framework. The winning Task CAS persists one immutable, generation-bound pendingInputIntent before sidecar materialization (control-plane/src/services/task-service.ts:230); exact retries reuse that intent without another transition (control-plane/src/services/task-service.ts:223, control-plane/src/services/task-service.ts:866); both repositories enforce operation-level idempotency, integrity checking, atomic conditional consumption, and non-resurrection (control-plane/src/storage/memory-repository.ts:413, control-plane/src/storage/mongo-repository.ts:556); and successful polling clears the intent through replaceTaskForActiveClaim without making cleanup responsible for delivery correctness (control-plane/src/services/task-service.ts:273). Public projection explicitly suppresses the new authority (control-plane/src/services/task-service.ts:1072), while the deterministic HTTP and repository-contract tests cover the required end-to-end failure and recovery path (control-plane/src/http/server.test.ts:481, control-plane/src/storage/repository-contract.test.ts:373). No evidenced BEAUTY-GATE smell or stated-requirement gap remains.

⟦AI:FKST⟧

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop merge gate failed: missing current-claim consumption fence
Reproduce locally with scripts/run.sh test from the repository root.

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop fix pushed for re-review

Previous reviewed head: 7a0c309
New head: 74be4f8

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR is ready for review

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR review decision: approve
Verdicts: teleology=approve parsimony=approve fidelity=approve natural-ownership=approve proportional-containment=approve

teleology:
ESSENCE: This is a dual-write recovery problem governed by transactional-outbox/durable-intent, idempotent-consumer, and fencing-token practice: persist the delivery obligation with authoritative state, then materialize and consume it only for its owning generation. IDEAL: one immutable Task-owned intent, insert-once projection, generation-fenced single consumption, and best-effort cleanup. SIX-SMELL: The named gap is closed. The fix compares pendingInputIntent.taskId, claimId, and claimGeneration with the currently authenticated worker Task before consumption (control-plane/src/services/task-service.ts:273), and the focused regression advances ownership while retaining the old intent, verifies the new worker receives nothing, then proves the sidecar itself remained unconsumed (control-plane/src/services/task-service.test.ts:648). No magic numbers are introduced; no proxy-over-truth remains within the settled walking-skeleton boundary; the check is an ownership invariant rather than a symptom branch; narrative-over-verification is avoided by the regression and existing end-to-end recovery proof (control-plane/src/http/server.test.ts:579); missing-inevitability is answered by durable intent plus insert-once, conditional consumption (control-plane/src/storage/mongo-repository.ts:553); and skipped-purpose is absent because the form directly serves generation-bound one-time delivery without broadening into the excluded expiry matrix.

parsimony:
The named gap is closed. After authenticating the polling worker against the current active lease, getWorkerInput() now refuses consumption unless the persisted intent’s taskId, claimId, and claimGeneration equal the current Task authority (control-plane/src/services/task-service.ts:273, control-plane/src/services/task-service.ts:277; worker preconditions at control-plane/src/services/task-service.ts:749). This is the parsimonious fencing-token rule required by transactional-outbox/idempotent-consumer practice, not a symptom branch. The added regression advances the claim while deliberately retaining the old intent, proves the new worker receives undefined, and then proves the old sidecar remained unconsumed (control-plane/src/services/task-service.test.ts:648). Across the full BEAUTY-GATE rubric: no magic constant was added; proxy-over-truth is removed; the single invariant guard avoids symptom branching; the test verifies rather than narrates; stale non-delivery follows inevitably from exact authority equality; and no unrelated purpose or machinery was introduced.

fidelity:
The named gap is closed. getWorkerInput() now compares the persisted intent’s taskId, claimId, and claimGeneration with the currently authenticated Task before calling consumePendingInput() (control-plane/src/services/task-service.ts:274, control-plane/src/services/task-service.ts:276). The added regression deliberately retains the generation-N intent through a generation-N+1 claim, proves the new worker receives undefined, and separately proves the old sidecar remained unconsumed, so the test measures the ownership boundary rather than merely an empty store (control-plane/src/services/task-service.test.ts:648, control-plane/src/services/task-service.test.ts:659, control-plane/src/services/task-service.test.ts:661). Repository consumption still matches the complete immutable intent and marks it consumed once (control-plane/src/storage/memory-repository.ts:422, control-plane/src/storage/mongo-repository.ts:567). No fix regression or evidenced BEAUTY-GATE smell remains within the issue’s stated walking-skeleton bounds.

natural-ownership:
ESSENCE: The governing practice is transactional outbox/durable intent combined with fencing tokens and idempotent consumption: persist the obligation with the Task aggregate, and let the layer possessing current claim authority decide whether its projection may be consumed. IDEAL: TaskService authenticates the polling worker against the current Task claim, compares the persisted intent’s full claim binding, then asks storage to atomically consume the matching insert-once sidecar; storage owns record identity and one-time mutation, while the service owns claim validity. SIX-SMELL: The named gap is closed. The fix adds the missing current-Task binding check for taskId, claimId, and claimGeneration before consumption (control-plane/src/services/task-service.ts:273), adjacent to getWorkerTask(), which already establishes current worker, token, committed-claim, status, and lease authority (control-plane/src/services/task-service.ts:749). This is not proxy-over-truth: current Task authority, rather than the retained sidecar alone, gates delivery. It is not a symptom branch: one general claim-binding invariant covers requeue and reclaim. No magic behavior constant is introduced. Narrative is verified by a deterministic generation-N-to-N+1 regression showing the new worker receives undefined while the old sidecar still exists (control-plane/src/services/task-service.test.ts:648). Inevitability comes from immutable generation comparison, not timing. Purpose remains narrow: repository methods continue owning atomic one-time consumption, while TaskService owns eligibility, avoiding a misplaced cross-aggregate invariant in storage (control-plane/src/storage/mongo-repository.ts:599). No new in-scope regression is evidenced.

proportional-containment:
ESSENCE: This is a dual-write recovery problem governed by the transactional-outbox/durable-intent pattern: persist the obligation with aggregate authority, project idempotently, and fence consumption to the owning generation. IDEAL: Keep authority on the Task, permit consumption only when the intent still matches its active claim, atomically consume the sidecar once, and perform best-effort cleanup. SIX-SMELL: The named gap is closed without over-hoisting. The fix places the current-claim fence in TaskService.getWorkerInput(), the natural owner already authenticating the worker, and compares taskId, claimId, and claimGeneration before repository consumption (control-plane/src/services/task-service.ts:273, control-plane/src/services/task-service.ts:277). The focused regression retains a generation-N intent through generation advancement and proves generation N+1 receives nothing while the record itself remains unconsumed (control-plane/src/services/task-service.test.ts:648). This is not magic numbers—the generation is persisted protocol authority; not proxy-over-truth—the current Task claim is consulted; not a symptom branch—the check expresses the ownership invariant; not narrative-over-verification—the stale-generation test exercises it; not missing-inevitability—the repositories still provide conditional one-time consumption (control-plane/src/storage/memory-repository.ts:422, control-plane/src/storage/mongo-repository.ts:567); and not skipped-purpose—the intervention remains confined to generic Task-input polling for the active claim. No fix regression or stated-requirement gap is evidenced.

⟦AI:FKST⟧

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop merge gate failed: own-ci-red
Reproduce locally with scripts/run.sh test from the repository root.

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop timeout redrive attempt: fixing 3

⟦AI:FKST⟧

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop merge gate failed: own-ci-red
Reproduce locally with scripts/run.sh test from the repository root.

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop fix pushed for re-review

Previous reviewed head: 74be4f8
New head: 58ae387

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR is ready for review

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop PR review decision: approve
Verdicts: teleology=approve parsimony=approve fidelity=approve natural-ownership=approve proportional-containment=approve

teleology:
The established transactional-outbox/durable-intent and idempotent-consumer pattern applies, and the current head follows it cleanly. The winning active-claim CAS persists the immutable pendingInputIntent before fallible materialization (control-plane/src/services/task-service.ts:230); exact reconciliation reuses that authority (control-plane/src/services/task-service.ts:223); both repositories enforce complete-record identity, atomic one-time consumption, and non-resurrection (control-plane/src/storage/memory-repository.ts:413; control-plane/src/storage/mongo-repository.ts:558); and internal authority is excluded from public projection (control-plane/src/services/task-service.ts:1077). Most importantly, the previous proxy-over-truth rejection is resolved: consumption now requires the persisted intent to match the current Task’s taskId, claimId, and claimGeneration, with a focused generation-change regression test (control-plane/src/services/task-service.ts:276; control-plane/src/services/task-service.test.ts:648). No evidenced BEAUTY-GATE smell or stated-requirement gap remains.

parsimony:
ESSENCE: This is the established transactional-outbox/durable-intent problem: an authoritative Task CAS and a fallible worker-readable projection form a dual write, so the obligation must be persisted with Task truth, projected idempotently, and consumed once under a fencing token. IDEAL: one immutable claim-bound intent, one insert-once sidecar keyed by operationId, one atomic conditional consume, and best-effort Task cleanup. SIX-SMELL: The current head remains clean and closes the previously settled gap. No magic numbers: the schema version and positive claimGeneration are explicit protocol authority (control-plane/src/domain/types.ts:59). No proxy-over-truth: the winning CAS stores the intent before materialization (control-plane/src/services/task-service.ts:238), and polling compares it with current Task claim authority before consumption (control-plane/src/services/task-service.ts:273). No symptom branches: that single equality fence covers stale ownership generally. No narrative-over-verification: deterministic tests prove 500→identical-retry→one-time polling, stale-generation refusal, idempotency, and non-resurrection (control-plane/src/http/server.test.ts:556; control-plane/src/services/task-service.test.ts:648; control-plane/src/storage/repository-contract.test.ts:373). No missing-inevitability: Mongo uses $setOnInsert and one conditional findOneAndUpdate (control-plane/src/storage/mongo-repository.ts:558; control-plane/src/storage/mongo-repository.ts:569). No skipped-purpose: public projection hides the authority (control-plane/src/services/task-service.ts:1096). Since the approved prior head, the only change replaces an unsafe cast with the minimal typed PendingInputDocument collection (control-plane/src/storage/mongo-repository.ts:65; control-plane/src/storage/mongo-repository.ts:76), adding no behavior or machinery.

fidelity:
Established transactional-outbox, idempotent-consumer, and fencing-token practice remains faithfully implemented. The only change since the settled approved head replaces an unchecked PendingInputRecord assertion with an accurate PendingInputDocument collection schema (control-plane/src/storage/mongo-repository.ts:65, control-plane/src/storage/mongo-repository.ts:76, control-plane/src/storage/mongo-repository.ts:564). This moves the implementation from proxy toward source truth without altering runtime control flow. The schema matches the record written through $setOnInsert (control-plane/src/storage/mongo-repository.ts:558), and the existing repository contract verifies idempotency, non-resurrection, integrity failure, and generation fencing (control-plane/src/storage/repository-contract.test.ts:370). No evidenced BEAUTY-GATE smell or new stated-requirement gap remains.

natural-ownership:
ESSENCE: This is the established transactional-outbox/durable-intent problem combined with fencing-token and idempotent-consumer practice: an aggregate transition creates a delivery obligation that must survive a failed projection write, while only the current claim may consume it. IDEAL: The Task aggregate atomically owns one immutable, generation-bound intent; TaskService, which possesses current claim authority, gates eligibility; repositories own insert-once projection and atomic one-time consumption; cleanup is best-effort and cannot resurrect consumption. SIX-SMELL: The proposal matches that ownership split. Magic numbers: the schema version and positive generation are explicit protocol invariants, not unexplained constants (control-plane/src/domain/types.ts:59, control-plane/src/services/task-service.ts:230). Proxy-over-truth: the winning CAS persists the intent before materialization, and polling compares it with the current Task’s taskId, claimId, and claimGeneration before storage consumption (control-plane/src/services/task-service.ts:238, control-plane/src/services/task-service.ts:273). Symptom branches: one general binding predicate covers stale claims rather than enumerating expiry/requeue cases (control-plane/src/services/task-service.ts:277). Narrative-over-verification: deterministic HTTP recovery, repository no-resurrection, and generation-advance regressions exercise the claimed behavior (control-plane/src/http/server.test.ts:556, control-plane/src/storage/repository-contract.test.ts:373, control-plane/src/services/task-service.test.ts:648). Missing-inevitability: both stores preserve immutable identity and consume conditionally once (control-plane/src/storage/memory-repository.ts:413, control-plane/src/storage/mongo-repository.ts:558). Skipped-purpose: internal authority is excluded from public projection (control-plane/src/services/task-service.ts:1077). The change since the previously appr

proportional-containment:
ESSENCE: This is a dual-write crash-window problem governed by transactional outbox/durable intent plus generation fencing. IDEAL: keep intent on the authoritative Task, let TaskService enforce current-claim eligibility, and let repositories atomically materialize and consume once. SIX-SMELL: the implementation is bounded and clean: the winning Task CAS stores pendingInputIntent before materialization (control-plane/src/services/task-service.ts:238, control-plane/src/services/task-service.ts:254); reconciliation requires the exact active claim and exact payload (control-plane/src/services/task-service.ts:871); worker polling verifies the current taskId, claimId, and claimGeneration (control-plane/src/services/task-service.ts:273); repositories conditionally consume once (control-plane/src/storage/memory-repository.ts:422, control-plane/src/storage/mongo-repository.ts:569); and public projection hides the intent (control-plane/src/services/task-service.ts:1096). The latest head only narrows Mongo typing with PendingInputDocument and removes an unsafe cast (control-plane/src/storage/mongo-repository.ts:65, control-plane/src/storage/mongo-repository.ts:76, control-plane/src/storage/mongo-repository.ts:564). No evidenced beauty-gate smell or stated-requirement gap remains.

⟦AI:FKST⟧

@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop is merging PR #48

@chronoai-fkst
chronoai-fkst Bot merged commit 5317a52 into qa-tools-fkst-staging Sep 11, 2026
4 checks passed
@chronoai-fkst

chronoai-fkst Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

github-devloop merged PR #48

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.

0 participants