Skip to content

Preview Azure area and iteration moves with rule refusals and relation impact - #42

Merged
unbraind merged 2 commits into
mainfrom
feat/move-simulator
Oct 23, 2026
Merged

unbraind merged 2 commits into
mainfrom
feat/move-simulator

Conversation

@unbraind

@unbraind unbraind commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Azure backlog moves previously required an agent to attempt a classification update to discover inherited permission denials or custom iteration rules. pm ado move-preview and the typed simulateMove SDK now return compact allowed/refused rows and direct relation scope evidence before any separate application request.

The command requires explicit linked pm IDs and one project/type. It reuses the shared project field contract, host SDK complete reads and renderer, existing batch reader, revision patch builder and same-organization relation mapper. All validation patches assert the observed revision and set validateOnly=true&bypassRules=false; no apply/save or implicit bulk-update path exists. Classification moves preserve links; relation output shows endpoint area/iteration boundaries in the scenario where all allowed rows move. Unreadable and opaque targets are explicit unknowns.

Before: moving Example\Old into Example\Release could discover an inherited deny or conditional process rule during application. After: each selected item reports allowed, permission_denied, process_rule, a stale revision or another typed refusal with a remedy, without saving changes.

Acceptance Evidence
Deterministic inherited permissions and custom iteration rules Synthetic REST project tests yield allowed/permission_denied/process_rule rows; reversing selection preserves the result; inherited source and destination denials are checked.
No implicit bulk update Explicit 1..50 unique, scope-bound links; validation-only patches, no apply flag; remote and authoritative tracker snapshots unchanged.
Bounded requests and downstream relations Maximum case: 50 rows, 200 direct links, exactly 56 requests. Relation fanout above the cap refuses; opaque/unreadable targets remain unknown.
Typed SDK, agent output and no git Public SDK types/refusals, installed JSON/TOON commands, README and SDK/CLI example; real SDK trackers with git absent from PATH and a ceiling directory.
Reuse rather than overlap Current CLI 2026.10.23 generic update and sibling Gantt scheduling have no Azure classification/ACL semantics. Reuses the shipped field-contract feature; no second crawler.

Validation:

  • npm run typecheck, npm run build, npm run build:test, npm run docstring (12 source files, 86 documented declarations), and git diff --check: pass. No standalone lint script is defined.
  • node --test --experimental-test-coverage --test-coverage-include=moves.ts test/moves.test.ts: 11/11 pass, zero skips; simulator 100% lines/branches/functions.
  • npx --no-install pm test pm-ado-move-simulator --run --progress: one linked command / 11 tests pass, zero skips.
  • Behavioral revert: changed only simulateMove to treat rejected validation responses as allowed. The permissions/rules regression failed with exit 1: the expected permission_denied and process_rule rows became allowed. Restored the function and reran the linked test successfully.
  • Full unchanged-threshold npm run release:check and bun run release:check: implementation CI passed both release gates and both Node 22/26 jobs. Each suite passed 226/226 with zero skips, in both native-coverage and statement-instrumented passes; 100/100/100/100 coverage across 8 measured source files, including 1,361/1,361 statements. Production audit: zero vulnerabilities. Final exact-head CI passed all four jobs at 463ae1a64905955aae5c1937cc9643d93a81a4fa with the same counts and coverage; this final commit only records the passing gates and releases the pm claim. The saturated host ran targeted checks only.

Real-data validation used a read-only, non-git export of the public unbraind/pm-ado tracker at 3592ce90e40331217021b053c479402642a23478. The SDK read 29 items, and all 63 authoritative files remained unchanged. The actual unlinked selection refused at zero remote requests. An explicitly synthetic Azure projection of those public identities, lifecycle states and relations produced 7 allowed rows, 6 inherited denials, 16 custom iteration-rule refusals, 8 direct relations with 5 boundary changes, 34 requests per preview and 11,057 JSON bytes. First preview: 62 ms; repeat with a git ceiling: 107 ms. Reversed-selection replay was identical; zero local or remote fixture mutations. This does not claim live Azure acceptance. Reproduction is documented in docs/move-simulator.md and test/real-data-moves.ts.

Limits: individual validation is not an atomic multi-item plan or a future authorization. Relation evidence covers direct classification boundaries, not transitive/team-board membership. Live Azure credentials were not used. No merge or release requested. Automated review skips/rate limits are missing review evidence; no human approval is claimed.

PM items:

Commits: b5112e3 (implementation and pm evidence), 463ae1a (CI receipt and claim release). pm-ado-move-simulator remains in progress and unclaimed for orchestrator verification; it was not closed.

@sourcery-ai

sourcery-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Sorry @unbraind, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 18 hours and 51 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 1e38e1a2-7f9f-4e86-ab84-6756bdd8e859
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR implements a deterministic Azure area/iteration move preview that reuses the existing contract and SDK infrastructure to validate explicit linked items through revision-bound non-saving requests, classify refusals, expose direct relation scope impact, and provide bounded CLI/SDK output with comprehensive synthetic and no-git validation evidence.

Sequence diagram for the Azure move preview validation

