Observed since 20 Oct, 22:15 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Agentic devtools integrate Jira, DevOps & more
Agentic devtools integrate Jira, DevOps & more. This package provides simple CLI commands that can be easily auto-approved by VS Code AI assistants.
Audience: End users of the AGDT CLI. This README focuses on installation and usage.
A pip-installable Python package that provides CLI commands for AI agents to interact with Git, Azure DevOps, Jira, and other services.
# Install pipx if you don't have it
pip install pipx
pipx ensurepath
# ⚠️ IMPORTANT: Restart your terminal for PATH changes to take effect
# Or refresh PATH in current PowerShell session:
Workflow steps can be started from VS Code Copilot Chat using
`/agdt.<workflow>.<step>` commands.
# Install agentic-devtools
cd agentic_devtools
pipx install .
# For development (editable install)
pipx install -e .
Install directly into your system Python. May require administrator privileges on Windows.
cd agentic_devtools
# Global install (may need admin/sudo)
pip install .
# For development (editable)
pip install -e .
# With dev dependencies
pip install -e ".[dev]"
Note: Avoid
pip install --useras it places scripts in a directory that may not be on your PATH (%APPDATA%\Python\PythonXXX\Scriptson Windows).
After installation, verify the commands are available:
agdt-set --help
agdt-show
If commands are not found after installation:
pipx ensurepath and restart your terminalC:\PythonXXX\Scripts (or equivalent) is on your PATHagdt-setup generates a setup-dev-tools.py script tailored to the current
repository and optionally auto-runs it in the same invocation so that a single
command completes the full developer-environment setup.
First-run vs re-run. Whether setup-dev-tools.py already exists in the
worktree (re-run) or not (first-run), agdt-setup always regenerates the
script and then decides whether to auto-run it. The common local-interactive
path auto-runs, but if setup creates a dedicated branch/PR for generated repo
changes, auto-run is skipped until you review and merge that setup PR, then run
python setup-dev-tools.py. Either path may report UPGRADED_RERUN_NEEDED if
the package was upgraded during the invocation.
| Context | Default behavior | Override |
|---|---|---|
| Local interactive (first run) | Auto-run enabled; deferred if setup branch is created | --no-run |
| Local interactive (re-run) | Auto-runs | --no-run |
| CI / non-TTY | No auto-run | --run or AGDT_SETUP_RUN=1 |
PR-workflow exception: If setup generates repository changes and creates a
setup branch, auto-run is skipped even in a local interactive session. Review
and merge the setup PR, then run python setup-dev-tools.py.
Workflow-step exception: Auto-run is also skipped while a workflow is still
scaffolding the workspace — work-on-jira-issue at the setup step, or
pull-request-review at the initiate step. Both this and the PR-workflow
exception can be overridden by passing --run explicitly, which proceeds with
auto-run and prints a warning instead of skipping.
--run / --no-run FlagsThe two flags are mutually exclusive; passing both raises an error. Either flag overrides all environment variables and TTY detection.
Full precedence chain (highest priority first):
--run CLI flag → enable auto-run--no-run CLI flag → disable auto-runAGDT_SETUP_NO_AUTORUN env var (truthy) → disable auto-runAGDT_SETUP_RUN env var (truthy) → enable auto-runIn CI and non-TTY environments auto-run is disabled by default because
generated scripts should be reviewed before execution in non-interactive
contexts. To opt in, pass --run explicitly or set AGDT_SETUP_RUN=1.
UPGRADED_RERUN_NEEDED (Exit Code 4)When auto-run upgrades the agentic-devtools package during execution, the
command exits with code 4 (UPGRADED_RERUN_NEEDED). This signals that the
running CLI is now outdated and a re-run of agdt-setup is required to pick up
the new version.
AUTORUN_FAILED (Exit Code 6)When the auto-run of setup-dev-tools.py fails, agdt-setup exits with code
6 (AUTORUN_FAILED) and prints the path of the setup report containing the
recorded failure. A detected package upgrade takes precedence: if the version
changed during the run, exit code 4 is reported instead.
Setup prints AGDT_SETUP_PHASE: markers to stdout so that log consumers can
tell generation output apart from the auto-run child's output:
generation:start, generation:end, execution:start, and execution:end.
The execution:* pair is only printed when auto-run actually invokes the
generated script.
agdt-state.json file stores all parametersagdt-set command works for all keys
(approve once, use for everything)()[]{} and
multiline content directly!# Set state values (approve agdt-set once, use for any key)
agdt-set pr_id 23046
agdt-set thread_id 139474
agdt-set content "Thanks for the feedback!
I've made the changes you suggested."
# Execute action (parameterless - approve once)
agdt-reply-to-pr-thread
Agents are available in two contexts:
VS Code Copilot Chat — type / to browse all commands:
/speckit.agdt:specify Add a dark mode toggle ← SDD: create spec
/speckit.agdt:plan ← SDD: generate plan
/speckit.agdt:implement ← SDD: execute tasks
/agdt.work-on-jira-issue.initiate PROJECT-1 ← Jira workflow (11 steps)
/agdt.pull-request-review.initiate ← PR review (5 steps)
/agdt.git-save-work ← individual CLI command agent
/agdt.squash-commits ← standalone utility agent
Terminal Copilot CLI — ask naturally or use shell commands:
agdt-speckit-analyze # renders + prints the speckit.agdt:analyze prompt
agdt-speckit-specify "add dark mode"
Every agdt-* CLI command has a corresponding agent (.agent.md) and prompt
stub (.prompt.md) in .github/agents/ and .github/prompts/.
📖 Full reference: docs/copilot-commands.md
# Set any key-value pair
agdt-set <key> <value>
# Get a value
agdt-get <key>
# Delete a key
agdt-delete <key>
# Clear all state
agdt-clear
# Show all state
agdt-show
# Simple values
agdt-set pr_id 23046
agdt-set thread_id 139474
agdt-set dry_run true
# Content with special characters (works directly!)
agdt-set content "Fix: handle (optional) [array] parameters"
# Multiline content (works directly!)
agdt-set content "Thanks for the feedback!
I've addressed your concerns:
- Fixed the null check
- Added unit tests
- Updated documentation"
# View current state
agdt-show
Azure DevOps commands support both CLI parameters and state-based execution, and parameters passed
via CLI are automatically persisted to state for reuse. The provider-neutral
agdt-reply-to-pull-request-thread command snapshots CLI overrides for its background task but
does not persist them.
# Option A: With CLI parameters (explicit, self-documenting)
agdt-reply-to-pull-request-thread --provider azure_devops --pull-request-id 23046 --thread-id 139474 --content "Your reply"
agdt-reply-to-pull-request-thread --provider github --repository owner/repo -p 23046 -t 139474 -c "Thanks!"
# Option B: Parameterless (uses current state)
agdt-set platform.code_hosting azure_devops # or github
agdt-set repository owner/repo # required for GitHub
agdt-set pull_request_id 23046
agdt-set discussion_id 139474
agdt-set content "Your reply message"
agdt-reply-to-pull-request-thread
agdt-task-wait
# Optionally resolve the thread after replying
# Azure DevOps: no extra keys required
agdt-set resolve_thread true
agdt-reply-to-pull-request-thread
agdt-task-wait
# GitHub: also set the GraphQL review-thread node ID (required for resolution)
agdt-set review_thread_id "PRRT_opaque_node_id" # must match discussion_id
agdt-set resolve_thread true
agdt-reply-to-pull-request-thread
agdt-task-wait
# Option A: With CLI parameters (explicit)
agdt-set platform.code_hosting azure_devops
agdt-add-pull-request-comment --pull-request-id 23046 --content "LGTM!"
agdt-add-pull-request-comment -p 23046 -c "Looks good"
# Option B: Parameterless (uses current state)
agdt-set platform.code_hosting azure_devops
agdt-set pull_request_id 23046
agdt-set content "Your comment"
agdt-add-pull-request-comment
# For file-level comment
agdt-set path "src/example.py"
agdt-set line 42
agdt-add-pull-request-comment
# Azure DevOps
# Option A: With CLI parameters
agdt-set platform.code_hosting azure_devops
agdt-approve-pull-request --pull-request-id 23046 --content "Approved!"
agdt-approve-pull-request -p 23046
# Option B: Parameterless (uses current state)
agdt-set platform.code_hosting azure_devops
agdt-set pull_request_id 23046
agdt-set content "Approved!"
agdt-approve-pull-request
# GitHub (also requires a full head SHA to guard against approving a stale head)
agdt-set platform.code_hosting github
agdt-set github.repo owner/repo
agdt-set pull_request_id 23046
agdt-set "sourceCodeHostingPlatform.pullRequest.headSha" "<full 40-character commit SHA>"
agdt-approve-pull-request --content "Approved!"
# Option A: With CLI parameter
agdt-get-pull-request-threads --pull-request-id 23046
agdt-get-pull-request-threads -p 23046
# Option B: Parameterless (uses current state)
agdt-set pull_request_id 23046
agdt-get-pull-request-threads
# Option A: With CLI parameters
agdt-set platform.code_hosting azure_devops
agdt-resolve-thread --pull-request-id 23046 --thread-id 139474
# Option B: Parameterless (uses current state)
agdt-set platform.code_hosting github
agdt-set github.repo owner/repo
agdt-set pull_request_id 23046
agdt-set github.thread_node_id PRRT_opaque
agdt-resolve-thread
The command is provider-neutral: Azure DevOps accepts numeric PR thread IDs, while
GitHub accepts opaque PRRT_... review-thread node IDs (or a numeric github.comment_id
that is looked up before resolution). It returns a background task ID; use
agdt-task-wait to wait for completion and agdt-task-log to inspect the verified structured result.
agdt-set dry_run true
agdt-reply-to-pull-request-thread # Previews without making API calls
Manage multiple Azure CLI accounts (e.g., corporate account for Azure DevOps and AZA account for App Insights) without repeated az login / az logout cycles.
The Azure context system uses separate AZURE_CONFIG_DIR directories per account context. Both accounts can stay authenticated simultaneously and can be switched instantly via environment variable.
Available Contexts:
devops - Corporate account for Azure DevOps, Service Bus, etc.resources - AZA account for App Insights, Azure resources, Terraform, etc.Switch to a context (one-time setup per context):
# Switch to DevOps context
agdt-azure-context-use devops
# Switch to resources context
agdt-azure-context-use resources
Log in to each context (one-time per context):
# After switching to a context, log in using Azure CLI
az login
# This login is stored in the context's isolated config directory
Show all contexts with login status:
agdt-azure-context-status
Output:
Azure CLI Contexts:
================================================================================
devops [ACTIVE]
Description: Corporate account for Azure DevOps, Service Bus, etc.
Config Dir: ~/.azure-contexts/devops
Status: ✓ Logged in as user@company.com
resources
Description: AZA account for App Insights, Azure resources, Terraform, etc.
Config Dir: ~/.azure-contexts/resources
Status: ✓ Logged in as user@company.com
================================================================================
Check current active context:
agdt-azure-context-current
Switch contexts:
# Switch to DevOps context
agdt-azure-context-use devops
# Switch to resources context
agdt-azure-context-use resources
Ensure logged in (prompts if needed):
# Ensure current context is logged in
agdt-azure-context-ensure-login
# Ensure specific context is logged in
agdt-azure-context-ensure-login devops
Each context uses its own isolated Azure CLI configuration directory:
~/.azure-contexts/devops/ - DevOps context config and tokens~/.azure-contexts/resources/ - Resources context config and tokensWhen you run az commands, the active context's AZURE_CONFIG_DIR is used, so both accounts stay authenticated simultaneously. Switching contexts is instant (no browser login flow).
With VPN toggle: Contexts work seamlessly with the VPN toggle system. When certain contexts require VPN, the system coordinates VPN state automatically.
With Azure CLI:
All az commands respect the active context automatically via the AZURE_CONFIG_DIR environment variable.
The package provides streamlined Git workflow commands that support the single-commit policy.
# Option A: With CLI parameter (explicit)
| `agdt-get-pull-request-threads` | Get all PR comment threads |
- Change 1
- Change 2
[PROJECT-1234](https://jira.swica.ch/browse/PROJECT-1234)"
# Option B: Parameterless (uses current state)
# Current commit_message: run `agdt-get commit_message` to check
agdt-git-save-work
The agdt-git-save-work command automatically detects if you're updating an
existing commit:
# First commit - creates new commit and publishes branch
agdt-git-save-work --commit-message "feature(PROJECT-1234): initial implementation"
# Subsequent commits on same issue - automatically amends and force pushes
agdt-git-save-work --commit-message "feature(PROJECT-1234): refined implementation
- Original changes
- Additional updates"
# Auto-detects and amends!
Detection logic:
origin/main ANDjira.issue_key state)agdt-git-stage # Stage all changes (git add .)
agdt-git-push # Push changes (git push)
agdt-git-force-push # Force push with lease
agdt-git-publish # Push with upstream tracking
| Key | Purpose |
|---|---|
commit_message | The commit message (multiline supported) |
dry_run | If true, preview commands without executing |
skip_stage | If true, skip staging step |
skip_push | If true, skip push step (for agdt-git-save-work) |
The package provides workflow commands for managing structured work processes.
When a workflow creates a new worktree and opens it in VS Code, a Copilot CLI
session can auto-start in the VS Code integrated terminal via a
.vscode/tasks.json entry with "runOn": "folderOpen". This makes the session
immediately visible to the user as soon as the window opens. The task is
one-shot: it marks the current run ID in the workflow state
(copilot.auto_start_triggered_runs) before execution and, on success,
removes itself from tasks.json. When
tasks.json was created solely for auto-start and no other tasks remain, the
file is deleted (along with the .vscode/ directory if empty) so no untracked
files are left behind. When tasks.json was pre-existing, it is rewritten
without the injected task (preserving other tasks and top-level keys). On
failure the task stays in tasks.json so the next folderOpen retries the
command.
When the session is requested in interactive mode but there is no TTY attached (background task context) and VS Code is not available, a notice is printed:
NOTE: VS Code integrated terminal auto-start not available. Copilot session
will run in the background. Run agdt-task-log to view output.
All agdt-initiate-*-workflow commands automatically launch a Copilot CLI session after
workflow initiation (and auto-setup when needed). The rendered prompt is saved to the
workflow state directory; the normal bootstrap prompt names the exact rendered prompt
file and tells the agent to read it before doing any work. When the workflow is unknown,
or when the nested auto-execute step fails while preparing a worktree, the bootstrap
prompt instead tells the agent to run agdt-get-next-workflow-prompt so the current step
is regenerated from state. In the PR review workflow, once the initiate prompt has been
read, the agent advances with agdt-advance-workflow pr-synthesis. See
docs/workflow-prompts.md for the prompt file inventory and
full lifecycle.
Two session modes exist depending on context. When a new worktree is opened in VS Code, a
folderOpen auto-start task starts an interactive session in the integrated terminal
regardless of --interactive. For direct invocations from the CLI, pass
--interactive true to attach to the terminal (requires a TTY and VS Code), or omit it
(default: non-interactive) to run the Copilot session as a detached background process
(not an agdt background task — use the copilot.* state keys to locate the session log
file):
agdt-initiate-work-on-jira-issue-workflow --issue-key PROJECT-1234
agdt-initiate-pull-request-review-workflow --pull-request-id 12345 --interactive true
If auto-session launch fails (no gh copilot, no TTY, or VS Code unavailable), the
rendered prompt is printed to the console and saved to the workflow state directory so you
can paste it manually into Copilot Chat as a fallback.
# Start work on a Jira issue
agdt-set jira.issue_key "PROJECT-1234"
agdt-initiate-work-on-jira-issue-workflow
Workflow Steps:
# Create implementation checklist
agdt-create-checklist "item1" "item2" "item3"
# Update checklist (mark items complete)
agdt-update-checklist --completed 1 3 # Mark items 1 and 3 as complete
# View current checklist
agdt-show-checklist
# Update during commit (auto-marks items and advances workflow)
agdt-git-save-work --completed 1 2 # Marks items complete before committing
# View current workflow state
agdt-get-workflow
# Advance to next step
agdt-advance-workflow
# Clear workflow
agdt-clear-workflow
Verwende die pypi.* Namespace-Keys für Release-Parameter. Setze deine PyPI
Tokens via Umgebungsvariablen:
TWINE_USERNAME=__token__TWINE_PASSWORD=<pypi-token># Parameter setzen
agdt-set pypi.package_name agentic-devtools
agdt-set pypi.version 0.1.0
agdt-set pypi.repository pypi # oder testpypi
agdt-set pypi.dry_run false
# Release starten (parameterlos)
agdt-release-pypi
agdt-task-status
agdt-task-log
agdt-task-wait
All Jira commands use the jira.* namespace for state values. Set
JIRA_COPILOT_PAT environment variable with your Jira API token.
agdt-set jira.issue_key "PROJECT-1234"
agdt-get-jira-issue
Commands with optional CLI parameters support two usage patterns:
# Option A: With CLI parameters (explicit)
agdt-add-jira-comment --jira-comment "Your comment text"
# Option B: Parameterless (uses current state)
# Current jira.issue_key: run `agdt-get jira.issue_key` to check
# Current jira.comment: run `agdt-get jira.comment` to check
agdt-add-jira-comment
agdt-set jira.project_key "PROJECT"
agdt-set jira.summary "Epic Title"
agdt-set jira.epic_name "EPIC-KEY"
agdt-set jira.role "developer"
agdt-set jira.desired_outcome "implement feature"
agdt-set jira.benefit "improved UX"
agdt-create-epic
# Optional: Add acceptance criteria
agdt-set jira.acceptance_criteria "- Criterion 1
- Criterion 2"
agdt-create-epic
agdt-set jira.project_key "PROJECT"
agdt-set jira.summary "Issue Title"
agdt-set jira.description "Issue description"
agdt-create-issue
# Or use user story format
agdt-set jira.role "developer"
agdt-set jira.desired_outcome "complete task"
agdt-set jira.benefit "value delivered"
agdt-create-issue
agdt-set jira.parent_key "PROJECT-1234"
agdt-set jira.summary "Subtask Title"
agdt-set jira.description "Subtask description"
agdt-create-subtask
agdt-set jira.dry_run true
agdt-create-issue # Previews payload without API call
The corporate VPN (Pulse Secure/Ivanti) creates a full tunnel that blocks public registries (npm, PyPI) while being required for internal resources (Jira, ESB). These commands provide intelligent VPN management so you don't need to manually connect/disconnect VPN when switching between tasks.
Check your current network context:
agdt-network-status
Output shows:
Automatically manage VPN based on command requirements:
# Ensure VPN is connected before running (for Jira, ESB, etc.)
agdt-vpn-run --require-vpn "curl https://jira.swica.ch/rest/api/2/issue/DP-123"
# Temporarily disconnect VPN for public access (npm, pip, etc.)
agdt-vpn-run --require-public "npm install"
# Auto-detect requirement from command content (default)
agdt-vpn-run --smart "az devops ..."
agdt-vpn-run "npm install express" # --smart is the default
The command will:
Direct VPN control commands (run in background):
# Connect VPN (skipped if on corporate network)
agdt-vpn-on
agdt-task-wait
# Disconnect VPN
agdt-vpn-off
agdt-task-wait
# Check VPN status
agdt-vpn-status
agdt-task-wait
Install npm packages (needs public access):
agdt-vpn-run --require-public "npm install"
Access Jira API (needs VPN):
agdt-vpn-run --require-vpn "curl https://jira.swica.ch/rest/api/2/serverInfo"
Smart detection (recommended):
# Auto-detects that npm install needs public access
agdt-vpn-run "npm install express lodash"
# Auto-detects that Jira URL needs VPN
agdt-vpn-run "curl https://jira.swica.ch/rest/api/2/issue/DP-123"
When on the corporate network (physically in the office), VPN operations are automatically skipped since internal resources are already accessible. However, note that the corporate network may still block external registries (npm, PyPI) - in that case, consider connecting to a different network (e.g., mobile hotspot) for external access.
All new unit tests follow the 1:1:1 policy — one test file per symbol (function or class), mirroring the
source structure under tests/unit/. See tests/README.md for the full
policy, rationale, and step-by-step guide.
Quick reference:
tests/unit/{module_path}/{source_file_name}/test_{symbol_name}.py
Examples:
| Source | Test file |
|---|---|
agentic_devtools/state.py → get_value() | tests/unit/state/test_get_value.py |
agentic_devtools/cli/git/core.py → get_current_branch() | tests/unit/cli/git/core/test_get_current_branch.py |
Run the structure validator before pushing:
python scripts/validate_test_structure.py
| Variable | Purpose |
|---|---|
AZURE_DEV_OPS_COPILOT_PAT | Azure DevOps PAT for API calls |
JIRA_COPILOT_PAT | Jira API token for authentication |
JIRA_BASE_URL | Override default Jira URL (default: https://jira.swica.ch) |
JIRA_SSL_VERIFY | Set to 0 to disable SSL verification |
JIRA_CA_BUNDLE | Path to custom CA bundle PEM file for Jira SSL |
REQUESTS_CA_BUNDLE | Standard requests library CA bundle path (fallback) |
AGENTIC_DEVTOOLS_STATE_DIR | Override default state directory (e.g., .agdt/workflows/_unscoped) |
By default, state is stored in .agdt/workflows/{identity}/{worktree_key}/state.json (relative to the
repo root).
VS Code's auto-approval matches exact command strings. By using:
agdt-set key value - approve once, use for any keyagdt-reply-to-pr-thread...you only need to approve a few commands once, then they work for all future operations.
Unlike PowerShell, Python's CLI parsing handles special characters natively:
# This just works!
agdt-set content "Code with (parentheses) and [brackets]"
Python preserves multiline strings from the shell:
agdt-set content "Line 1
Line 2
Line 3"
The repository includes GitHub Actions that automatically trigger the SpecKit
specification process when a speckit label is added to an issue. The pipeline
creates a separate PR per phase, enabling incremental review.
For an overview of the original SpecKit workflow design, see the SpecKit Workflow Sequence Diagram.
Note: The diagram documents the initial monolithic pipeline design. The current per-phase PR progression described below supersedes parts of that flow.
speckit label to the issuespec.md and creates a PR labeled speckit:phase-1plan.md, tasks.md, and
generated/analysis-report.md; epic runs omit tasks.md; task runs produce
only tasks.md using parent feature contextspeckit:completed and speckit:needs-implementation labels are appliedEach phase creates its own focused PR for independent review. Reviewers can edit artifacts before merging, steering subsequent phases.
Configure the action using repository variables:
| Variable | Default | Description |
|---|---|---|
SPECKIT_TRIGGER_LABEL | speckit | The label that triggers the SDD workflow |
SPECKIT_COPILOT_MODEL | claude-opus-4.6 | Model for Copilot SDK spec generation |
SPECKIT_COMMENT_ON_ISSUE | true | Post status comments to the issue |
SPECKIT_CREATE_BRANCH | true | Create a feature branch |
SPECKIT_CREATE_PR | true | Create a pull request |
SPECKIT_AUTO_MERGE_PHASES | (empty) | Comma-separated phase names to auto-merge (e.g., plan) |
| Secret | Description |
|---|---|
COPILOT_APP_ID | App ID of the agentic-devtools-copilot-reviewer GitHub App |
COPILOT_APP_PRIVATE_KEY | PEM private key for the agentic-devtools-copilot-reviewer GitHub App. Required permissions: Pull requests: Read & Write, Contents: Read, Copilot: Read |
speckit label (or your configured trigger label)You can also trigger the workflow manually for testing:
gh workflow run speckit-issue-trigger.yml -f issue_number=123
The workflow uses labels to manage state:
speckit - Trigger label: Add this to an issue to start specification generationspeckit:processing - Specification generation in progressspeckit:phase-N - Applied to each phase's PR (N = 1–3)speckit:phase-N-complete - Applied to the issue when phase N's PR is mergedspeckit:completed - All phases completed successfullyspeckit:needs-implementation - Ready for implementation (applied after Phase 3)speckit:failed - Generation failed (check workflow logs)The repository includes an automated security scanning workflow that runs whenever code is merged to the main branch. This ensures continuous security monitoring and helps identify vulnerabilities early.
bandit, pip-audit, safetyAfter each merge to main, an issue is automatically created with:
The workflow uses labels to categorize scan results:
security - All security scan reportssecurity-scan - Identifies automated scan issuesneeds-review - Findings detected, review requiredall-clear - No security issues detectedWhen a security scan detects issues:
You can manually trigger a security scan by running:
# Install security tools
pip install bandit safety pip-audit
# Run scans
pip-audit
bandit -r agentic_devtools -c .bandit
safety scan
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.2.569 | 20 Oct 2026 | 36 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:15 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:7bde8e4a3b6bfa052c3b4baeee42ace39e1973edff69fc23609011c2b98c8c4c