Repository navigation
feat: add Astra choice and pick list ask blocks - #731
Conversation
There was a problem hiding this comment.
Important
Choice-answer preprocessing can suppress the quota-independent crisis support response. This safety regression should be fixed before merging.
Reviewed changes across all 45 files, including the answer lifecycle, bulk approval path, and compatibility with the sibling client contracts.
- Interactive questions: Adds negotiated, chat-only
choiceandpickListblocks, argument validation, tool-round termination, and feature-flag controls. - One-shot persistence: Adds owner-scoped storage, expiry, invalidation, atomic claims, migration, and account cleanup.
- Answer processing: Adds multipart answers and pre-stream HTTP errors; choices consume one daily message while pick lists create approval previews without model calls or writes, including in shadow mode.
- Verification: The solution builds with zero errors and all 9,653 existing tests pass. A temporary regression test reproduced the crisis-answer failure described inline; it was removed afterward, leaving both worktrees clean.
gpt-6.1-sol | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes in 0265c574 since the prior Pullfrog review at b414370d, with the full PR diff reread for context. The resolved finding is addressed, and no new blocking issues remain.
- Restored quota-independent crisis replies: Routed validated crisis choice answers to the existing static support response before quota checks, consumption, or model calls, while preserving ownership validation and one-shot claims.
- Preserved feature-flag behavior: Shared the crisis enablement predicate with ordinary chat and retained normal quota/model handling when crisis support is disabled.
- Verified regressions: Confirmed English and Portuguese crisis-answer coverage, invalid-answer rejection, concurrent claims, and ordinary choice behavior. The solution build completed with zero errors, and all 9,662 tests passed.
gpt-6.1-sol | 𝕏
|
The squash of orbit-api#731 replaced the commits this branch was stacked on. Five add/add conflicts take the merged #731 version (this branch did not change them beyond its older #731 base); the model snapshot keeps this branch's Notion entities on top of it. The result equals the tree of combined check a2 (base c8877ee with #731, #732 and #730 merged), which passed build, the openapi freshness check and all four test projects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>




Closes thomasluizon/orbit-tickets#1480.
Astra can issue
choiceandpickListparts to chat clients that declare those kinds. Answers are validated and claimed once before any model call. Choice answers consume one daily message. Pick list answers bypass the model and daily allowance, and return one bulk approval preview containing the selected stored arguments.The implementation lands in:
AskTool, the chat handler partials, validators, and block contracts: both forms, per-item bulk validation, capability negotiation, prompt guidance, the kill switch, stopping afterask, and both PostHog events.IssuedAstraBlock, its store,OrbitDbContext, the generated migration and designer, and account reset: ownership, 24-hour expiry, invalidation by later turns, atomic claims, and cascade deletion.AstraBlockAnswerServiceand the existing operation executor/policy evaluator: stored selections use the same bulk preview builder. Preview-only requests also require a preview in shadow mode, so the selection cannot execute a write.ChatController, rate limiting, service registration, the agent catalog, and generatedopenapi.json: optional multipartblockAnsweron both routes, answer throttling, HTTP rejection statuses before streaming, and exclusion ofaskfrom API key and MCP operations.Deploy the API and its migration before the clients for thomasluizon/orbit-tickets#1483 and thomasluizon/orbit-tickets#1484.
Assumptions
{habit_id, date}items inrevised_items; dynamic filters were rejected because each selected id must identify one stored item.IUserDateService; resolving them on the answer turn was rejected so the stored proposal remains stable.askis explicitly chat-only and omitted from the public agent catalog; adding an externally executable agent operation was rejected.Extended the existing ask test suites instead of creating a separate test project.
Test evidence
dotnet build Orbit.slnx: exit 0, zero errors; regenerated OpenAPI is committed.dotnet test tests/Orbit.Domain.Tests --no-build --no-restore: exit 0, 672 passed.dotnet test tests/Orbit.Application.Tests --no-build --no-restore: exit 0, 5,600 passed.dotnet test tests/Orbit.Infrastructure.Tests --no-build --no-restore: exit 0, 3,349 passed.dotnet test --no-build --no-restore: exit 0 across all four test projects, including 32 analyzer tests (9,653 total).The stopped-round token counter needed a stronger test:
Ask_EmitsNegotiatedPartAndStopsBeforeLaterToolspassed with the defect present:dotnet test tests/Orbit.Application.Tests --no-build --no-restore --filter FullyQualifiedName~Ask_EmitsNegotiatedPartAndStopsBeforeLaterToolsreturned exit 0, one passed.dotnet test tests/Orbit.Application.Tests --no-restore --filter FullyQualifiedName~Ask_EmitsNegotiatedPartAndStopsBeforeLaterToolsreturned exit 1, one failed and one passed: the handler incorrectly rejected the valid reply after counting the same model response twice.dotnet test tests/Orbit.Application.Tests --no-restore --filter 'FullyQualifiedName~ValidationCopyTests|FullyQualifiedName~ErrorCopyTests|FullyQualifiedName~Ask_EmitsNegotiatedPartAndStopsBeforeLaterTools'returned exit 0, 1,235 passed, including both strengthened cases. The full application suite above also passes.b414370d:dotnet test tests/Orbit.Application.Tests --filter FullyQualifiedName~Handle_CrisisDisclosureBeyondQuota_ReturnsStaticResourcesWithoutCallingAipassed, exit 0.dotnet test tests/Orbit.Application.Tests --filter FullyQualifiedName~ChoiceAnswer_CrisisDisclosure_ReturnsStaticResourcesWithoutQuotaOrModeldotnet build Orbit.slnx: exit 0, zero errors. OpenAPI regenerated unchanged.dotnet test tests/Orbit.Domain.Tests: 672 passed, exit 0.dotnet test tests/Orbit.Application.Tests: 5,609 passed, exit 0.dotnet test tests/Orbit.Infrastructure.Tests: 3,349 passed, exit 0.External interface evidence
IssuedAstraBlockStoreTestsexecutes the installed EF Core SQLite provider to verify affected-row claim results, owner scoping, expiry, invalidation, reset, and cascade deletion.AstraPickListPreviewTestsalso verifies transaction rollback after a quota race against real SQL.The migration was generated from
OrbitDbContextFactorywithdotnet ef migrations add AddIssuedAstraBlocks --project ../Orbit.Infrastructure --startup-project .fromsrc/Orbit.Api; the tool reported a successful build and generation.Eval scenarios for #26
choicepart, such as a short walk with Morning, Lunch, and Evening options.pickListwith actioncreate_habits.askblock.Manual steps
After integration, deploy through GitHub Actions → Release API (
release.yml). Verify a validated crisis choice answer at exhausted quota returns static resources without increasing usage. No new configuration, migrations, or backfills.