Add helpers for detecting open-ended activations (#26) - #65
Merged
Merged
Conversation
activation_is_open() and activation_end_time() read an activation saved without end_time back. Reading endTime directly on an open record does not fail but yields a zero Timestamp (1970), and carrying that forward as end_time= in a re-save gets the save rejected. activation_end_time() returns None instead, so it is also the correct carry-forward. Module-level functions rather than a result property, so they cover get, query, iterate, and get_active_configurations() alike. Presence is the only test: an endTime present with value 0 is closed, not open. The cookbook adopts them, fixes the recipe that printed 0 for an open interval, completes the getActiveConfigurations match rule, and adds a recipe for finding the open activation without its id. Closes #26 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PgJ3cRwMrh8UzxzZwraLCT
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
No unresolved review comments remain, and all approval-readiness assessments approve the changes.
Review effort: Lite
Findings: None
What changed in this PR
Adds public helpers for detecting open-ended activations and safely retrieving optional end times.
Changes:
- Adds and exports
activation_is_open()andactivation_end_time(). - Adds unit and integration coverage for presence and epoch-zero behavior.
- Updates documentation, release notes, guidance, and snippet checks.
| File | Summary |
|---|---|
tests/unit/test_machine_config_activation_client.py |
Tests helper behavior and edge cases. |
tests/integration/test_machine_config_client_integration.py |
Adds round-trip assertions. |
src/dp_python_lib/client/machine_config_client.py |
Implements activation helpers. |
src/dp_python_lib/client/__init__.py |
Exports the helpers. |
doc/release-notes/NEXT.md |
Documents the user-visible change. |
doc/cookbook/machine-configuration.md |
Documents safe activation handling. |
CLAUDE.md |
Updates project guidance. |
.dev/tools/check-cookbook-snippets.py |
Makes helpers available to snippet checks. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Cookbook: the "no activation id" recipe now queries by the incoming configuration's category plus CA.timestamp(changeover), instead of paging a configuration's whole history by name and filtering to open records. That matches the server's overlap check, which is by category as well as name, and also catches a bounded activation whose scheduled end is after the changeover. - CLAUDE.md: carry-forward snippet narrows activation_end_time() with `is not None`, so it stays clean once typed stubs land. - NEXT.md: correct the description of the rejected re-save. - Rewrap the get_active_configurations() paragraph; note the recipe revision in plan/tickets/26/plan.md; fix a test docstring. Refs #26 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PgJ3cRwMrh8UzxzZwraLCT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the plan merged in #64 (
plan/tickets/26/plan.md).Helpers —
activation_is_open()andactivation_end_time()inmachine_config_client, exported fromdp_python_lib.client. Module-level so they cover get, query, iterate, andget_active_configurations()alike (D1). Reading.endTimedirectly on an open activation silently yields a zeroTimestamp(1970);activation_end_time()returnsNoneinstead, which also makesend_time=activation_end_time(current)the correct carry-forward in a full-replace re-save (D3). Presence is the only test: anendTimepresent with value 0 is closed (D5).Tests — new
TestActivationOpenEndedHelpers(open, bounded, epoch-zero, reading.endTimedoes not set presence, re-save round trip, open record carried forward stays open, filtering a mixed query page). The integration open-ended round trip asserts the helpers beside the existing rawHasFieldchecks, which remain the wire verification.Cookbook (
doc/cookbook/machine-configuration.md)end_time.CA.timestamp(changeover), the same terms as the server's overlap check (category as well as name). Deliberately not narrowed to open records, since a bounded activation ending after the changeover blocks the next save just as an open one does. Handles zero / one / more-than-one results. (Revised in review; the plan carries a dated note.)get_active_configurations()match rule now includes an absentendTime.0for an open interval.Also — CLAUDE.md,
doc/release-notes/NEXT.mdsection, cookbook checker preamble.Verification —
pytest tests/unit/(746 passed),ruff check .,ruff format --check .,mypy src/, cookbook snippet checker, release-notes checker all clean.tests/integration/test_machine_config_client_integration.pyagainst a live stack: 3 passed, including the open-ended round trip with the new helper assertions. The revised recipe was also exercised against the live stack with a throwaway script: an empty result with nothing in effect, an open activation of a different configuration found through the category, the next save rejected while it stays open, a bounded activation ending after the changeover still found, and the next save succeeding once it is closed.Closes #26
🤖 Generated with Claude Code
https://claude.ai/code/session_01PgJ3cRwMrh8UzxzZwraLCT