targetprocess-py 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- targetprocess_py-0.1.0/.coderabbit.yaml +147 -0
- targetprocess_py-0.1.0/.commitlintrc.json +35 -0
- targetprocess_py-0.1.0/.env.example +25 -0
- targetprocess_py-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +80 -0
- targetprocess_py-0.1.0/.github/ISSUE_TEMPLATE/config.yml +9 -0
- targetprocess_py-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +66 -0
- targetprocess_py-0.1.0/.github/dependabot.yml +107 -0
- targetprocess_py-0.1.0/.github/labels.yml +56 -0
- targetprocess_py-0.1.0/.github/pull_request_template.md +62 -0
- targetprocess_py-0.1.0/.github/workflows/ci.yml +106 -0
- targetprocess_py-0.1.0/.github/workflows/commit-message.yml +30 -0
- targetprocess_py-0.1.0/.github/workflows/release.yml +137 -0
- targetprocess_py-0.1.0/.gitignore +61 -0
- targetprocess_py-0.1.0/.jscpd.json +15 -0
- targetprocess_py-0.1.0/.pre-commit-config.yaml +97 -0
- targetprocess_py-0.1.0/.python-version +1 -0
- targetprocess_py-0.1.0/.tool-versions +1 -0
- targetprocess_py-0.1.0/CHANGELOG.md +101 -0
- targetprocess_py-0.1.0/CODEOWNERS +14 -0
- targetprocess_py-0.1.0/CODE_OF_CONDUCT.md +132 -0
- targetprocess_py-0.1.0/CONTRIBUTING.md +233 -0
- targetprocess_py-0.1.0/LICENSE +21 -0
- targetprocess_py-0.1.0/PKG-INFO +476 -0
- targetprocess_py-0.1.0/README.md +437 -0
- targetprocess_py-0.1.0/SECURITY.md +55 -0
- targetprocess_py-0.1.0/SPEC.md +951 -0
- targetprocess_py-0.1.0/docs/USAGE.md +588 -0
- targetprocess_py-0.1.0/docs/testing.md +128 -0
- targetprocess_py-0.1.0/examples/README.md +62 -0
- targetprocess_py-0.1.0/examples/bulk_updates.py +132 -0
- targetprocess_py-0.1.0/examples/create_bug.py +117 -0
- targetprocess_py-0.1.0/examples/list_user_stories.py +68 -0
- targetprocess_py-0.1.0/examples/readonly_reporting.py +78 -0
- targetprocess_py-0.1.0/pyproject.toml +161 -0
- targetprocess_py-0.1.0/scripts/apply_labels.sh +86 -0
- targetprocess_py-0.1.0/scripts/check_commit_message.py +122 -0
- targetprocess_py-0.1.0/scripts/check_internal_refs.py +169 -0
- targetprocess_py-0.1.0/scripts/check_large_files.py +100 -0
- targetprocess_py-0.1.0/scripts/check_model_coverage.py +538 -0
- targetprocess_py-0.1.0/scripts/check_todos.py +107 -0
- targetprocess_py-0.1.0/scripts/live_smoke.py +303 -0
- targetprocess_py-0.1.0/src/targetprocess/__init__.py +231 -0
- targetprocess_py-0.1.0/src/targetprocess/_assignables.py +162 -0
- targetprocess_py-0.1.0/src/targetprocess/_base.py +318 -0
- targetprocess_py-0.1.0/src/targetprocess/_content.py +287 -0
- targetprocess_py-0.1.0/src/targetprocess/_dates.py +70 -0
- targetprocess_py-0.1.0/src/targetprocess/_entity_types.py +33 -0
- targetprocess_py-0.1.0/src/targetprocess/_generals.py +324 -0
- targetprocess_py-0.1.0/src/targetprocess/_joins.py +217 -0
- targetprocess_py-0.1.0/src/targetprocess/_lookups.py +477 -0
- targetprocess_py-0.1.0/src/targetprocess/_nested.py +223 -0
- targetprocess_py-0.1.0/src/targetprocess/_observability.py +368 -0
- targetprocess_py-0.1.0/src/targetprocess/client.py +430 -0
- targetprocess_py-0.1.0/src/targetprocess/exceptions.py +147 -0
- targetprocess_py-0.1.0/src/targetprocess/models.py +121 -0
- targetprocess_py-0.1.0/src/targetprocess/py.typed +1 -0
- targetprocess_py-0.1.0/src/targetprocess/request_handler.py +724 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/__init__.py +76 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/assignments.py +29 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/attachments.py +164 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/base.py +563 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/bugs.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/comments.py +23 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/custom_activities.py +56 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/custom_fields.py +27 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/custom_rules.py +28 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/entities.py +433 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/entity_states.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/entity_types.py +61 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/epics.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/features.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/iterations.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/priorities.py +85 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/processes.py +65 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/projects.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/relation_types.py +59 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/relations.py +34 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/releases.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/requests.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/role_efforts.py +21 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/roles.py +52 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/severities.py +53 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/tasks.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/team_assignments.py +21 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/team_iterations.py +24 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/teams.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/terms.py +28 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/test_cases.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/times.py +392 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/user_stories.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/users.py +20 -0
- targetprocess_py-0.1.0/src/targetprocess/resources/workflows.py +27 -0
- targetprocess_py-0.1.0/src/targetprocess/response_parser.py +113 -0
- targetprocess_py-0.1.0/src/targetprocess/transport.py +116 -0
- targetprocess_py-0.1.0/src/targetprocess/types.py +56 -0
- targetprocess_py-0.1.0/tests/__init__.py +1 -0
- targetprocess_py-0.1.0/tests/_support/__init__.py +1 -0
- targetprocess_py-0.1.0/tests/_support/request_handler.py +74 -0
- targetprocess_py-0.1.0/tests/conftest.py +123 -0
- targetprocess_py-0.1.0/tests/integration/__init__.py +1 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_entity_types_catalogue_parses.yaml +209 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_find_for_day_matches_a_real_entry.yaml +159 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_generic_entities_comment.yaml +88 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_get_single_with_include.yaml +176 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_list_user_stories_parses.yaml +154 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_pagination_crosses_page_boundary.yaml +999 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_priorities_scoped_to_an_entity_type.yaml +87 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readonly/test_severities_rank_the_bug_set.yaml +82 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite/test_bulk_create_and_update_tasks_under_a_story.yaml +807 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite/test_request_create_update_delete_round_trip.yaml +361 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite/test_user_story_create_update_delete_round_trip.yaml +359 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_assignment_create_and_delete.yaml +487 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_attachment_upload_list_download_and_delete.yaml +655 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_comment_create_update_delete_round_trip.yaml +497 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_relation_create_and_delete.yaml +660 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_role_effort_create_update_delete_round_trip.yaml +620 -0
- targetprocess_py-0.1.0/tests/integration/cassettes/test_live_readwrite_surfaces/test_team_assignment_create_and_delete.yaml +564 -0
- targetprocess_py-0.1.0/tests/integration/conftest.py +520 -0
- targetprocess_py-0.1.0/tests/integration/test_live_readonly.py +120 -0
- targetprocess_py-0.1.0/tests/integration/test_live_readwrite.py +279 -0
- targetprocess_py-0.1.0/tests/integration/test_live_readwrite_surfaces.py +482 -0
- targetprocess_py-0.1.0/tests/live_payloads.py +84 -0
- targetprocess_py-0.1.0/tests/test_assignment.py +38 -0
- targetprocess_py-0.1.0/tests/test_attachment.py +68 -0
- targetprocess_py-0.1.0/tests/test_bug.py +98 -0
- targetprocess_py-0.1.0/tests/test_cassette_guard.py +405 -0
- targetprocess_py-0.1.0/tests/test_cassette_sanitiser.py +533 -0
- targetprocess_py-0.1.0/tests/test_client.py +252 -0
- targetprocess_py-0.1.0/tests/test_comment.py +59 -0
- targetprocess_py-0.1.0/tests/test_commit_message.py +146 -0
- targetprocess_py-0.1.0/tests/test_custom_activity.py +44 -0
- targetprocess_py-0.1.0/tests/test_custom_field.py +50 -0
- targetprocess_py-0.1.0/tests/test_custom_field_value.py +50 -0
- targetprocess_py-0.1.0/tests/test_custom_rule.py +32 -0
- targetprocess_py-0.1.0/tests/test_entity_extras.py +262 -0
- targetprocess_py-0.1.0/tests/test_entity_ref.py +88 -0
- targetprocess_py-0.1.0/tests/test_entity_state.py +46 -0
- targetprocess_py-0.1.0/tests/test_entity_type.py +46 -0
- targetprocess_py-0.1.0/tests/test_epic.py +55 -0
- targetprocess_py-0.1.0/tests/test_exceptions.py +124 -0
- targetprocess_py-0.1.0/tests/test_feature.py +73 -0
- targetprocess_py-0.1.0/tests/test_integration_request_response.py +108 -0
- targetprocess_py-0.1.0/tests/test_internal_refs.py +190 -0
- targetprocess_py-0.1.0/tests/test_iteration.py +58 -0
- targetprocess_py-0.1.0/tests/test_model_field_coverage.py +578 -0
- targetprocess_py-0.1.0/tests/test_models.py +168 -0
- targetprocess_py-0.1.0/tests/test_observability.py +632 -0
- targetprocess_py-0.1.0/tests/test_priority.py +37 -0
- targetprocess_py-0.1.0/tests/test_process.py +32 -0
- targetprocess_py-0.1.0/tests/test_project.py +60 -0
- targetprocess_py-0.1.0/tests/test_relation.py +39 -0
- targetprocess_py-0.1.0/tests/test_relation_type.py +17 -0
- targetprocess_py-0.1.0/tests/test_release.py +56 -0
- targetprocess_py-0.1.0/tests/test_request.py +55 -0
- targetprocess_py-0.1.0/tests/test_request_handler.py +883 -0
- targetprocess_py-0.1.0/tests/test_request_handler_bulk.py +146 -0
- targetprocess_py-0.1.0/tests/test_resources/test_assignments.py +84 -0
- targetprocess_py-0.1.0/tests/test_resources/test_attachments.py +206 -0
- targetprocess_py-0.1.0/tests/test_resources/test_base_resource.py +533 -0
- targetprocess_py-0.1.0/tests/test_resources/test_bugs.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_comments.py +82 -0
- targetprocess_py-0.1.0/tests/test_resources/test_custom_activities.py +48 -0
- targetprocess_py-0.1.0/tests/test_resources/test_custom_fields.py +63 -0
- targetprocess_py-0.1.0/tests/test_resources/test_custom_rules.py +72 -0
- targetprocess_py-0.1.0/tests/test_resources/test_entities.py +596 -0
- targetprocess_py-0.1.0/tests/test_resources/test_entity_states.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_entity_types.py +51 -0
- targetprocess_py-0.1.0/tests/test_resources/test_epics.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_features.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_iterations.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_lookup_resolvers.py +109 -0
- targetprocess_py-0.1.0/tests/test_resources/test_priorities.py +154 -0
- targetprocess_py-0.1.0/tests/test_resources/test_processes.py +84 -0
- targetprocess_py-0.1.0/tests/test_resources/test_projects.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_relation_types.py +156 -0
- targetprocess_py-0.1.0/tests/test_resources/test_relations.py +88 -0
- targetprocess_py-0.1.0/tests/test_resources/test_releases.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_requests.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_role_efforts.py +64 -0
- targetprocess_py-0.1.0/tests/test_resources/test_roles.py +105 -0
- targetprocess_py-0.1.0/tests/test_resources/test_server_capability.py +133 -0
- targetprocess_py-0.1.0/tests/test_resources/test_severities.py +43 -0
- targetprocess_py-0.1.0/tests/test_resources/test_tasks.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_team_assignments.py +65 -0
- targetprocess_py-0.1.0/tests/test_resources/test_team_iterations.py +80 -0
- targetprocess_py-0.1.0/tests/test_resources/test_teams.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_terms.py +56 -0
- targetprocess_py-0.1.0/tests/test_resources/test_test_cases.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_times.py +603 -0
- targetprocess_py-0.1.0/tests/test_resources/test_user_stories.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_users.py +39 -0
- targetprocess_py-0.1.0/tests/test_resources/test_workflows.py +59 -0
- targetprocess_py-0.1.0/tests/test_response_parser.py +167 -0
- targetprocess_py-0.1.0/tests/test_role.py +39 -0
- targetprocess_py-0.1.0/tests/test_role_effort.py +48 -0
- targetprocess_py-0.1.0/tests/test_severity.py +38 -0
- targetprocess_py-0.1.0/tests/test_task.py +76 -0
- targetprocess_py-0.1.0/tests/test_team.py +40 -0
- targetprocess_py-0.1.0/tests/test_team_assignment.py +36 -0
- targetprocess_py-0.1.0/tests/test_team_iteration.py +91 -0
- targetprocess_py-0.1.0/tests/test_term.py +35 -0
- targetprocess_py-0.1.0/tests/test_test_case.py +52 -0
- targetprocess_py-0.1.0/tests/test_time.py +111 -0
- targetprocess_py-0.1.0/tests/test_transport.py +106 -0
- targetprocess_py-0.1.0/tests/test_types.py +47 -0
- targetprocess_py-0.1.0/tests/test_uploaded_attachment.py +124 -0
- targetprocess_py-0.1.0/tests/test_user.py +82 -0
- targetprocess_py-0.1.0/tests/test_user_story.py +75 -0
- targetprocess_py-0.1.0/tests/test_workflow.py +39 -0
- targetprocess_py-0.1.0/uv.lock +852 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
|
2
|
+
#
|
|
3
|
+
# This file supersedes the CodeRabbit dashboard settings for this repository:
|
|
4
|
+
# once present, dashboard values no longer apply here, so any organisation-wide
|
|
5
|
+
# settings we rely on must be restated in this file.
|
|
6
|
+
|
|
7
|
+
language: en-ZA
|
|
8
|
+
|
|
9
|
+
reviews:
|
|
10
|
+
profile: assertive
|
|
11
|
+
in_progress_fortune: false
|
|
12
|
+
# Withhold CodeRabbit's approval until every conversation on the PR is
|
|
13
|
+
# resolved and no error-mode pre-merge check is failing; approval is then
|
|
14
|
+
# granted automatically. This makes CodeRabbit re-approve once satisfied
|
|
15
|
+
# (a first-pass "changes requested" otherwise never clears to approved),
|
|
16
|
+
# and gives the error-mode pre-merge checks below their merge-blocking teeth.
|
|
17
|
+
request_changes_workflow: true
|
|
18
|
+
|
|
19
|
+
auto_review:
|
|
20
|
+
# No automatic reviews. Every pull request here is agent-authored and its
|
|
21
|
+
# coordinator requests each review explicitly ("@coderabbitai review", or
|
|
22
|
+
# "full review") once the content is final, so no included review or paid
|
|
23
|
+
# credit is spent on an intermediate push, and draft state gates nothing.
|
|
24
|
+
# With automatic reviews off CodeRabbit posts a passing "Review skipped"
|
|
25
|
+
# status on every push, so a required CodeRabbit status check no longer
|
|
26
|
+
# proves a review ran; the approving-review requirement is the gate.
|
|
27
|
+
# Bot-authored pull requests (Dependabot and the like) are not auto-reviewed
|
|
28
|
+
# regardless.
|
|
29
|
+
enabled: false
|
|
30
|
+
|
|
31
|
+
finishing_touches:
|
|
32
|
+
simplify:
|
|
33
|
+
enabled: true
|
|
34
|
+
|
|
35
|
+
pre_merge_checks:
|
|
36
|
+
# Only a requested reviewer — never the PR author — may ignore a failing
|
|
37
|
+
# error-mode check, so the author cannot self-bypass the error-mode gate
|
|
38
|
+
# defined below.
|
|
39
|
+
override_requested_reviewers_only: true
|
|
40
|
+
|
|
41
|
+
# The built-in docstring-coverage check cannot exclude test code, and test
|
|
42
|
+
# methods idiomatically carry no docstrings — so it is disabled here and
|
|
43
|
+
# replaced by the "Docstring coverage (non-test)" custom check below, which
|
|
44
|
+
# excludes tests by prose.
|
|
45
|
+
docstrings:
|
|
46
|
+
mode: "off"
|
|
47
|
+
|
|
48
|
+
custom_checks:
|
|
49
|
+
- name: "Docstring coverage (non-test)"
|
|
50
|
+
mode: "error"
|
|
51
|
+
instructions: |
|
|
52
|
+
Fail if any public function, method, or class ADDED or MODIFIED in
|
|
53
|
+
this pull request lacks a docstring. Judge each file by intent, not by
|
|
54
|
+
an exhaustive pattern list. EXCLUDE all test code: any file located in
|
|
55
|
+
a test directory at any depth (e.g. tests/, test/, __tests__/, spec/)
|
|
56
|
+
or whose name marks it as a test (test_*, *_test, *.test.*, *.spec.*
|
|
57
|
+
in any language or extension), and any test function or method (name
|
|
58
|
+
starting with "test") — test code idiomatically carries no docstrings
|
|
59
|
+
and must not count against coverage. Also exclude generated or
|
|
60
|
+
vendored code. Scope the check to languages that have a docstring
|
|
61
|
+
convention (Python, and JS/TS/JSX/TSX via JSDoc); ignore languages
|
|
62
|
+
that have none (YAML, shell, JSON).
|
|
63
|
+
|
|
64
|
+
- name: "Checklist complete"
|
|
65
|
+
mode: "error"
|
|
66
|
+
instructions: |
|
|
67
|
+
Parse task-list items in THIS pull request's own description only —
|
|
68
|
+
never in a linked issue, a comment, or any external document. GitHub
|
|
69
|
+
Flavored Markdown task lists use unordered ("-", "*", "+") or ordered
|
|
70
|
+
("1." or "1)") list markers at any indentation level. IGNORE any
|
|
71
|
+
section whose heading is "Post-merge verification" (or that clearly
|
|
72
|
+
denotes post-merge / post-deploy checks): those are verified after
|
|
73
|
+
merge and must not gate this pre-merge check. Of the remaining items,
|
|
74
|
+
fail if any is unticked ("[ ]"). Treat "[x]" and "[X]" as ticked and
|
|
75
|
+
"[~]" (inapplicable) as addressed. Pass when no unticked items remain,
|
|
76
|
+
or the description has no gating task-list items.
|
|
77
|
+
|
|
78
|
+
- name: "No committed superpowers artefacts"
|
|
79
|
+
mode: "error"
|
|
80
|
+
instructions: |
|
|
81
|
+
Fail if this pull request ADDS any new file under docs/superpowers/
|
|
82
|
+
or docs/plans/. These directories hold transient brainstorming and
|
|
83
|
+
writing-plans working documents (design specs and implementation
|
|
84
|
+
plans) that are kept on disk for the working session only and must
|
|
85
|
+
never be committed — the living specification lives in SPEC.md,
|
|
86
|
+
updated alongside changes. A new file anywhere outside these two
|
|
87
|
+
directories is fine; the ban is scoped to them.
|
|
88
|
+
|
|
89
|
+
path_filters:
|
|
90
|
+
# Auto-generated lockfiles — reviewing their diffs is noise, not signal.
|
|
91
|
+
- "!**/package-lock.json"
|
|
92
|
+
- "!**/*.script.lock"
|
|
93
|
+
- "!**/poetry.lock"
|
|
94
|
+
- "!**/bun.lockb"
|
|
95
|
+
- "!**/uv.lock"
|
|
96
|
+
|
|
97
|
+
path_instructions:
|
|
98
|
+
- path: "src/targetprocess/**"
|
|
99
|
+
instructions: >
|
|
100
|
+
Async Python library for the TargetProcess v1 REST API. TP facts that are
|
|
101
|
+
correct and must not be "fixed": tokens are sent as an access_token query
|
|
102
|
+
parameter (TP has no header token scheme); dates arrive as /Date(ms±HHMM)/;
|
|
103
|
+
collection responses are {Next, Items} and pagination follows Next verbatim.
|
|
104
|
+
- path: "tests/**"
|
|
105
|
+
instructions: |
|
|
106
|
+
Pytest suite. New or modified test doubles must be constrained to a
|
|
107
|
+
real interface: Mock() and MagicMock() require spec= (or spec_set=),
|
|
108
|
+
and patch()/patch.object() require autospec=True or an explicit
|
|
109
|
+
spec. An unspecced double accepts any attribute access, hiding
|
|
110
|
+
exactly the interface-drift bugs a test exists to catch. For
|
|
111
|
+
TypedDicts and other shapes that spec poorly, use real stub dicts
|
|
112
|
+
instead of mocks.
|
|
113
|
+
- path: "tests/integration/cassettes/**"
|
|
114
|
+
instructions: >
|
|
115
|
+
Recorded VCR fixtures — flag immediately any unredacted credential,
|
|
116
|
+
PII (names, logins, emails), real TargetProcess hostname, or real
|
|
117
|
+
business content (issue titles, descriptions, comments): those must
|
|
118
|
+
be sanitised placeholder values. Bare numeric Ids are deliberately
|
|
119
|
+
preserved and must NOT be flagged — neither real entity Ids nor the
|
|
120
|
+
product-seeded lookup constants every TP tenant shares (Priority
|
|
121
|
+
1–5, EntityType 4): with names, logins, text and hostname already
|
|
122
|
+
placeholders, an Id on its own identifies nothing. Structural
|
|
123
|
+
fields — Id, ResourceType, dates, numeric/boolean fields, the
|
|
124
|
+
Items/Next/Prev envelope — are kept as recorded so a cassette still
|
|
125
|
+
exercises real parsing, pagination and filter behaviour
|
|
126
|
+
(docs/testing.md). On a write-path cassette the REQUEST body is
|
|
127
|
+
recorded as sent and is deliberately not field-scrubbed: its
|
|
128
|
+
Name/Description values are synthetic strings the test invented,
|
|
129
|
+
carrying the recording ticket's reference as a prefix, and must NOT
|
|
130
|
+
be flagged. Do flag a request body carrying text that reads as
|
|
131
|
+
having come off the live instance rather than being invented.
|
|
132
|
+
- path: ".github/workflows/**"
|
|
133
|
+
instructions: |
|
|
134
|
+
GitHub Actions CI — high blast radius. Validation jobs run on pull
|
|
135
|
+
requests; nothing here deploys. Flag changes that loosen branch gating,
|
|
136
|
+
broaden event triggers, widen permissions, or expose secrets.
|
|
137
|
+
- path: "**/.env"
|
|
138
|
+
instructions: |
|
|
139
|
+
Gitignored credentials file — it must never be committed. Treat any
|
|
140
|
+
.env appearing in a diff as a critical defect.
|
|
141
|
+
|
|
142
|
+
chat:
|
|
143
|
+
art: false
|
|
144
|
+
|
|
145
|
+
code_generation:
|
|
146
|
+
docstrings:
|
|
147
|
+
language: en-ZA
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": ["@commitlint/config-conventional"],
|
|
3
|
+
"rules": {
|
|
4
|
+
"type-enum": [
|
|
5
|
+
2,
|
|
6
|
+
"always",
|
|
7
|
+
[
|
|
8
|
+
"feat",
|
|
9
|
+
"fix",
|
|
10
|
+
"docs",
|
|
11
|
+
"style",
|
|
12
|
+
"refactor",
|
|
13
|
+
"perf",
|
|
14
|
+
"test",
|
|
15
|
+
"build",
|
|
16
|
+
"ci",
|
|
17
|
+
"chore",
|
|
18
|
+
"revert"
|
|
19
|
+
]
|
|
20
|
+
],
|
|
21
|
+
"type-case": [2, "always", "lower-case"],
|
|
22
|
+
"type-empty": [2, "never"],
|
|
23
|
+
"subject-empty": [2, "never"],
|
|
24
|
+
"subject-full-stop": [2, "never", "."],
|
|
25
|
+
"subject-case": [
|
|
26
|
+
2,
|
|
27
|
+
"always",
|
|
28
|
+
["lower-case", "sentence-case"]
|
|
29
|
+
],
|
|
30
|
+
"header-max-length": [2, "always", 72],
|
|
31
|
+
"body-leading-blank": [2, "always"],
|
|
32
|
+
"body-max-line-length": [2, "always", 100],
|
|
33
|
+
"footer-leading-blank": [2, "always"]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Copy this file to .env and fill in real values. .env is gitignored and
|
|
2
|
+
# must never be committed. See the "Secrets management" section of the
|
|
3
|
+
# README for the env-var -> secrets-manager pattern.
|
|
4
|
+
#
|
|
5
|
+
# cp .env.example .env
|
|
6
|
+
|
|
7
|
+
# TargetProcess instance domain (no scheme), e.g. example.tpondemand.com
|
|
8
|
+
TP_DOMAIN=example.tpondemand.com
|
|
9
|
+
|
|
10
|
+
# TargetProcess API token, sent as the access_token query parameter.
|
|
11
|
+
# Fetch it from your TP instance's account settings; never share or commit it.
|
|
12
|
+
TP_TOKEN=your-api-token
|
|
13
|
+
|
|
14
|
+
# Comma-separated allow-list of project ids the write examples may modify.
|
|
15
|
+
# Only set this for a throwaway/sandbox project; never production.
|
|
16
|
+
# Required by examples/create_bug.py and examples/bulk_updates.py.
|
|
17
|
+
TP_WRITE_ALLOWED_PROJECT_IDS=
|
|
18
|
+
|
|
19
|
+
# --- Integration-cassette recording only -------------------------------------
|
|
20
|
+
# tests/integration/ replays committed cassettes offline and needs nothing set.
|
|
21
|
+
# Re-recording against a live instance (ALLOW_PROD_RECORDING=1) uses this second
|
|
22
|
+
# pair instead, read from the environment or from ~/.config/targetprocess/.env.
|
|
23
|
+
# Leave both blank unless you are deliberately re-recording.
|
|
24
|
+
TP_BASE_URL=
|
|
25
|
+
TP_API_TOKEN=
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report something that is not working as expected
|
|
3
|
+
title: "[Bug] "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to file a bug report! Please fill in the
|
|
10
|
+
sections below so we can reproduce and fix it.
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: summary
|
|
13
|
+
attributes:
|
|
14
|
+
label: Summary
|
|
15
|
+
description: A concise description of the problem.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: reproduce
|
|
20
|
+
attributes:
|
|
21
|
+
label: Steps to reproduce
|
|
22
|
+
description: |
|
|
23
|
+
The smallest self-contained example that triggers the bug. Include the
|
|
24
|
+
code, the command you ran, and any relevant environment details. Redact
|
|
25
|
+
real tokens — never paste a live `TP_TOKEN`.
|
|
26
|
+
placeholder: |
|
|
27
|
+
1. ...
|
|
28
|
+
2. ...
|
|
29
|
+
3. ...
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: expected
|
|
34
|
+
attributes:
|
|
35
|
+
label: Expected behaviour
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
- type: textarea
|
|
39
|
+
id: actual
|
|
40
|
+
attributes:
|
|
41
|
+
label: Actual behaviour
|
|
42
|
+
description: |
|
|
43
|
+
Include the full traceback or error message if there is one. Redact
|
|
44
|
+
tokens, credentials, authorisation headers, cookies, and query strings
|
|
45
|
+
before posting — a traceback often carries the request URL.
|
|
46
|
+
validations:
|
|
47
|
+
required: true
|
|
48
|
+
- type: textarea
|
|
49
|
+
id: environment
|
|
50
|
+
attributes:
|
|
51
|
+
label: Environment
|
|
52
|
+
description: Library version, Python version, OS, and anything else relevant.
|
|
53
|
+
placeholder: |
|
|
54
|
+
- targetprocess-py: 0.x.y
|
|
55
|
+
- Python: 3.12.x
|
|
56
|
+
- OS: ...
|
|
57
|
+
validations:
|
|
58
|
+
required: true
|
|
59
|
+
- type: dropdown
|
|
60
|
+
id: priority
|
|
61
|
+
attributes:
|
|
62
|
+
label: Priority
|
|
63
|
+
description: |
|
|
64
|
+
How urgent is this? P1 blocks work with no reasonable workaround, P2 has
|
|
65
|
+
real impact but a workaround exists, P3 is cosmetic or minor. P0 is
|
|
66
|
+
reserved for security incidents — report those via the security link on
|
|
67
|
+
the issue chooser instead.
|
|
68
|
+
options:
|
|
69
|
+
- "P1 — High"
|
|
70
|
+
- "P2 — Medium"
|
|
71
|
+
- "P3 — Low"
|
|
72
|
+
validations:
|
|
73
|
+
required: true
|
|
74
|
+
- type: textarea
|
|
75
|
+
id: context
|
|
76
|
+
attributes:
|
|
77
|
+
label: Additional context
|
|
78
|
+
description: Anything else? Links, related issues, screenshots.
|
|
79
|
+
validations:
|
|
80
|
+
required: false
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
# GitHub's "report a vulnerability" advisory route needs private vulnerability
|
|
4
|
+
# reporting, which this private repository does not expose, so the security
|
|
5
|
+
# contact is e-mail. Switch to the advisories URL if the repo is ever made
|
|
6
|
+
# public and the feature is enabled.
|
|
7
|
+
- name: Security report
|
|
8
|
+
url: mailto:louis@man8.com?subject=targetprocess-py%20security%20report
|
|
9
|
+
about: Report a security vulnerability privately by e-mail, not as a public issue.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new capability or improvement
|
|
3
|
+
title: "[Feature] "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for the suggestion! Tell us what you want and why.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: problem
|
|
12
|
+
attributes:
|
|
13
|
+
label: Problem
|
|
14
|
+
description: What is currently hard or impossible to do?
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: solution
|
|
19
|
+
attributes:
|
|
20
|
+
label: Proposed solution
|
|
21
|
+
description: What would you like the library to do instead?
|
|
22
|
+
validations:
|
|
23
|
+
required: true
|
|
24
|
+
- type: textarea
|
|
25
|
+
id: alternatives
|
|
26
|
+
attributes:
|
|
27
|
+
label: Alternatives considered
|
|
28
|
+
description: Any workarounds or other approaches you thought about.
|
|
29
|
+
validations:
|
|
30
|
+
required: false
|
|
31
|
+
- type: dropdown
|
|
32
|
+
id: area
|
|
33
|
+
attributes:
|
|
34
|
+
label: Area
|
|
35
|
+
description: Which part of the library does this touch?
|
|
36
|
+
options:
|
|
37
|
+
- "area: client"
|
|
38
|
+
- "area: models"
|
|
39
|
+
- "area: transport"
|
|
40
|
+
- "area: observability"
|
|
41
|
+
- "area: docs"
|
|
42
|
+
- "area: ci"
|
|
43
|
+
- "area: testing"
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
- type: dropdown
|
|
47
|
+
id: priority
|
|
48
|
+
attributes:
|
|
49
|
+
label: Priority
|
|
50
|
+
description: |
|
|
51
|
+
How important is this to you? P1 blocks work with no reasonable
|
|
52
|
+
workaround, P2 has real impact but a workaround exists, P3 is cosmetic
|
|
53
|
+
or minor.
|
|
54
|
+
options:
|
|
55
|
+
- "P1 — High"
|
|
56
|
+
- "P2 — Medium"
|
|
57
|
+
- "P3 — Low"
|
|
58
|
+
validations:
|
|
59
|
+
required: true
|
|
60
|
+
- type: textarea
|
|
61
|
+
id: context
|
|
62
|
+
attributes:
|
|
63
|
+
label: Additional context
|
|
64
|
+
description: Anything else? Links, mockups, related issues.
|
|
65
|
+
validations:
|
|
66
|
+
required: false
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Automated dependency updates. Two ecosystems are in play here:
|
|
2
|
+
#
|
|
3
|
+
# uv — the locked Python environment (pyproject.toml + uv.lock).
|
|
4
|
+
# versioning-strategy: lockfile-only keeps Dependabot out of
|
|
5
|
+
# pyproject.toml entirely, so the declared floors stay
|
|
6
|
+
# deliberate while the resolved versions CI installs stay
|
|
7
|
+
# current. See the strategy note on that key below.
|
|
8
|
+
# github-actions — the SHA-pinned actions in .github/workflows/. Pinning to a
|
|
9
|
+
# commit is the supply-chain-safe form but it never floats, so
|
|
10
|
+
# without Dependabot those pins silently rot.
|
|
11
|
+
# pre-commit — the hook repos pinned by `rev:` in .pre-commit-config.yaml.
|
|
12
|
+
# Same rot problem as the action pins. The ruff/mypy hooks are
|
|
13
|
+
# not listed there: they run via `uv run`, so the uv ecosystem
|
|
14
|
+
# above already keeps them current.
|
|
15
|
+
#
|
|
16
|
+
# Every update lands as a pull request, so the existing gates (ruff, ruff-format,
|
|
17
|
+
# mypy --strict, pytest with --cov-fail-under=90, the pre-commit hook suite,
|
|
18
|
+
# duplication detection, CodeQL, CodeRabbit review) decide whether a bump is safe
|
|
19
|
+
# before it reaches main.
|
|
20
|
+
version: 2
|
|
21
|
+
|
|
22
|
+
updates:
|
|
23
|
+
- package-ecosystem: "uv"
|
|
24
|
+
directory: "/"
|
|
25
|
+
# Explicit rather than the default "auto", which guesses app-vs-library and
|
|
26
|
+
# would rewrite pyproject.toml: "increase" raises the floor to the newest
|
|
27
|
+
# release, and "widen" adds an upper bound. Neither is right for a published
|
|
28
|
+
# library — an upper cap propagates into every downstream resolution, and a
|
|
29
|
+
# raised floor drops support for versions that still work. lockfile-only
|
|
30
|
+
# confines Dependabot to uv.lock. Because the constraints here are open-ended
|
|
31
|
+
# (httpx>=0.27.0, pydantic>=2.0.0, easylimit>=0.3.4), the manifest already
|
|
32
|
+
# permits new releases, so this forgoes no upgrades: majors still land, they
|
|
33
|
+
# just arrive as a lock change plus a green/red CI signal, and widening the
|
|
34
|
+
# declared floor stays a deliberate human decision.
|
|
35
|
+
versioning-strategy: "lockfile-only"
|
|
36
|
+
schedule:
|
|
37
|
+
interval: "weekly"
|
|
38
|
+
day: "monday"
|
|
39
|
+
time: "07:00"
|
|
40
|
+
timezone: "Africa/Johannesburg"
|
|
41
|
+
open-pull-requests-limit: 5
|
|
42
|
+
labels:
|
|
43
|
+
- "dependencies"
|
|
44
|
+
commit-message:
|
|
45
|
+
prefix: "deps"
|
|
46
|
+
prefix-development: "deps-dev"
|
|
47
|
+
include: "scope"
|
|
48
|
+
groups:
|
|
49
|
+
# Test/lint/type tooling moves together: a mypy or ruff bump is judged by
|
|
50
|
+
# whether CI still passes, so batching them keeps review cost proportional.
|
|
51
|
+
dev-tooling:
|
|
52
|
+
patterns:
|
|
53
|
+
- "pytest*"
|
|
54
|
+
- "mypy*"
|
|
55
|
+
- "ruff"
|
|
56
|
+
- "coverage*"
|
|
57
|
+
- "vcrpy"
|
|
58
|
+
- "pre-commit"
|
|
59
|
+
# Runtime dependencies are batched only for minor/patch. Majors are
|
|
60
|
+
# deliberately left ungrouped so each arrives as its own PR — httpx,
|
|
61
|
+
# pydantic and easylimit are the library's public surface (pydantic v2
|
|
62
|
+
# models and httpx types leak into user code), so a major needs to be
|
|
63
|
+
# reviewed and released on its own.
|
|
64
|
+
runtime-minor-patch:
|
|
65
|
+
patterns:
|
|
66
|
+
- "httpx"
|
|
67
|
+
- "pydantic*"
|
|
68
|
+
- "easylimit"
|
|
69
|
+
update-types:
|
|
70
|
+
- "minor"
|
|
71
|
+
- "patch"
|
|
72
|
+
|
|
73
|
+
- package-ecosystem: "pre-commit"
|
|
74
|
+
directory: "/"
|
|
75
|
+
schedule:
|
|
76
|
+
interval: "weekly"
|
|
77
|
+
day: "monday"
|
|
78
|
+
time: "07:00"
|
|
79
|
+
timezone: "Africa/Johannesburg"
|
|
80
|
+
open-pull-requests-limit: 3
|
|
81
|
+
labels:
|
|
82
|
+
- "dependencies"
|
|
83
|
+
commit-message:
|
|
84
|
+
prefix: "ci"
|
|
85
|
+
include: "scope"
|
|
86
|
+
groups:
|
|
87
|
+
pre-commit:
|
|
88
|
+
patterns:
|
|
89
|
+
- "*"
|
|
90
|
+
|
|
91
|
+
- package-ecosystem: "github-actions"
|
|
92
|
+
directory: "/"
|
|
93
|
+
schedule:
|
|
94
|
+
interval: "weekly"
|
|
95
|
+
day: "monday"
|
|
96
|
+
time: "07:00"
|
|
97
|
+
timezone: "Africa/Johannesburg"
|
|
98
|
+
open-pull-requests-limit: 3
|
|
99
|
+
labels:
|
|
100
|
+
- "dependencies"
|
|
101
|
+
commit-message:
|
|
102
|
+
prefix: "ci"
|
|
103
|
+
include: "scope"
|
|
104
|
+
groups:
|
|
105
|
+
github-actions:
|
|
106
|
+
patterns:
|
|
107
|
+
- "*"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Issue and pull-request label set for targetprocess-py.
|
|
2
|
+
#
|
|
3
|
+
# GitHub's 9 default labels plus the two Dependabot labels
|
|
4
|
+
# (`dependencies`, `python:uv`) are already present; this file defines the
|
|
5
|
+
# project-specific priority and area labels that sit on top of them.
|
|
6
|
+
#
|
|
7
|
+
# To (re)apply this set to the repository, run:
|
|
8
|
+
#
|
|
9
|
+
# scripts/apply_labels.sh
|
|
10
|
+
#
|
|
11
|
+
# which calls `gh label create` (or `--force` to update colours/descriptions).
|
|
12
|
+
# Existing labels are left untouched unless they appear below.
|
|
13
|
+
#
|
|
14
|
+
# The priority and area dropdowns in the issue forms record the reporter's
|
|
15
|
+
# choice in the issue body only — GitHub applies just the form's own top-level
|
|
16
|
+
# `labels:` key, so the P#/area labels below still have to be applied by hand
|
|
17
|
+
# (or by a future labeler workflow) during triage.
|
|
18
|
+
|
|
19
|
+
# --- Priority ---------------------------------------------------------------
|
|
20
|
+
# P0 is reserved for security incidents and outages and is not exposed in the
|
|
21
|
+
# issue-template dropdowns; file those via the Security report contact link.
|
|
22
|
+
- name: "P0 — Critical"
|
|
23
|
+
color: "b60205"
|
|
24
|
+
description: "Security incident or outage; drop everything."
|
|
25
|
+
- name: "P1 — High"
|
|
26
|
+
color: "d93f0b"
|
|
27
|
+
description: "Blocks work, no reasonable workaround."
|
|
28
|
+
- name: "P2 — Medium"
|
|
29
|
+
color: "fbca04"
|
|
30
|
+
description: "Real impact, a workaround exists."
|
|
31
|
+
- name: "P3 — Low"
|
|
32
|
+
color: "0e8a16"
|
|
33
|
+
description: "Cosmetic or minor; nice to have."
|
|
34
|
+
|
|
35
|
+
# --- Area -------------------------------------------------------------------
|
|
36
|
+
- name: "area: client"
|
|
37
|
+
color: "1d76db"
|
|
38
|
+
description: "Client layer and resource managers."
|
|
39
|
+
- name: "area: models"
|
|
40
|
+
color: "5319e7"
|
|
41
|
+
description: "Pydantic entity and reference models."
|
|
42
|
+
- name: "area: transport"
|
|
43
|
+
color: "006b75"
|
|
44
|
+
description: "HTTP transport, auth, retry, rate limiting."
|
|
45
|
+
- name: "area: observability"
|
|
46
|
+
color: "0052cc"
|
|
47
|
+
description: "Logging, scrubbing, request-id propagation."
|
|
48
|
+
- name: "area: docs"
|
|
49
|
+
color: "0075ca"
|
|
50
|
+
description: "README, usage guide, examples, SPEC."
|
|
51
|
+
- name: "area: ci"
|
|
52
|
+
color: "6f42c1"
|
|
53
|
+
description: "GitHub Actions, pre-commit, Dependabot, CodeRabbit."
|
|
54
|
+
- name: "area: testing"
|
|
55
|
+
color: "a2eeef"
|
|
56
|
+
description: "pytest suite, VCR cassettes, coverage."
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Thanks for the pull request! Title it as a Conventional Commits subject
|
|
3
|
+
(`type(scope): description`): squash merge makes it the commit on main, and CI
|
|
4
|
+
checks it as one. Fill in the sections below, then complete the
|
|
5
|
+
checklist. CodeRabbit's "Checklist complete" pre-merge check fails if any
|
|
6
|
+
unticked ("- [ ]") task-list item remains in this description, so tick each
|
|
7
|
+
box as you go (or mark inapplicable items with "[~]").
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
<!-- What does this change do, and why? Reference the issue or work item
|
|
13
|
+
this closes. -->
|
|
14
|
+
|
|
15
|
+
Closes #
|
|
16
|
+
|
|
17
|
+
## Changes
|
|
18
|
+
|
|
19
|
+
<!-- Bullet list of the meaningful changes. Group by area if the PR spans
|
|
20
|
+
more than one (e.g. transport, models, docs). -->
|
|
21
|
+
|
|
22
|
+
-
|
|
23
|
+
|
|
24
|
+
## Testing
|
|
25
|
+
|
|
26
|
+
<!-- How did you verify this? Which commands did you run? Paste a short,
|
|
27
|
+
redacted transcript if useful. Never paste a live TP_TOKEN. -->
|
|
28
|
+
|
|
29
|
+
-
|
|
30
|
+
|
|
31
|
+
## Context
|
|
32
|
+
|
|
33
|
+
<!-- Anything a reviewer should know: alternatives considered, follow-ups,
|
|
34
|
+
risk, migration notes, or "none". -->
|
|
35
|
+
|
|
36
|
+
-
|
|
37
|
+
|
|
38
|
+
## Checklist
|
|
39
|
+
|
|
40
|
+
- [ ] `uv run ruff check .` and `uv run ruff format --check .` pass
|
|
41
|
+
- [ ] `uv run mypy --strict src` passes
|
|
42
|
+
- [ ] `uv run pytest -q` passes and coverage stays at or above 90%
|
|
43
|
+
- [ ] `uv run pre-commit run --all-files --hook-stage pre-commit` passes
|
|
44
|
+
- [ ] `uv run pre-commit run --all-files --hook-stage pre-push` passes
|
|
45
|
+
- [ ] New public functions, methods, and classes have docstrings
|
|
46
|
+
- [ ] No real credentials, tokens, or PII are added to the diff
|
|
47
|
+
- [ ] `TODO`/`FIXME`/`HACK`/`XXX` markers name an issue (e.g. `TODO(#123)`)
|
|
48
|
+
|
|
49
|
+
<!--
|
|
50
|
+
Post-merge verification does not belong in this description. It lives on the
|
|
51
|
+
linked work item under its own "## Post-merge verification" heading, where it
|
|
52
|
+
gates that item's Verify -> Done transition. Keeping it there leaves this
|
|
53
|
+
checklist purely pre-merge, so "all boxes ticked" and "ready to merge" mean the
|
|
54
|
+
same thing.
|
|
55
|
+
-->
|
|
56
|
+
|
|
57
|
+
<!--
|
|
58
|
+
Implicit merge gates — CI passing, the CodeRabbit review, human approval — are
|
|
59
|
+
deliberately absent from the checklist above. Branch protection already
|
|
60
|
+
enforces them, and rendering them as boxes invites a tick before the gate has
|
|
61
|
+
actually cleared.
|
|
62
|
+
-->
|