sequenceDiagram
    actor User
    participant CLI as move-preview CLI
    participant SDK as Host SDK
    participant Preview as simulateMove
    participant Contract as discoverProjectContract
    participant Azure as Azure DevOps

    User->>CLI: runMoveCommand
    CLI->>SDK: listAllComplete
    SDK-->>CLI: complete item snapshot
    CLI->>Preview: simulateMove
    Preview->>Contract: discoverProjectContract
    Contract-->>Preview: field contract
    Preview->>Azure: getWorkItemsReport
    Azure-->>Preview: selected items and revisions
    Preview->>Azure: getWorkItemsReport
    Azure-->>Preview: direct relation targets
    loop each selected item
        Preview->>Azure: PATCH buildUpdatePatch with validateOnly=true&bypassRules=false
        Azure-->>Preview: validation status
    end
    Preview-->>CLI: rows and preserved relation evidence
    CLI-->>User: JSON or TOON preview
Loading

Flow diagram for Azure move preview decisions

flowchart TD
    A[Explicit linked pm IDs and one destination] --> B{Selection and scope valid?}
    B -- No --> C[Whole-preview refusal with remedy]
    B -- Yes --> D[Discover shared project field contract]
    D --> E[Read selected items and direct relation targets]
    E --> F{Within item, relation, and request limits?}
    F -- No --> C
    F -- Yes --> G[Validate each item at observed revision]
    G --> H{Azure validation result}
    H -- 200 --> I[allowed row]
    H -- 401 or 403 --> J[permission_denied row]
    H -- 400 --> K[process_rule row]
    H -- 409 or 412 --> L[revision_changed row]
    H -- Other refusal --> M[Typed refusal row]
    I --> N[Compute direct relation boundaries]
    J --> N
    K --> N
    L --> N
    M --> N
    N --> O[Return preview only; links preserved and no save]
Loading

File-Level Changes

Change Details Files
Adds a bounded, read-only Azure classification move preview across the SDK and CLI.
  • Introduces typed simulateMove options, preview rows, relation evidence, refusal codes, remedies, exit codes, and request limits.
  • Validates explicit project-scoped linked IDs against complete SDK metadata and the shared field contract.
  • Reads selected items and direct neighbors in batches, then issues revision-tested validateOnly=true&bypassRules=false PATCH requests without an apply path.
  • Maps Azure responses to sanitized permission, process-rule, revision, schema, selection, and remote refusals.
  • Reports preserved direct links and before/after area/iteration scope boundaries, including unknown opaque or unreadable targets.
  • Registers ado move-preview with JSON/TOON-compatible host rendering and exports the public SDK API.
  • Updates built artifacts and package documentation examples.
moves.ts
index.ts
dist/moves.js
dist/moves.d.ts
dist/index.js
dist/index.d.ts
package.json
README.md
Adds deterministic synthetic REST coverage for inherited permissions, custom iteration rules, relation impact, safety limits, and no-write behavior.
  • Tests allowed, permission-denied, process-rule, stale-revision, schema, selection, and remote-failure outcomes.
  • Verifies request ceilings, relation fanout refusal, deterministic ordering, reversed-selection replay, and secret-free output.
  • Checks authoritative tracker immutability and absence of an implicit apply or bulk-update path.
  • Exercises the installed command and SDK through a real non-git tracker with JSON and TOON output.
  • Adds public-tracker projection validation with explicit non-live-Azure limitations and reproducibility checks.
test/fixtures/move-service.ts
test/moves.test.ts
test/real-data-moves.ts
Documents the preview contract, operational limits, SDK usage, relation semantics, and validation evidence.
  • Explains validation-only semantics, typed refusals, complete-read requirements, and explicit selection rules.
  • Documents 50-item, 200-relation, and 56-request bounds plus non-atomic and non-authorizing limitations.
  • Records synthetic and public-tracker-copy measurements and reproduction instructions.
  • Adds PM feature specification and history artifacts.
docs/move-simulator.md
.agents/pm/features/pm-ado-move-simulator.toon
.agents/pm/history/pm-ado-move-simulator.jsonl

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@unbraind unbraind left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orchestrator review (built-in Claude review agent, verified by the orchestrator; bots are not waited for since 2026-10-22):

Pre-merge review (codex gpt-6.1-sol read-only review agent + orchestrator diff check).

VERDICT: MERGE
FINDINGS:

  • none
    SUMMARY: Adds revision-checked Azure area and iteration previews with typed refusals and direct relation boundary evidence. The tests cover synthetic permissions, process rules, request limits, malformed responses and non-git CLI operation; I reviewed them without rerunning them, and live Azure acceptance remains unverified.

Orchestrator check: every PATCH goes to validateOnly=true&bypassRules=false (asserted in test/moves.test.ts:61 and :210, so a persisting request fails the suite); no private data or absolute paths in the diff; CI release gate green on npm and bun (226/226, 100% coverage).

@unbraind
unbraind merged commit 92868d2 into main Oct 23, 2026
10 checks passed
@unbraind
unbraind deleted the feat/move-simulator branch October 23, 2026 14:55
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.

1 participant