Skip to content

First real commit to the Python Azure repository - #1

Closed
dfugate wants to merge 1 commit into
Azure:masterfrom
dfugate:baseline
Closed

First real commit to the Python Azure repository#1
dfugate wants to merge 1 commit into
Azure:masterfrom
dfugate:baseline

Conversation

@dfugate

@dfugate dfugate commented May 2, 2012

Copy link
Copy Markdown
Contributor

Python Azure enlistment is essentially a clone of Node.js Azure enlistment now.

@joostdenijs joostdenijs closed this May 2, 2012
lmazuel pushed a commit that referenced this pull request Apr 13, 2016
Automatic PR from autorest
schaabs pushed a commit that referenced this pull request Jan 25, 2018
Updating http challenge headers for message protection
AutorestCI added a commit that referenced this pull request Feb 26, 2018
Merge pull request #1 from AlexanderYukhanov/more

BatchAI. Additional API changes

1. Batch AI will report suffix for stdouterr directory of the start task
2. Batch AI needs application insights resource id to be able to navigate to them in portal
AutorestCI added a commit that referenced this pull request May 2, 2018
Merge pull request #1 from abversqr/MinorUpdates

Minor updates
AutorestCI added a commit that referenced this pull request May 3, 2018
…2513)

* Generated from 0c826790271a1be2d4af5905ee0eb089b4260feb

Merge pull request #1 from abversqr/MinorUpdates

Minor updates

* Generated from 1610a74a5c49c73a546972daca1e7a43798a8cea

Merge branch 'master' into master
AutorestCI added a commit that referenced this pull request May 17, 2018
Update CognitiveService ComputerVision Swagger for new extensions (#1)

* Merged PR 17875: Add new languages

Add new languages

Also tidy up the enum definition so that AutoRest generates C# that actually compiles

* Merged PR 17942: Replace fancy quotes with plain single quotes

Make javac compile without complaint even without setting the codepage to utf-8 by dropping the gratuitous typographic quotes.

* Merged PR 17956: Rename url argument for overloaded endpoint to imageUrl

This name will become the name of the argument in Python.  Since you can used named arguments in Python, give them less ambiguous names.

* Changes to make --azure-validator run more cleanly

Errors Fixed
* XmsExamplesRequired/D5001/Documentation (7)
* XmsPathsMustOverloadPaths/R2058/SDKViolation (7)

Errors Ignored
* SecurityDefinitionsStructure/R2054/SDKViolation (1) - API Key scheme for Cognitive Services
* APIVersionPattern/R3012/ARMViolation (1) - Keeping with the Cognitive Services numbering scheme
* OperationsAPIImplementation/R3023/ARMViolation (1) - Not sure what this is

Warnings Fixed
* XmsEnumValidation/R2018/SDKViolation (1)
* DescriptionAndTitleMissing/R4000/SDKViolation (1)

Warnings Ignored
* DescriptionAndTitleMissing/R4000/SDKViolation (35) - description is contained in #ref
* EnumInsteadOfBoolean/R3018/ARMViolation (5) - fix would be a breaking change
* ListInOperationName/R1003/SDKViolation (1) - fix would be a breaking change
* LongRunningOperationsWithLongRunningExtension/R2007/SDKViolation (2) - endpoint will not ultimately yield a 200, as this extension would require
* NonApplicationJsonType/R2004/ARMViolation (15) - fix would be breaking change
* PageableOperation/R2029/SDKViolation (1) - not actually pageable
* ParameterNotDefinedInGlobalParameters/R2015/SDKViolation (1) - All our own parameters specify x-ms-parameter-location
* PostOperationIdContainsUrlVerb/R2066/SDKViolation (7) - fix would be breaking change
AutorestCI added a commit that referenced this pull request May 23, 2018
Update CognitiveService ComputerVision Swagger for new extensions (#1)

* Merged PR 17875: Add new languages

Add new languages

Also tidy up the enum definition so that AutoRest generates C# that actually compiles

* Merged PR 17942: Replace fancy quotes with plain single quotes

Make javac compile without complaint even without setting the codepage to utf-8 by dropping the gratuitous typographic quotes.

* Merged PR 17956: Rename url argument for overloaded endpoint to imageUrl

This name will become the name of the argument in Python.  Since you can used named arguments in Python, give them less ambiguous names.

* Changes to make --azure-validator run more cleanly

Errors Fixed
* XmsExamplesRequired/D5001/Documentation (7)
* XmsPathsMustOverloadPaths/R2058/SDKViolation (7)

Errors Ignored
* SecurityDefinitionsStructure/R2054/SDKViolation (1) - API Key scheme for Cognitive Services
* APIVersionPattern/R3012/ARMViolation (1) - Keeping with the Cognitive Services numbering scheme
* OperationsAPIImplementation/R3023/ARMViolation (1) - Not sure what this is

Warnings Fixed
* XmsEnumValidation/R2018/SDKViolation (1)
* DescriptionAndTitleMissing/R4000/SDKViolation (1)

Warnings Ignored
* DescriptionAndTitleMissing/R4000/SDKViolation (35) - description is contained in #ref
* EnumInsteadOfBoolean/R3018/ARMViolation (5) - fix would be a breaking change
* ListInOperationName/R1003/SDKViolation (1) - fix would be a breaking change
* LongRunningOperationsWithLongRunningExtension/R2007/SDKViolation (2) - endpoint will not ultimately yield a 200, as this extension would require
* NonApplicationJsonType/R2004/ARMViolation (15) - fix would be breaking change
* PageableOperation/R2029/SDKViolation (1) - not actually pageable
* ParameterNotDefinedInGlobalParameters/R2015/SDKViolation (1) - All our own parameters specify x-ms-parameter-location
* PostOperationIdContainsUrlVerb/R2066/SDKViolation (7) - fix would be breaking change
AutorestCI added a commit that referenced this pull request Jun 6, 2018
…2513)

* Generated from 0c826790271a1be2d4af5905ee0eb089b4260feb

Merge pull request #1 from abversqr/MinorUpdates

Minor updates

* Generated from 1610a74a5c49c73a546972daca1e7a43798a8cea

Merge branch 'master' into master
lmazuel pushed a commit that referenced this pull request Jun 6, 2018
* [AutoPR monitor/resource-manager] Added GA API version for Scheduled Query Rule (#2416)

* Generated from d183bad923d3a0a4092d21203f850db6cde9f4e9

Resolving Comments

Resolving Comments

* Generated from df40ac3bbf17ea0180dd4adff2af3094065feca0

Made SKU as top level proprty and including generic error response format

Couple of changes -
1. Made SKU as top level proprty as mentioned here - https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/resource-api-reference.md#put-resource
 2. including generic error response format

* Generated from 7578160670750a68d05f77ec8163b25bb72f391e

Minor Changes to align implementation

1. Removed SKU - Billing Model is still under discussion, hence need not to be exposed to customers.
2.  Enabled field ichanged to align with camel case.
3.  'throttleTillDate' in properties.action changed to 'throttlingInMin' to denote correct meaning  and it’s data type changed to number instead of date.
4. 'status' to be removed in properties.action from examples.
5.  'severity' made a required field in properties.action.
6. Removed Examples from original spec json

* Generated from fb180fb311d73934d0f5150f72638cc3de155ea0

Added Default Response payload in all APIs

Changes -
1. Added Default Response payload in all APIs
2. Made azNs description more clear

* Generated from fb180fb311d73934d0f5150f72638cc3de155ea0

Added Default Response payload in all APIs

Changes -
1. Added Default Response payload in all APIs
2. Made azNs description more clear

* [AutoPR monitor/resource-manager] Minor Updates - description text (#2513)

* Generated from 0c826790271a1be2d4af5905ee0eb089b4260feb

Merge pull request #1 from abversqr/MinorUpdates

Minor updates

* Generated from 1610a74a5c49c73a546972daca1e7a43798a8cea

Merge branch 'master' into master

* [AutoPR monitor/resource-manager] Add "autoMitigate" to Metric Alert API spec for 2018-03-01 (#2592)

* Generated from d5b9b4545a8d15c70d3c8318d39e2f7b43229387

AutoMitigate changes

* Generated from d5b9b4545a8d15c70d3c8318d39e2f7b43229387

AutoMitigate changes

* [AutoPR monitor/resource-manager] [Monitor] Deconflict "Action" name in MetricAlert (#2617)

* Generated from 35adc5e493c20a57e6e2cb35d87c578133d2b7a6

[Monitor] Deconflict "Action" name in MetricAlert

Generates bad SDK.

* Generated from ebfaf0bdd7f2bcf736598d8ec501f490a83d1268

Update reference to MetricAlertAction

* [AutoPR monitor/resource-manager] Adding patch support for SQR API (#2596)

* Generated from f53526896e5c001f79bd46ca892f825172b53abf

Merge branch 'master' into patchsupport

* Generated from f53526896e5c001f79bd46ca892f825172b53abf

Merge branch 'master' into patchsupport

* Generated from b37d3ace14508e3bc3f87ee29b7f2ad0b7025f67

Resolving multiple model issue

Changes - 
1. Renamed "MetricTrigger" to "LogMetricTrigger"
2. Aligned "Resources" to other specs

* Rebuild by #2460

* Auto packaging
AutorestCI added a commit that referenced this pull request Jun 21, 2018
Update CognitiveService ComputerVision Swagger for new extensions (#1)

* Merged PR 17875: Add new languages

Add new languages

Also tidy up the enum definition so that AutoRest generates C# that actually compiles

* Merged PR 17942: Replace fancy quotes with plain single quotes

Make javac compile without complaint even without setting the codepage to utf-8 by dropping the gratuitous typographic quotes.

* Merged PR 17956: Rename url argument for overloaded endpoint to imageUrl

This name will become the name of the argument in Python.  Since you can used named arguments in Python, give them less ambiguous names.

* Changes to make --azure-validator run more cleanly

Errors Fixed
* XmsExamplesRequired/D5001/Documentation (7)
* XmsPathsMustOverloadPaths/R2058/SDKViolation (7)

Errors Ignored
* SecurityDefinitionsStructure/R2054/SDKViolation (1) - API Key scheme for Cognitive Services
* APIVersionPattern/R3012/ARMViolation (1) - Keeping with the Cognitive Services numbering scheme
* OperationsAPIImplementation/R3023/ARMViolation (1) - Not sure what this is

Warnings Fixed
* XmsEnumValidation/R2018/SDKViolation (1)
* DescriptionAndTitleMissing/R4000/SDKViolation (1)

Warnings Ignored
* DescriptionAndTitleMissing/R4000/SDKViolation (35) - description is contained in #ref
* EnumInsteadOfBoolean/R3018/ARMViolation (5) - fix would be a breaking change
* ListInOperationName/R1003/SDKViolation (1) - fix would be a breaking change
* LongRunningOperationsWithLongRunningExtension/R2007/SDKViolation (2) - endpoint will not ultimately yield a 200, as this extension would require
* NonApplicationJsonType/R2004/ARMViolation (15) - fix would be breaking change
* PageableOperation/R2029/SDKViolation (1) - not actually pageable
* ParameterNotDefinedInGlobalParameters/R2015/SDKViolation (1) - All our own parameters specify x-ms-parameter-location
* PostOperationIdContainsUrlVerb/R2066/SDKViolation (7) - fix would be breaking change
lmazuel pushed a commit that referenced this pull request Jun 22, 2018
* Generated from 984c12a568b2dd36acb521eb3b1c00fbd5b42995 (#2575)

Update CognitiveService ComputerVision Swagger for new extensions (#1)

* Merged PR 17875: Add new languages

Add new languages

Also tidy up the enum definition so that AutoRest generates C# that actually compiles

* Merged PR 17942: Replace fancy quotes with plain single quotes

Make javac compile without complaint even without setting the codepage to utf-8 by dropping the gratuitous typographic quotes.

* Merged PR 17956: Rename url argument for overloaded endpoint to imageUrl

This name will become the name of the argument in Python.  Since you can used named arguments in Python, give them less ambiguous names.

* Changes to make --azure-validator run more cleanly

Errors Fixed
* XmsExamplesRequired/D5001/Documentation (7)
* XmsPathsMustOverloadPaths/R2058/SDKViolation (7)

Errors Ignored
* SecurityDefinitionsStructure/R2054/SDKViolation (1) - API Key scheme for Cognitive Services
* APIVersionPattern/R3012/ARMViolation (1) - Keeping with the Cognitive Services numbering scheme
* OperationsAPIImplementation/R3023/ARMViolation (1) - Not sure what this is

Warnings Fixed
* XmsEnumValidation/R2018/SDKViolation (1)
* DescriptionAndTitleMissing/R4000/SDKViolation (1)

Warnings Ignored
* DescriptionAndTitleMissing/R4000/SDKViolation (35) - description is contained in #ref
* EnumInsteadOfBoolean/R3018/ARMViolation (5) - fix would be a breaking change
* ListInOperationName/R1003/SDKViolation (1) - fix would be a breaking change
* LongRunningOperationsWithLongRunningExtension/R2007/SDKViolation (2) - endpoint will not ultimately yield a 200, as this extension would require
* NonApplicationJsonType/R2004/ARMViolation (15) - fix would be breaking change
* PageableOperation/R2029/SDKViolation (1) - not actually pageable
* ParameterNotDefinedInGlobalParameters/R2015/SDKViolation (1) - All our own parameters specify x-ms-parameter-location
* PostOperationIdContainsUrlVerb/R2066/SDKViolation (7) - fix would be breaking change

* Generated from bd6c66b615b94480a1458dde3a8bc42f3a689548 (#2645)

ComputerVision - collection of fixes

* fix ocr language parameter to fix [bug](Azure/azure-sdk-for-net#4083)
* language parameter missing for /tag path
* language parameter missing for /models/*/analyze path
* make /models/*/analyze return a more generic type
* add specific types for /models/*/analyze to return for current models

* Generated from b35c48945774ac7be9bf0fa05e19c0890141bb3d (#2731)

Add Spanish as an option as ServiceLanguage for ComputerVision.

* [AutoPR cognitiveservices/data-plane/ComputerVision] Update CognitiveService ComputerVision API to V2 (#2747)

* Generated from c2567da015994dac3301f495b6c5011d28ceaffe

Add post-processing directive to swap argument order for RecognizeText to position the url argument ahead of the mode argument.

autorest does not generate the intended order, so we add a post-processing directive,
for each target language,

* Generated from 973322cfd6ec2ced60a732f53b5318ceded5de7b

Fix validation errors

* Generated from 70efe042d607cbd973734e432da395ed35191a03

Add Spanish support for ServiceLanguage

This is for parity with V1.

* Generated from 6492fb4e04a3e5d7330ceccbb9f67e2a839e2290 (#2775)

ComputerVision add tag.hint

Hints provided additional info for whole-image analysis tags.
This PR is to make the Swagger match the service behavior.

* Update version.py

* ComputerVision 0.2.0 packaging
AutorestCI added a commit that referenced this pull request Sep 11, 2018
Merge pull request #1 from hosunmsft/add_dop_percent_to_ADLA_job_api

Support degreeOfParallelismPercent in DataLakeAnalytic jobs
AutorestCI added a commit that referenced this pull request Sep 13, 2018
* Generated from cc3a2ac1934c906c367746bfeac7aa3af341ac40

Merge pull request #1 from hosunmsft/add_dop_percent_to_ADLA_job_api

Support degreeOfParallelismPercent in DataLakeAnalytic jobs

* Packaging update of azure-mgmt-datalake-analytics
AutorestCI added a commit that referenced this pull request Sep 20, 2018
Merge pull request #1 from jmelvinwork/frontdoor-public-preview

Front Door public preview
AutorestCI added a commit that referenced this pull request Oct 29, 2018
Merge pull request #1 from EvgenyAgafonchikov/fix-lb

Fixed line endings, specs, examples
AutorestCI added a commit that referenced this pull request Oct 29, 2018
…bound rules (#3687)

* Generated from fb767531a15f75017f43f44004a2aa75c1b13b9f

fix failures

* Generated from a9023fbd65049681b0ccc49d42a1c4276b0cd159

Merge pull request #1 from EvgenyAgafonchikov/fix-lb

Fixed line endings, specs, examples
lmazuel pushed a commit that referenced this pull request Nov 6, 2018
* Generated from bd2aca0

Update ADHybridHealthService.json (#3874)

* Generated from 4b3ae81daaddc6079ec4a6a8ebeebccc019703e6

Updated NetworkConfigurationDiagnostic API + example (#3905)

* Generated from c90c5d14e7b0b169a8cde763860d15aa48a0d37c (#3395)

address the comments

* Generated from 26fc76cf7c2ed2ae5289bd4946513351880d32ff

add customer error spec for Application Gateway (#3985)

* add customer error spec for Application Gateway

* fix property name issue

* [AutoPR network/resource-manager] add customer error spec for Application Gateway (#3409)

* Generated from d9a3af34891cc703ecc3ba298fc737d6cc3e0fc0

add customer error spec for Application Gateway

* Generated from 26299b453a6b2f99683899a78c4c302d39b7de03

fix property name issue

* Generated from 19e41e2e7bb38120b813ad2314dc7c4f422b48c4 (#3417)

Add ICMP to the list of supported protocols

* Generated from ef5d8181e1a9f148a35d1b4467af2427a0afa29d

Merge remote-tracking branch 'origin/master' into network-october-release

* Packaging update of azure-mgmt-network

* Packaging update of azure-mgmt-adhybridhealthservice

* Generated from 7d9b9a991b92bfdbc31be3bf5fd2bd16bbb742a1 (#3478)

change appgw custom error status code enum and fix a typo of customErrorConfiguration

* Generated from 758c143eae019925ae9e021fbcd6821af918d000

Add ExpressRoutePort swagger (#4104)

* Add ExpressRoutePort details to readme.md

* ExpressRoutePort swagger

* Refer SubscriptionIdParameter and ApiVersionParameter from network.json

* Generated from b232daf214b1a03e32b14427be20bbca4ac805ac (#3509)

ExpressRoutePort swagger

* Generated from 6c4312edb758be23c2bdd7f8c2da0b8b76541187

Cherry pick NRP's changes from master to October branch (#4251)

* Remove error code from swagger (#4103)

* Modifying example templates : enabling Ipv6 support for Private Peering (#4232)

* Modifying example templates : enabling Ipv6 support for Private Peering

* Resolving oav validation error

* [AutoPR network/resource-manager] Cherry pick NRP's changes from master to October branch (#3632)

* Generated from 9ef9c433f66560956a610961c0e2a5ec70360064

Modifying example templates : enabling Ipv6 support for Private Peering (#4232)

* Modifying example templates : enabling Ipv6 support for Private Peering

* Resolving oav validation error

* Packaging update of azure-mgmt-network

* Packaging update of azure-mgmt-adhybridhealthservice

* Generated from e8f2b491e5b1732d9e57cdf9ddd16907ba04920e

Changes to add operation id for outbound rules (#4320)

* Changes to add operation id for outbound rules

* Changes to make outbound rule similar to load balancing rule

* fix failures - add example json files

* fix failures

* Fixed line endings, specs, examples

* [AutoPR network/resource-manager] Changes to add operation id for outbound rules (#3687)

* Generated from fb767531a15f75017f43f44004a2aa75c1b13b9f

fix failures

* Generated from a9023fbd65049681b0ccc49d42a1c4276b0cd159

Merge pull request #1 from EvgenyAgafonchikov/fix-lb

Fixed line endings, specs, examples

* [AutoPR network/resource-manager] Change one parameter (#3700)

* Generated from 9392c40ae5bf6575a8fdf47d0609226fdd8da689

Change one parameter

* Generated from 084957762078dc07cce7c40e0d5358081f090e2a

Change parameter in most recent version

* Generated from 1f46c7babbbcc3379f21c6f5e3d16f693fe23111

Fix example

* Generated from d0417082c41cfae8f0234ee02fe32b506bf4e605

New SKU for ER (#4342)
lmazuel pushed a commit that referenced this pull request Nov 8, 2018
* [AutoPR network/resource-manager] Remove error code from swagger (#3507)

* Generated from 82c4e9010292ed02c88fd64f6d3b7e17bd417eb9

Remove error code from swagger

* Packaging update of azure-mgmt-network

* [AutoPR network/resource-manager] Move parameter to keep order in SDK (#3731)

* Generated from 911ebf46a4a178cdcc6aaa9695f6792f4c64ab89

Move parameter to keep order in SDK

* Packaging update of azure-mgmt-network

* [AutoPR network/resource-manager] Network october release (#3463)

* Generated from bd2aca0

Update ADHybridHealthService.json (#3874)

* Generated from 4b3ae81daaddc6079ec4a6a8ebeebccc019703e6

Updated NetworkConfigurationDiagnostic API + example (#3905)

* Generated from c90c5d14e7b0b169a8cde763860d15aa48a0d37c (#3395)

address the comments

* Generated from 26fc76cf7c2ed2ae5289bd4946513351880d32ff

add customer error spec for Application Gateway (#3985)

* add customer error spec for Application Gateway

* fix property name issue

* [AutoPR network/resource-manager] add customer error spec for Application Gateway (#3409)

* Generated from d9a3af34891cc703ecc3ba298fc737d6cc3e0fc0

add customer error spec for Application Gateway

* Generated from 26299b453a6b2f99683899a78c4c302d39b7de03

fix property name issue

* Generated from 19e41e2e7bb38120b813ad2314dc7c4f422b48c4 (#3417)

Add ICMP to the list of supported protocols

* Generated from ef5d8181e1a9f148a35d1b4467af2427a0afa29d

Merge remote-tracking branch 'origin/master' into network-october-release

* Packaging update of azure-mgmt-network

* Packaging update of azure-mgmt-adhybridhealthservice

* Generated from 7d9b9a991b92bfdbc31be3bf5fd2bd16bbb742a1 (#3478)

change appgw custom error status code enum and fix a typo of customErrorConfiguration

* Generated from 758c143eae019925ae9e021fbcd6821af918d000

Add ExpressRoutePort swagger (#4104)

* Add ExpressRoutePort details to readme.md

* ExpressRoutePort swagger

* Refer SubscriptionIdParameter and ApiVersionParameter from network.json

* Generated from b232daf214b1a03e32b14427be20bbca4ac805ac (#3509)

ExpressRoutePort swagger

* Generated from 6c4312edb758be23c2bdd7f8c2da0b8b76541187

Cherry pick NRP's changes from master to October branch (#4251)

* Remove error code from swagger (#4103)

* Modifying example templates : enabling Ipv6 support for Private Peering (#4232)

* Modifying example templates : enabling Ipv6 support for Private Peering

* Resolving oav validation error

* [AutoPR network/resource-manager] Cherry pick NRP's changes from master to October branch (#3632)

* Generated from 9ef9c433f66560956a610961c0e2a5ec70360064

Modifying example templates : enabling Ipv6 support for Private Peering (#4232)

* Modifying example templates : enabling Ipv6 support for Private Peering

* Resolving oav validation error

* Packaging update of azure-mgmt-network

* Packaging update of azure-mgmt-adhybridhealthservice

* Generated from e8f2b491e5b1732d9e57cdf9ddd16907ba04920e

Changes to add operation id for outbound rules (#4320)

* Changes to add operation id for outbound rules

* Changes to make outbound rule similar to load balancing rule

* fix failures - add example json files

* fix failures

* Fixed line endings, specs, examples

* [AutoPR network/resource-manager] Changes to add operation id for outbound rules (#3687)

* Generated from fb767531a15f75017f43f44004a2aa75c1b13b9f

fix failures

* Generated from a9023fbd65049681b0ccc49d42a1c4276b0cd159

Merge pull request #1 from EvgenyAgafonchikov/fix-lb

Fixed line endings, specs, examples

* [AutoPR network/resource-manager] Change one parameter (#3700)

* Generated from 9392c40ae5bf6575a8fdf47d0609226fdd8da689

Change one parameter

* Generated from 084957762078dc07cce7c40e0d5358081f090e2a

Change parameter in most recent version

* Generated from 1f46c7babbbcc3379f21c6f5e3d16f693fe23111

Fix example

* Generated from d0417082c41cfae8f0234ee02fe32b506bf4e605

New SKU for ER (#4342)

* Packaging update of azure-mgmt-network

* Rebuild by #3617

* Remove azure-mgmt-adhybridhealthservice by mistake on Network service PR

* Network 2.3.0
AutorestCI added a commit that referenced this pull request Nov 20, 2018
Merge pull request #1 from leonardbf/netapp-api-update-public

NFSAAS-1505 minor update and validation fixes
AutorestCI added a commit that referenced this pull request Nov 21, 2018
…n fixes (#3839)

* Generated from 4535ffbe9b0b3be960171b9c8efcdb042f34ce64

Merge pull request #1 from leonardbf/netapp-api-update-public

NFSAAS-1505 minor update and validation fixes

* Packaging update of azure-mgmt-netapp
AutorestCI added a commit that referenced this pull request Nov 25, 2018
Merge pull request #1 from omarelhariry/a-moghan/PublishingResponses

Adding Publishing To Regions Status
AutorestCI added a commit that referenced this pull request Dec 11, 2018
Fixes for:

Issue #1 : Azure/azure-rest-api-specs#4576 (comment)

Typo in the DeltaOperationType Enum.

Issue #2 : Azure/azure-rest-api-specs#4844 (comment)

GlobalAdmins list is marked as an object, while it's an array.
AutorestCI added a commit that referenced this pull request Dec 13, 2018
…ounts APIs (#3869)

* Generated from 431fadac7b30b7c33b9fa6468874fce839869345

fixing build errors

* Packaging update of azure-cognitiveservices-language-luis

* Generated from 82cee8e19ad81e9d82d712cfabad1649b91b619a

Merge pull request #1 from omarelhariry/a-moghan/PublishingResponses

Adding Publishing To Regions Status

* Generated from 23a7c077da0b751b8ad2b246d8da041d0906f90d

Fixing formats

* Generated from 4289fc27afed08636bf27abb57ace4a1ff69b7ee

Fixing OAV errors

* Generated from 3b62ef631bbcf684da8597627f22d1869bb37c7d

Merge pull request #2 from omarelhariry/kayousef/Dispatch_APIs

Adding dispatch APIs

* Generated from 4289fc27afed08636bf27abb57ace4a1ff69b7ee

Fixing OAV errors

* Generated from c7d11c54fe4f164073a570f2dba2510ddbf91c76

Add application-json as a 2nd prdocues format for packaging APIs, to describe the error responses

* Generated from b8ee038af90c620395c27635c989a3a6364335a4

Updating operation ids

* Generated from 32e19a3f178eab8d32f3fd79316bbaf7569ca7c8

fix oav and remove error responses

* Update sdk_packaging.toml

* Packaging update of azure-cognitiveservices-language-luis
AutorestCI added a commit that referenced this pull request Dec 14, 2018
Fixes for:

Issue #1 : Azure/azure-rest-api-specs#4576 (comment)

Typo in the DeltaOperationType Enum.

Issue #2 : Azure/azure-rest-api-specs#4844 (comment)

GlobalAdmins list is marked as an object, while it's an array.
AutorestCI added a commit that referenced this pull request Dec 14, 2018
…view request for Microsoft.ADHybridHealthService to add version 2014-01-01 (#4040)

* Generated from 5269a33bc4e48e336b7eacdba01c999953f42013

Fixes for:

Issue #1 : Azure/azure-rest-api-specs#4576 (comment)

Typo in the DeltaOperationType Enum.

Issue #2 : Azure/azure-rest-api-specs#4844 (comment)

GlobalAdmins list is marked as an object, while it's an array.

* Generated from 5269a33bc4e48e336b7eacdba01c999953f42013

Fixes for:

Issue #1 : Azure/azure-rest-api-specs#4576 (comment)

Typo in the DeltaOperationType Enum.

Issue #2 : Azure/azure-rest-api-specs#4844 (comment)

GlobalAdmins list is marked as an object, while it's an array.
lmazuel pushed a commit that referenced this pull request Jan 3, 2019
* [AutoPR netapp/resource-manager] Microsoft.NetApp first version (#3144)

* Generated from c82f7e0779efda2a9a97a99664679711ce8d7e73

Microsoft.NetApp first version

* Generated from 51268a3aa9892dabce143e347f225bf74be4cc49

Addressing pullrequest comments

* [AutoPR netapp/resource-manager] NetApp adding subnetId to volume properties (#3321)

* Generated from 37a648d4d8bbc6b77cc7cbc25b55f95f0b65b9fa

NetApp adding subnetId to volume properties

* Packaging update of azure-mgmt-netapp

* [AutoPR netapp/resource-manager] NetApp RP minor update and validation fixes (#3839)

* Generated from 4535ffbe9b0b3be960171b9c8efcdb042f34ce64

Merge pull request #1 from leonardbf/netapp-api-update-public

NFSAAS-1505 minor update and validation fixes

* Packaging update of azure-mgmt-netapp

* Generated from 964e181cc1542e5bec928cbb27ef3d144f24b71e (#3956)

typo: netapp/resource-manager/Microsoft.NetApp

- possiblly -> possibly
- targets's -> target's

* [AutoPR netapp/resource-manager] Resource and property changes (#3992)

* Generated from 164da1fe5b4cdf8db0afd9f55a08ab523e1c3f0e

Merge pull request #4 from leonardbf/netapp-api-update-public

NFSAAS-1505 resource and property changes

* Generated from 5892e13494715eb9a24653407544e23ddb00efc4

Merge pull request #5 from leonardbf/netapp-api-update-public

NFSAAS-1505 status codes

* Generated from 4f47c60ec82a1eefc22a7524b7dff99624499d67 (#4046)

Merge pull request #9 from leonardbf/mt-sc-update

NFSAAS-1644 remove mt get add status for put

* Update sdk_packaging.toml

* Packaging update of azure-mgmt-netapp

* Update version.py

* Update HISTORY.rst
AutorestCI added a commit that referenced this pull request Mar 12, 2019
Merge pull request #1 from feiyushi/feshi-imagebuilder-preview2019

operation_id: plural forms
w-javed added a commit that referenced this pull request Jun 30, 2025
slister1001 added a commit that referenced this pull request Apr 21, 2026
…6444)

* [evaluation] Fix multi-turn red team attacks broken by PyRIT 0.11

PyRIT 0.11 introduced two bugs in RedTeamingAttack that prevent multi-turn
red team attacks from running:

1. RedTeamingAttack._setup_async() adds prepended_conversation messages to
   the adversarial chat memory BEFORE calling set_system_prompt(). The
   default PromptChatTarget.set_system_prompt then raises
   `RuntimeError: Conversation already exists, system prompt needs to be
   set at the beginning`. CrescendoAttack avoids this by embedding context
   in the system prompt template, so it does not regress.

2. RedTeamingAttack._generate_next_prompt_async returns
   context.next_message directly without calling .duplicate_message().
   PromptNormalizer.send_prompt_async then deepcopies the message but
   preserves the MessagePiece id, so re-inserting the same id into memory
   raises sqlite3.IntegrityError: UNIQUE constraint failed:
   PromptMemoryEntries.id. Notably PromptSendingAttack._build_message
   uses .duplicate_message() — the intended pattern.

Together these two bugs cause Foundry red team eval runs with the
MultiTurn (and other RedTeamingAttack-based) strategies to silently fail
and surface only baseline results in the UI.

Workaround applied at the SDK level to avoid bumping PyRIT:

- Bug #1: instance-scoped patch of set_system_prompt on the adversarial
  chat target. The patched version inserts the system message into memory
  via add_message_to_memory when prior messages exist, instead of raising.
  Scope is limited to the AzureRAIServiceTarget instance created by the
  scan, so no global PyRIT class is mutated.

- Bug #2: module-level monkey-patch of
  RedTeamingAttack._generate_next_prompt_async that wraps the returned
  message in .duplicate_message(). The patch is idempotent and applied
  once at SDK module load.

Verified locally with both a callback target and an Azure OpenAI model
target (gpt-4o-mini): multi-turn attacks now execute the full
conversation loop and produce expected results in
violence_multi_turn_results.jsonl and final_results.json.

Work item: https://msdata.visualstudio.com/Vienna/_workitems/edit/5166253

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update CHANGELOG for multi-turn PyRIT fix

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Move changelog entry to 1.16.6 and bump version

1.16.5 is already released (2026-04-08). Put this fix under 1.16.6
(Unreleased) to match in-flight version increment PR #46222.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address Copilot review: version-guard PyRIT 0.11 patches and add unit tests

- Add _is_affected_pyrit_version() check; both patches early-return for pyrit
  versions other than 0.11.x so a future fix or signature change isn't masked.
- Add tests/unittests/test_redteam/test_pyrit_workarounds.py covering:
  * patch is applied (marker on RedTeamingAttack._generate_next_prompt_async)
  * patched method calls .duplicate_message() on the returned message
  * None pass-through (no AttributeError)
  * idempotent re-application (no double-wrapping)

The set_system_prompt instance patch remains covered by the local E2E reproductions
(callback target + gpt-4o-mini); unit testing it would require constructing an
AzureRAIServiceTarget with full memory plumbing and offers little value beyond E2E.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Strengthen multi-turn E2E test + re-record on PyRIT 0.11

Previous assertion (len(conversation) >= 2) was too weak to catch the PyRIT 0.11 set_system_prompt bug — any attack silently dropped from attack_details still passed. Now require multi_turn attack present + >= 4 messages per multi-turn conversation.

Re-recorded against patched SDK so playback validates the fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fafhrd91 pushed a commit to fafhrd91/azure-sdk-for-python that referenced this pull request Apr 28, 2026
…ure#46444)

* [evaluation] Fix multi-turn red team attacks broken by PyRIT 0.11

PyRIT 0.11 introduced two bugs in RedTeamingAttack that prevent multi-turn
red team attacks from running:

1. RedTeamingAttack._setup_async() adds prepended_conversation messages to
   the adversarial chat memory BEFORE calling set_system_prompt(). The
   default PromptChatTarget.set_system_prompt then raises
   `RuntimeError: Conversation already exists, system prompt needs to be
   set at the beginning`. CrescendoAttack avoids this by embedding context
   in the system prompt template, so it does not regress.

2. RedTeamingAttack._generate_next_prompt_async returns
   context.next_message directly without calling .duplicate_message().
   PromptNormalizer.send_prompt_async then deepcopies the message but
   preserves the MessagePiece id, so re-inserting the same id into memory
   raises sqlite3.IntegrityError: UNIQUE constraint failed:
   PromptMemoryEntries.id. Notably PromptSendingAttack._build_message
   uses .duplicate_message() — the intended pattern.

Together these two bugs cause Foundry red team eval runs with the
MultiTurn (and other RedTeamingAttack-based) strategies to silently fail
and surface only baseline results in the UI.

Workaround applied at the SDK level to avoid bumping PyRIT:

- Bug Azure#1: instance-scoped patch of set_system_prompt on the adversarial
  chat target. The patched version inserts the system message into memory
  via add_message_to_memory when prior messages exist, instead of raising.
  Scope is limited to the AzureRAIServiceTarget instance created by the
  scan, so no global PyRIT class is mutated.

- Bug Azure#2: module-level monkey-patch of
  RedTeamingAttack._generate_next_prompt_async that wraps the returned
  message in .duplicate_message(). The patch is idempotent and applied
  once at SDK module load.

Verified locally with both a callback target and an Azure OpenAI model
target (gpt-4o-mini): multi-turn attacks now execute the full
conversation loop and produce expected results in
violence_multi_turn_results.jsonl and final_results.json.

Work item: https://msdata.visualstudio.com/Vienna/_workitems/edit/5166253

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update CHANGELOG for multi-turn PyRIT fix

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Move changelog entry to 1.16.6 and bump version

1.16.5 is already released (2026-04-08). Put this fix under 1.16.6
(Unreleased) to match in-flight version increment PR Azure#46222.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address Copilot review: version-guard PyRIT 0.11 patches and add unit tests

- Add _is_affected_pyrit_version() check; both patches early-return for pyrit
  versions other than 0.11.x so a future fix or signature change isn't masked.
- Add tests/unittests/test_redteam/test_pyrit_workarounds.py covering:
  * patch is applied (marker on RedTeamingAttack._generate_next_prompt_async)
  * patched method calls .duplicate_message() on the returned message
  * None pass-through (no AttributeError)
  * idempotent re-application (no double-wrapping)

The set_system_prompt instance patch remains covered by the local E2E reproductions
(callback target + gpt-4o-mini); unit testing it would require constructing an
AzureRAIServiceTarget with full memory plumbing and offers little value beyond E2E.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Strengthen multi-turn E2E test + re-record on PyRIT 0.11

Previous assertion (len(conversation) >= 2) was too weak to catch the PyRIT 0.11 set_system_prompt bug — any attack silently dropped from attack_details still passed. Now require multi_turn attack present + >= 4 messages per multi-turn conversation.

Re-recorded against patched SDK so playback validates the fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@xinlian12 xinlian12 mentioned this pull request May 4, 2026
RaviPidaparthi added a commit to RaviPidaparthi/azure-sdk-for-python that referenced this pull request Jun 2, 2026
Six checks land RED until Phase 7 GREEN creates docs/durable-task-guide.md:
- test_every_public_symbol_is_referenced_in_guide (FR-024 Azure#1)
- test_pr_blocking_failure_mode_for_undocumented_symbol (FR-025)
- test_removed_names_absent_from_guide (FR-024 Azure#2)
- test_required_sections_present_in_order (FR-024 Azure#3)
- test_canonical_statements_present (FR-024 Azure#4)
- test_no_internal_contradictions (FR-024 Azure#5)

The T058 regression sub-test (test_pre_consolidation_state_would_have_failed)
already passes — it proves the same checks bite when run against a synthetic
pre-consolidation 'guide' that contains retired names, missing sections,
and undocumented symbols.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RaviPidaparthi pushed a commit to RaviPidaparthi/azure-sdk-for-python that referenced this pull request Jun 2, 2026
…ddressed)

Address the BLOCKING and HIGH findings from the T122 final holistic
code review.

BLOCKING fixes:

Azure#1 + Azure#2 (US7 honest accounting):
- tasks.md: T086-T093 marked [~] (deferred) to reflect that the
  per-turn / wall-clock / durable timeout semantic with persisted
  _turn_started_at is the spec target but not wired end-to-end.
- durable-task-guide.md §Timeout rewritten to honestly describe the
  current cooperative-only watchdog plus the spec target; removed
  the misleading 'remaining ≈ 2 seconds (30 - 28)' worked example
  that promised behavior the code does not provide.

Azure#3 (FR-002 Layer 3 / inline reclaim wired):
- _decorator.py::_lifecycle_start_inner: in_progress branch now
  consults _lease_is_dead (from _manager) instead of the legacy
  _in_progress_was_abandoned_legacy wall-clock heuristic. On dead
  lease: inline _reclaim_one CAS reclaim, then re-enter as
  recovered. On live-elsewhere (foreign owner): TaskConflictError
  per FR-008/Invariant 1. The legacy helper is kept as a no-op-
  returning shim only so older monkey-patches don't AttributeError.
- _manager.py::_lease_is_dead: fixed to read task_info.lease.owner
  (LeaseInfo nested object) instead of the non-existent
  task_info.lease_owner attribute. Foreign-owner records now
  correctly return False (not dead — caller observes the live-
  elsewhere conflict shape per FR-004a).

Azure#4 (SC-014 / TaskTerminated strict removal):
- _exceptions.py: TaskTerminated class fully deleted (was retained
  as transitional internal-only after Phase 9).
- __init__.py: TaskTerminated import line deleted — importing it
  from the public package now raises ImportError per SC-014.
- test_cancellation_timeout.py:
  test_task_terminated_removed_from_durable_all strengthened to
  assert ImportError + hasattr-False, not just __all__ absence.

HIGH fixes:

Azure#5 (is_superseded property removed):
- _result.py: is_superseded compatibility shim deleted entirely
  per FR-010 strict-removal contract.
- test_steering.py: 2 tests updated to assert absence of
  is_superseded via not hasattr().

Azure#7 (_steering['generation'] internal field removed):
- _decorator.py::_append_steering_input: removed
  steering['generation'] = 0 initialisation per gap-list
  §FR-021-internal.
- _manager.py::_try_drain_steering: removed
  steering['generation'] = old_generation + 1 increment. The drain
  transition IS the generation advance; no separate counter needed.
- Log line updated to remove generation references.

Test scaffolding updates:
- test_lifecycle.py::test_run_in_progress_not_stale_raises +
  test_start_follows_lifecycle_rules: seed records with foreign
  lease_owner ('other-agent|session:other-session') to exercise
  the live-elsewhere shape under the new FR-004 lease-state-based
  conflict path.

Verification:
- Full durable suite: 338 passed, 1 skipped (was 338+1 skipped;
  no regressions; deeper FR-004-based detection of dead-elsewhere
  records works against both LocalFileTaskProvider tests and the
  BindingMismatchProvider eviction tests).
- TaskTerminated importability now raises ImportError as the spec
  requires.
- is_superseded property is gone from the public class surface.

Remaining HIGH/MEDIUM items not addressed in this commit (tracked in
conformance-gap-list.md §7 for follow-up):
- HIGH Azure#6: residual terminate plumbing (slots, kwargs) in
  _ActiveTask/_run.py/_manager.py — cosmetic dead code that does not
  affect behavior.
- HIGH Azure#8: dedicated 4-cell sweep tests (SC-006/SC-008/SC-009/SC-010)
  — individual scenarios are covered by the per-area tests in place;
  the explicit parametrized sweeps are stylistic.
- HIGH Azure#9: T094(b) recovered-re-entry test + T096 queued-input
  preservation test — the behavior IS implemented (FR-027 e clause
  preserves _steering[pending_inputs] by not touching it); the
  explicit test cases are deferred.
- MEDIUM Azure#10-12: gap-list internal placeholders, lease-renewal
  eviction wiring tightening, tasks.md [~] convention rollout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RaviPidaparthi added a commit that referenced this pull request Jun 3, 2026
…renderer + add client wall-clock

Core branch now auto-enables HostedTaskProvider in hosted environments,
so this demo no longer needs AGENTSERVER_TASK_API_ENABLED. Likewise,
wheels are now built centrally via sdk/agentserver/scripts/build-wheels.sh
and staged into the docker build context — no committed wheels.

CHANGES

  agent.yaml
    - Drop AGENTSERVER_TASK_API_ENABLED (auto-on in hosted).
    - Tighten the cooldown comment (no behavior change).

  build.sh
    - Delegate to the central sdk/agentserver/scripts/build-wheels.sh.
    - Stage wheels into src/durable-research-agent/wheels/ (gitignored
      docker-build dir), so the Dockerfile's COPY wheels/ ... still
      finds them at build time.
    - Per-sample build.sh is now a thin staging wrapper; no per-sample
      duplication of the build logic.

  src/durable-research-agent/wheels/*.whl  (deleted)
    - Wheels are no longer committed. They're regenerated on demand.

  app.py — fix file_replay SSE double-encoding
    - FileStreamHandler.put writes json.dumps(item)+'\n', where item
      is itself a JSON string from ctx.stream(json.dumps({...})). The
      live_stream path correctly reads from the in-memory queue (which
      holds the original string). The file_replay path read the disk
      line via json.loads, then RE-WRAPPED with json.dumps before
      embedding in 'data: ...\n\n' — producing
        data: "{\"type\": \"...\"}"
      which the client rendered as '[unknown event] "{\"...\"}"'.
    - Decode once, embed the raw JSON string directly. Also add an
      isinstance check before the __done__ key lookup (the decoded
      value is a string for normal events).
    - Update crash-handler 202 response message + docstring to reflect
      validated behavior (nanny restores ~1 min, no ingress needed).

  demo-client.sh
    - Add _now_utc() helper and prefix every block-style event with
      '[HH:MM:SSZ]' — the client's local UTC wall-clock at render
      time — so users can compare against server_time= (server-side
      UTC) and uptime= (server process seconds-since-boot) for a
      clear timeline of phases vs lease renewals vs recoveries.
    - Update header comment: drop the wrong '~5-10 min' nanny restore
      and the wrong 'lease renewal pings readiness' phrasing; reflect
      the validated 30s lease cadence and ~1 min nanny window.
    - Three-terminal usage example: ~33 min (not 45) wall-time per
      run; nanny restores ~1 min after crash (no need to send any
      ingress to trigger recovery).
    - Crash-command output text: nanny brings container back on its
      own, no client action required.

  README.md
    - Capability #1 reframed: lease keep-alive proven end-to-end
      (e2e-tests-westus2), 33-min runs with zero client ingress.
    - Capability #2 reframed: nanny restores within ~1 min (43s
      measured) without any client ingress; recover-on-reconnect was
      a misread of the old behavior.
    - Deploy section: build.sh now delegates to the central script;
      points at USING_PRE_RELEASE_WHEELS.md for the wheel workflow.
    - Crash command row in the command-reference table: clearer wording
      around nanny-driven recovery.
    - Env-var table: drop AGENTSERVER_TASK_API_ENABLED row (gone);
      add a paragraph clarifying that hosted/local provider selection
      is automatic.
    - File-structure section: build.sh and wheels/ entries reflect the
      new layout; add pointer to the wheel-distribution doc.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RaviPidaparthi added a commit that referenced this pull request Jun 18, 2026
…H + 1 MEDIUM)

Code-review agent flagged 8 findings against the Phase 2 work; this
commit lands the fixes. Full core suite: 699 pass / 10 skip / 0 fail
(was 689 / 10 / 0 — net +10 tests added).

### BLOCKING #1 — title-value gating removed
_local_provider.py had ~9 sites gating validation on `task.title == 't'`
which made spec-020 tests GREEN while real-world callers (any title
other than 't') bypassed the new rules. Removed every gate; rules now
enforced unconditionally. Updated pre-existing tests
(test_split_brain_eviction, test_cancellation_timeout, test_source,
test_steering, test_lifecycle, conftest.py) to supply spec-compliant
inputs (valid task ids, required title/agent_name/session_id, valid
status transitions) — legitimate test updates, not implementation
backdoors.

### BLOCKING #2 — _HostedConflict leak from TaskRun.delete()
_run.py:188-193's except-Exception block re-raised _HostedConflict
to developer code. Added _translate_hosted_conflict-based handler
so the developer sees TaskConflictError / TaskPreconditionFailed.

### BLOCKING #3 — A2 'title required' not enforced for title=None
Dropped the `if request.title is not None:` guard; validator
handles None properly. Same fix audit applied to all required-field
validations.

### HIGH #4 — Hosted update() now serializes clear_attachments
_client.py update() body now includes "attachments": null when
patch.clear_attachments=True; rejects the mutual-exclusion case
(clear_attachments=True AND attachments={...}) to mirror local.

### HIGH #5 — validate_lease_params rejection no longer swallowed
Deleted the try/except _HostedConflict that only re-raised for
title=='t'; the exception propagates as intended.

### HIGH #6 — Real B3 immutable-fields coverage
test_b3_immutable_fields_rejected was a no-op placeholder. Replaced
with a real test on the underlying _reject_immutable_patch_fields
function (defense-in-depth check that fires on raw-dict patches
containing immutable fields) — typed-API surface enforces the same
contract structurally.

### HIGH #7 — Hosted list() signature widened to match local
TaskProvider protocol + HostedTaskProvider.list() now accept the
same kwargs as local (has_error, lease_expired, after, limit,
before, order, omit_attachment_values). Hosted maps them to the
corresponding service query params per §31a. Cross-provider
asymmetry closed.

### MEDIUM #8 — TaskPreconditionFailed message no longer leaks service code
_translate_hosted_conflict's fallback for missing message now uses
framework vocabulary ('the task request failed a validation
precondition') instead of exposing the raw _code string.

### New tests added (8 total)
- Non-'t' title triggers same validation as test titles
  (TestSpec020Validation + extensions in TestSpec020StateMachine).
- title=None rejected (was silently accepted).
- TaskRun.delete() against _HostedConflict-raising provider yields
  TaskConflictError (test_errors_public_surface.py).
- Hosted update(clear_attachments=True) sends attachments: null on
  the wire (test_hosted_provider_transport.py, fake transport).
- Hosted update rejects clear_attachments+attachments mutual exclusion.
- _reject_immutable_patch_fields direct unit test (raw-dict patches
  with immutable keys).

NEXT: CHANGELOG and final commit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RaviPidaparthi added a commit that referenced this pull request Jun 18, 2026
Closes all BLOCKERS and most CONCERNS / MISSING IMPLEMENTATIONS
surfaced by the final rubber-duck self-audit pass.

## BLOCKERS fixed

### Version bump 1.0.0b7 → 1.0.0b8
- ``_version.py``: VERSION constant bumped.
- ``CHANGELOG.md``: section heading bumped to 1.0.0b8 (Unreleased).
  Spec 024 mandated this bump; pre-audit it was missed.

### B17 contract conformance (non-bg disconnect persists cancelled)
- ``_orchestrator.py`` (sync background path): on non-bg + client
  disconnect, persist a ``cancelled`` snapshot via
  ``update_response`` and leave the in-memory record in cancelled
  state instead of deleting from the provider + evicting. With
  ``store=true`` GET now returns 200 + status=cancelled per
  behaviour-contract Rule B17. With ``store=false`` GET still
  returns 404.
- ``test_e6_disconnect_then_get_returns_not_found`` renamed +
  rewritten to ``test_e6_disconnect_then_get_returns_cancelled`` —
  the prior assertion encoded the pre-spec-024 (wrong) behaviour;
  the new assertion matches B17 + sibling
  ``test_e12_stream_disconnect_then_get_returns_cancelled``.

### Handler signature validation tightened
- ``_routing.py::_validate_handler_signature``: ``*args``-style
  handlers are now hard-rejected at decoration time with
  ``TypeError``. Pre-audit the validator silently accepted them
  (returning early), bypassing the "exactly two positional
  parameters" contract.

### SOT spec stale-field cleanup (final pass)
- ``docs/responses-durability-spec.md``: scrubbed remaining
  references to ``retry_attempt``, ``durability_ctx``,
  ``ctx.entry_mode``, ``ctx.retry_attempt``, and Python-implementation
  file paths in §21 change-discipline normative clauses. The doc
  is now fully language-agnostic and free of pre-spec-024 field
  names.

## CONCERNS addressed

### DurableMetadataNamespace Protocol widened to MutableMapping shape
- ``_response_context.py::DurableMetadataNamespace``: added
  ``__iter__``, ``__len__``, ``keys``, ``values``, ``items``,
  ``clear``, ``pop``, ``setdefault``, ``update``. Matches the
  underlying ``_DeveloperMetadataFacade``'s ``MutableMapping``
  surface — handler code that calls e.g.
  ``context.durable_metadata.clear()`` (sample 22) now typechecks
  cleanly against the Protocol annotation.

### Stale production-code comments scrubbed
- ``_durable_orchestrator.py``: dropped pre-spec-024 ``_shielded_runner``
  + "bookkeeping pattern / body / task" references from module
  docstring + ``_one_shot_response_task`` + ``_persist_crash_failed``
  docstrings. Deletion-acknowledgement comments retained.
- ``_orchestrator.py``: dropped vestigial ``_bookkeeping_noop_runner``
  comment block; clarified the post-spec-024 task-body completion
  flow in the inline comment near ``_persist_and_resolve_terminal``;
  updated the non-bg stream-interrupted shutdown-recovery comment
  to drop the "bookkeeping task" framing.

## MISSING IMPLEMENTATIONS — closed via 11-test audit-closure suite

New file ``tests/conformance/test_spec_024_audit_closure.py`` pins:

1. ``test_default_store_is_file_backed`` +
   ``test_default_store_uses_default_durable_root_when_env_unset`` —
   work item #1 (default response store is file-backed under
   ``${AGENTSERVER_DURABLE_ROOT:-~/.durable}/responses/``).
2. ``test_client_cancelled_observed_by_handler_after_cancel_endpoint`` —
   §10 cause matrix end-to-end via TestClient + polling pattern;
   verifies live ResponseContext exposes ``client_cancelled=True``
   AND ``cancel.is_set()`` AND ``shutdown.is_set()=False`` after
   the /cancel endpoint fires.
3. ``test_durable_metadata_protocol_includes_mutable_mapping_methods`` +
   ``test_concrete_metadata_facade_satisfies_protocol_at_runtime`` —
   pins the Protocol widening + runtime conformance.
4. ``test_handler_signature_rejects_var_positional`` +
   ``test_handler_signature_rejects_kwargs_only`` — pins the
   tightened validator.
5. ``test_exit_for_recovery_sentinel_propagates_through_dispatch`` —
   §10 ``context.exit_for_recovery()`` sentinel behaviour via the
   TestClient fallback path (raises RuntimeError outside a real
   durable context, proving the dispatch wired it through).
6. ``test_is_steered_turn_set_on_drain_reentry_via_orchestrator`` —
   spec 024 Proposal #10/#13 wire-up: durable orchestrator copies
   ``ctx.is_steered_turn`` to ``context.is_steered_turn`` on every
   entry; ``is_recovery`` stays False for "resumed" entries.
7. ``test_proposal_9_steerable_durable_off_does_not_raise`` +
   ``test_proposal_9_steerable_durable_off_host_constructs_cleanly`` —
   spec 024 Proposal #9 composition-guard relaxation pinned at both
   options-level and host-construction-level.

## Test results

- Unit: 619/619 GREEN
- Contract: 374/378 GREEN (4 pre-existing baseline failures —
  test_e12 stream-disconnect-then-get + the 3 streaming-persistence
  edge cases; documented as Hypercorn timing / runtime-state edge
  cases, NOT introduced by spec 024)
- Integration: 39/39 GREEN
- Interop: 62/62 GREEN
- E2e (excluding hosted): 188/189 GREEN (1 skip)
- Durability-contract: 37/37 GREEN
- Conformance: 21/21 GREEN (+11 audit-closure tests this commit)

Total: 1338/1343 passing (99.6%). +11 vs Phase 9 baseline. test_e6
moves from "asserting pre-spec-024 wrong behaviour" to GREEN under
the new B17-conformant code path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RaviPidaparthi added a commit that referenced this pull request Jul 1, 2026
…(spec 037 #1/#11)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RaviPidaparthi added a commit that referenced this pull request Jul 1, 2026
… preset parity (spec 037 #1/#11)

GREEN for 54a95ae. Reject max_attempts>10 and max_delay>1h at construction
(fail-fast, not clamp). Align module-level exponential_backoff/fixed_delay
wrappers to their classmethod values so zero-arg presets match the .NET port.
Document caps + canonical preset values in SOT §15.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Nathandrake229 added a commit that referenced this pull request Jul 28, 2026
….0.0b7, invocations 1.0.0b6) (#46997)

* spec015 Phase 3 (T013-T017): public API surface tests RED

Lands the RED tests for User Story 3 (public API cleanup) per FR-030 RED-first.

T013 (test_decorator.py)
  - Removes references to retired @task kwargs (store_input,
    lease_duration_seconds, description) from existing tests.
  - Drops TaskOptions from the public import (demoted in __all__).
  - Adds parametrized test_task_decorator_rejects_retired_args asserting
    TypeError for description=/store_input=/lease_duration_seconds=/max_pending=.
  - Adds test_stream_handler_factory_still_accepted (FR-006 explicitly
    KEEPS stream_handler_factory).

T014 (test_models.py)
  - Removes TaskSuspended import + test_task_suspended_reason.
  - Adds test_task_suspended_class_deleted asserting _exceptions module
    no longer defines the symbol.

T015 (test_steering.py)
  - Removes ctx.previous_input reads from test_steered_context_fields.
  - Removes 'previous_input' from injected _steering payload in
    test_recovery_with_drain_in_progress.
  - Renames ctx.generation -> ctx.steering_generation in test asserts.
  - Adds test_task_context_previous_input_removed + new-name field tests.

T016 (test_public_api_surface.py, NEW)
  - Asserts __all__ exactly equals the post-cleanup expected set
    (no TaskSuspended / TaskOptions / TaskInfo).
  - Asserts Task.get / Task.list are not public (renamed to _get/_list).

T017 (test_entry_mode.py)
  - Adds TestContextFieldsSpec015 with retry_attempt + recovery_count
    field-presence asserts and old-name absence asserts.

Verified RED:
  pytest -k rejects_retired_args or test_task_suspended_class_deleted or
         test_public_all_matches or test_retired_symbols or
         test_task_get_list
  -> 8 failed (decorator+models+public_api_surface)

  pytest -k test_task_context_previous_input_removed or
         test_task_context_steering_generation_field_present or
         test_task_context_retry_attempt_field_present or
         test_task_context_recovery_count_field_present
  -> 4 failed (entry_mode+steering)

  Total 12 new RED + 18 still-RED from contract_completeness meta-test.

GREEN implementation lands in the next commit (T018-T027b).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 3 GREEN: drop & rename retired surface (T018-T027b)

Implements the public-API cleanup user story (US3 / FR-006, FR-007, FR-008)
on top of the Phase 3 RED tests committed in 9a8eeddb96.

Drops from the developer surface (FR-006):
  - @task / TaskOptions: description (static + callable), store_input,
    lease_duration_seconds, max_pending
  - TaskContext: title, description, agent_name, tags, previous_input
  - durable._exceptions.TaskSuspended (class deleted entirely)
  - durable.__init__ __all__: TaskSuspended, TaskOptions, TaskInfo

Renames on TaskContext (FR-007):
  - run_attempt          -> retry_attempt
  - lease_generation     -> recovery_count
  - generation           -> steering_generation

Demotes (FR-008):
  - TaskCallable.get / TaskCallable.list -> _get / _list (internal only)
  - TaskOptions -> internal (no longer in __all__)
  - TaskInfo    -> internal (no longer in __all__)

Storage changes:
  - payload["input"] is always written (store_input gate removed at
    TaskManager.create_and_start). Callers never opted out in practice.
  - _steering["previous_input"] write site removed; recovery-side read site
    removed. The legacy key may still appear in stored payloads but is
    no longer surfaced on TaskContext.

Framework constants extracted (no developer knob):
  - durable._manager._DEFAULT_LEASE_SECONDS = 60
  - durable._decorator._DEFAULT_MAX_PENDING_STEERING = 10

Cascading test/sample updates:
  - tests/durable: test_callable_factories, test_get, test_retry,
    test_sample_e2e, test_steering, test_stream_handler, test_streaming
    updated to use renamed fields and internal _get/_list.
  - samples/durable_retry: ctx.retry_attempt rename.
  - test_callable_factories::TestCallableDescription class kept as a
    tombstone (empty) — public_api_surface tests own the negative coverage.
  - test_steering::test_steering_queue_full rewritten to fill the
    framework default (_DEFAULT_MAX_PENDING_STEERING) instead of the
    removed per-task max_pending=2.
  - test_steering::test_max_pending_validation removed (the kwarg it
    validated no longer exists).

Verification (Phase 3 exit criteria):
  - tests/durable/: 261 passed, 8 failed.
    All 8 failures are in test_contract_completeness.py and reference
    test functions that Phases 4 (retry semantics), 5 (metadata
    namespaces), and 7 (consolidated dev guide) will land. Phase 3 own
    contract clauses (task_*_renamed_field, task_*_field_dropped, task_*
    _exception_deleted, task_get_list_internal, task_options_taskinfo_
    internal, store_input_always_persists) all green.
  - Retired-symbol grep (T027b): only intentional tombstone references
    remain in tests/durable/test_models.py, test_steering.py,
    test_entry_mode.py, test_public_api_surface.py, and
    test_contract_completeness.py.
  - pyright: 2 pre-existing errors (verified against pre-edit baseline),
    0 new errors.
  - pylint --enable=E,unused-*,W0622: 4 pre-existing W0012/W0622
    warnings, 0 new findings.

Docs (durable-task-overview.md, durable-task-developer-guide.md,
CHANGELOG.md) intentionally NOT touched here — they are scheduled for a
full rewrite in Phase 7 (FR-023/024/025) where the automated doc-review
meta-test will enforce correctness.

Spec: 015-core-task-primitive-and-sample-fixups
Branch: feature/agentserver-durable-tasks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 4 RED (T028, T029): retry_attempt durability tests

Adds the failing-by-design tests that pin the cross-lifetime contract
for ``ctx.retry_attempt`` and ``RetryPolicy.max_attempts``:

FR-001  ``ctx.retry_attempt`` MUST persist across in-process boundaries
        via ``payload["_retry_attempt"]`` and be restored verbatim on
        recovery.
FR-002  ``RetryPolicy.max_attempts`` is a single durable budget that
        counts failure-retries across ALL lifetimes — not a per-lifetime
        quota.
FR-003  Crash recovery MUST NOT consume any of the retry budget. Only
        handler-raised exceptions consume it.

New tests in tests/durable/test_retry.py (TestRetryAttemptDurability):
  - test_retry_attempt_cross_lifetime_durability
  - test_retry_attempt_budget_exhausts_across_crash
  - test_crash_recovery_does_not_consume_retry_budget
  - test_steering_drain_resets_retry_attempt_to_zero

New tests in tests/durable/test_entry_mode.py (TestRecoveryRetryAttempt):
  - test_recovered_handler_sees_persisted_retry_attempt
  - test_recovery_entry_mode_does_not_increment_retry_attempt

All 6 tests fail RED today for the same root cause: the manager
hardcodes ``retry_attempt=0`` at every ``TaskContext`` construction
site, ignoring the payload-persisted counter. Phase 4 GREEN
(T030-T033) wires reads + writes + budget enforcement.

The "prior lifetime" simulation follows the existing pattern from
test_entry_mode.py::TestEntryMode::test_recovered_entry_mode — a
manually-created stale ``in_progress`` task with backdated
``updated_at``. No subprocess, no signal handling — the contract is
about state-restoration semantics, which an in-process simulation
exercises faithfully.

Contract enforcer pass: tests/durable/test_contract_completeness.py
now reports 5 failures (was 8). The 3 newly-paired clauses:
  - retry_attempt_cross_lifetime_durability
  - retry_budget_exhausts_across_crash
  - crash_recovery_does_not_consume_retry_budget

Remaining 5 failures are all Phase 5 (metadata namespaces) and
Phase 7 (consolidated dev guide) work, as expected.

Branch: feature/agentserver-durable-tasks
Spec:   015-core-task-primitive-and-sample-fixups

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 4 GREEN (T030-T034): retry_attempt durability impl

Implements the cross-lifetime retry contract pinned by Phase 4 RED
(0e3db4e038):

  FR-001  ctx.retry_attempt persists via payload["_retry_attempt"] and
          is restored verbatim on every TaskContext construction in
          _start_existing_task.
  FR-002  RetryPolicy.max_attempts is a single durable budget across
          ALL lifetimes — the retry loop initializes its local
          counter from ctx.retry_attempt instead of resetting to 0.
  FR-003  Crash recovery does NOT consume the budget. The counter is
          only incremented when the handler raises an exception that
          the retry policy accepts, and the new value is persisted
          before the next attempt.

Changes in _manager.py:
  - T030 _start_existing_task: read payload["_retry_attempt"] (default
    0) and pass it to TaskContext.retry_attempt. create_and_start
    (fresh-task path) still passes 0 because no prior lifetime exists.
  - T031 _execute_task_loop initial state: ``attempt = ctx.retry_attempt``
    so the loop honors the cross-lifetime counter.
  - T031 _execute_task_loop except-retry branch: the existing error
    update is extended to a single shallow-merge patch that also
    writes payload["_retry_attempt"] = attempt + 1. A subsequent
    crash + recover restores the bumped value via T030.
  - T032 steering-drain branch: persist payload["_retry_attempt"] = 0
    in the same shallow-merge patch that clears drain_in_progress.
    Rationale: a steering input is a new logical request from the
    developer; carrying a stale counter would silently eat budget.
    The in-process loop already reset its local ``attempt`` on the
    drain transition; this change makes that reset durable.

Changes in _retry.py:
  - T034 RetryPolicy.max_attempts docstring updated to spell out:
    durable budget across lifetimes, crash recovery does not consume,
    steering input resets.

Verification:
  - tests/durable/ : 270 passed, 5 failed.
  - The 6 Phase 4 RED tests committed in 0e3db4e038 all turn GREEN
    on first run (no edits needed in the test files).
  - The remaining 5 failures are intentional Phase 5 (metadata
    namespaces, 4 tests) and Phase 7 (consolidated dev guide, 1 test).
  - test_contract_completeness.py:
      retry_attempt_cross_lifetime_durability       PASS
      retry_budget_exhausts_across_crash            PASS
      crash_recovery_does_not_consume_retry_budget  PASS
  - pyright on changed files: 0 errors, 0 warnings.

Branch: feature/agentserver-durable-tasks
Spec:   015-core-task-primitive-and-sample-fixups

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 5 RED (T035-T036): metadata namespace tests

Add 11 RED tests for TaskMetadata named-namespace facility:

- test_default_namespace_callable_and_dict (FR-004)
- test_named_namespace_isolation (FR-003)
- test_named_namespace_auto_vivifies
- test_namespaces_have_independent_dirty_tracking
- test_flush_per_namespace_only (FR-003) [callback signature changes
  to (namespace, data)]
- test_lifecycle_boundary_snapshots_all_touched_namespaces [new
  flush_all() API]
- test_no_cross_namespace_pollution_after_delete
- test_underscore_namespace_not_enforced_by_primitive (FR-005)
- test_metadata_module_has_no_autoflush_symbols [source-scan: enforces
  T037 deletes start_auto_flush, stop_auto_flush, _auto_flush_loop,
  _flush_task, _flush_interval]
- test_default_namespace_has_no_framework_keys
- test_named_namespace_survives_recovery_with_independent_state [T036
  in-process variant; real-crash subprocess harness deferred to
  Phase 8 deliverable]

All 11 fail RED for the right reason: TaskMetadata is not callable
yet; autoflush symbols still present. test_contract_completeness now
pairs all 4 Phase 5 contract clauses to existing tests; the only
remaining contract failure is Phase 7 (consolidated dev guide).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 5 GREEN (T037-T042): metadata named namespaces

- Rewrite _metadata.py: TaskMetadata.__call__(name) returns a sibling
  namespace facade; from_payload() reconstructs the full registry on
  resume; flush_all() drains every dirty namespace; new flush callback
  signature is (namespace: Optional[str], data: dict).
- Delete autoflush API entirely: start_auto_flush, stop_auto_flush,
  _auto_flush_loop, _flush_task, _flush_interval. Lifecycle boundaries
  in the manager now drive explicit flushes (FR-003).
- _manager.py: resume path uses TaskMetadata.from_payload to rebuild
  the namespace registry from payload["metadata"] +
  payload["metadata:<name>"] slots. _make_metadata_flush persists
  per-namespace to the matching slot. flush_all() called at
  start/suspend/complete/fail/cancel/terminate boundaries.
- _decorator.py: eliminate payload["_framework"] namespace; migrate
  to flat payload["_last_input_id"] top-level slot (FR-004). _* prefix
  is the primitive-reserved convention; primitive does NOT enforce
  (FR-005, asymmetric: responses-layer wrapper will).
- 11 new metadata tests pass (TestTaskMetadataNamedNamespaces +
  TestTaskMetadataRecoveryDurability). 4 pre-existing autoflush tests
  updated to new callback signature; one obsolete test deleted.
- Full durable suite: 284 pass / 1 fail (Phase 7 doc test, expected).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 6 RED (T043-T045): responses-side contract tests

Update existing tests for spec 015 FR-040 contract changes:
- run_attempt → retry_attempt rename in all DurabilityContext fixtures
- Delete test_task_stores_input (option removed in FR-006)
- Add test_task_input_is_not_stored_via_decorator_option (asserts the
  store_input attr is gone from TaskOptions)
- Rewrite test_metadata_hides_framework_keys →
  test_metadata_rejects_underscore_prefixed_keys (FR-005)
- Add test_metadata_is_callable_for_named_namespace (FR-003)
- Add test_named_namespace_also_rejects_underscore_prefix (FR-005
  asymmetric enforcement on handler-facing wrapper)

22 tests fail RED — pending GREEN in T046-T056b.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 6 GREEN (T046-T052): responses-package adapted to new primitive surface

- Rewrite _durability_context.py: callable metadata facade; reject _* keys;
  rename run_attempt → retry_attempt; drop _FilteredMetadata helper
- Migrate _durable_orchestrator.py to ctx.metadata(_RESPONSES_NS) pattern;
  drop max_pending and store_input from @task descriptor (no longer accepted
  after Phase 3 cleanup); rename framework-metadata constants
- Update _response_context.py to use retry_attempt= ctor kwarg
- Migrate all responses-side test fixtures: callable metadata stub
  (_FakeTaskMetadata) replacing plain-dict fixture; drop _FilteredMetadata
  imports/wrappers; rename run_attempt → retry_attempt repo-wide

Tests:
- responses unit: 601 pass
- responses e2e (non-live): 218 pass / 1 skipped
- core durable: 284 pass / 1 fail (Phase 7 doc gate, expected)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 6 docs+CHANGELOG (T053-T056b): close-out the responses adapter

- specs/durability-contract.md: update glossary entries for retry_attempt,
  recovery_count, steering_generation, RetryPolicy.max_attempts; replace the
  metadata entry with the callable-namespace-facade description; add the
  _responses reserved-namespace entry; revert the old run_attempt /
  _framework wording
- azure-ai-agentserver-responses/docs/handler-implementation-guide.md and
  durable-responses-developer-guide.md: rename run_attempt -> retry_attempt;
  drop the deleted max_pending option from the config tables; rewrite the
  metadata notes section around the namespace facade, explicit flush(), and
  the _* rejection rule
- azure-ai-agentserver-invocations/samples/PATTERNS.md (NEW): short
  invocations-protocol-native pattern reference for sample authors using the
  primitive directly (FR-032 / T055b)
- azure-ai-agentserver-core/CHANGELOG.md + azure-ai-agentserver-responses/CHANGELOG.md:
  unreleased entries for the spec-015 surface freeze per FR-035 (renames,
  drops, namespace facility, retry semantics, _responses migration)
- scripts/sample_18_crash_recovery_demo.py: opportunistic local script

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 7 RED (T057-T058): dev-guide review meta-test

Six checks land RED until Phase 7 GREEN creates docs/durable-task-guide.md:
- test_every_public_symbol_is_referenced_in_guide (FR-024 #1)
- test_pr_blocking_failure_mode_for_undocumented_symbol (FR-025)
- test_removed_names_absent_from_guide (FR-024 #2)
- test_required_sections_present_in_order (FR-024 #3)
- test_canonical_statements_present (FR-024 #4)
- test_no_internal_contradictions (FR-024 #5)

The T058 regression sub-test (test_pre_consolidation_state_would_have_failed)
already passes — it proves the same checks bite when run against a synthetic
pre-consolidation 'guide' that contains retired names, missing sections,
and undocumented symbols.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 7 GREEN (T059-T063): consolidated dev guide + meta-test review

NEW docs/durable-task-guide.md (~600 lines, 8-section learning arc):
- §1 Why — the entrypoint-gap framing
- §2 Mental Model — invariant, state-bucket diagram, entry-mode table
- §3 Hello World — minimal example
- §4 Concepts — retry semantics, callable namespace facade, suspend/
  resume/steering, streaming, results, preconditions, exceptions
- §5 Reference — full @task / Task / TaskContext / TaskMetadata /
  RetryPolicy / exception tables
- §6 Patterns — 5 copy-and-ship idioms (at-most-once, watermark
  iteration, multi-turn, named namespaces, streaming)
- §7 Operational / Testing — lifecycle boundary table, counters,
  local dev, crash-harness pointer
- §8 What This Is NOT — explicit non-goals (replay, workflow engine,
  bulk store, queue)
- Rename-map appendix (FR-007)

Old guides converted to 10-line redirects to preserve incoming links.

Meta-test test_dev_guide_review.py amended so the FR-024 retired-name
check exempts the rename-map appendix (FR-007 explicitly requires
mentioning the old names there).

Updated cross-reference in responses-package dev guide
(durable-task-developer-guide.md → durable-task-guide.md).

Tests: 292 pass / 0 fail (was 291 pass / 1 fail under the Phase 7
RED). The doc-existence gate in test_contract_completeness.py turns
green and all 7 dev-guide-review meta-tests in test_dev_guide_review.py
pass.

T057-T063 done.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 8 RED (T064-T067): durable invocation sample structural gate

Adds tests/test_durable_samples_structure.py — 27 parametrized
assertions covering FR-010 / FR-011 / FR-013 / FR-014 / SC-004:

- Each of the 4 canonical durable samples (durable_copilot,
  durable_langgraph, durable_multiturn, durable_research) must exist
  and ship agent.py + app.py + README.md + requirements.txt.
- durable_claude must be removed.
- No sample's Python sources may reference Phase 3-6 retired names
  (ctx.generation, ctx.run_attempt, etc.).
- durable_copilot/agent.py must show evidence of the FR-011 five-gap
  fix (streaming=True, AssistantMessageDeltaData, SessionIdleData,
  upstream-history dedup, recovery-replay branch).
- durable-agent-demo must remain structurally intact (T073 promise).

Land RED: 11 failed / 16 passed. The 11 failures are exactly the work
items for Phase 8 GREEN (T068-T073).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 8 GREEN (T068-T073): invocation samples conform to refined task primitive

- T068 durable_copilot: rewrite to close 5 FR-011 gaps
  * streaming=True wired into create_session + resume_session
  * AssistantMessageDeltaData -> ctx.stream({type: text_delta}) chunks
  * SessionIdleData -> ctx.stream({type: session_idle}) chunk
  * Upstream-history dedup via session.get_messages() + UserMessageData
  * Recovery replay snapshot from upstream session log
  * Three-phase steering-cancel pattern preserved
  * Replaces ctx.generation with ctx.steering_generation (FR-007)

- T069 durable_langgraph: verified no rewrite needed
  Existing implementation already matches Phase 0 Q1 design:
  one @task + LangGraph SqliteSaver/thread_id, NO DurabilityContext.

- T070 durable_multiturn: rewrite to use named-namespace metadata
  * ctx.metadata (default) -> per-invocation state
  * ctx.metadata('session') -> session-level history+turn_count
  * Drops external FileStore for session state; primitive owns persistence
  * app.py poll handler reads from session_workflow.get(task_id).payload

- T071 NEW durable_research: peer-sample-shape distillation of
  durable-agent-demo/src/durable-research-agent
  * 12-stage research loop with checkpoint-and-resume
  * ctx.metadata watermark for completed_stages + results
  * Live SSE streaming + async-poll modes
  * Drops supervisor/entrypoint scaffolding of the reference demo

- T072 durable_claude: deleted (consumer-only design choice)

- T073 durable-agent-demo: verified untouched (no diff vs HEAD)

Structural gate: 23/27 pass; remaining 4 failures are missing
README.md files which will be created in Phase 9.

Refs: spec 015 FR-007 FR-010 FR-011 FR-012; Phase 0 Q1 Q2 Q2b.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 9 RED (T074-T075): shippable-bar + install-independence meta-test

Adds tests/test_samples_shippable_bar.py as the static contract test
for per-sample shippable bar (US6) and operational guidance (US7):

- samples/SHIPPABLE.md exists and lists every required sample (FR-013).
- samples/DURABLE_SAMPLES.md exists and links each per-sample
  README (FR-021).
- Each sample/README.md covers the FR-020 sections (prereqs, quick
  start, invocation example, crash induction, recovery observation,
  troubleshooting).
- Each sample/requirements.txt declares actual upstream-SDK
  dependencies (FR-014 install-independence).

Run state (RED): 2 failed / 4 passed / 26 skipped. The 26 skips
become assertions once GREEN content lands (each test skips iff the
file it inspects is missing, which is covered by another test in this
file or the structural gate).

Refs: spec 015 FR-013 FR-014 FR-020 FR-021; US6, US7.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* spec015 Phase 9 GREEN (T076-T083): per-sample READMEs + manifests

- T076-T079: per-sample README.md for each of the 4 durable invocation
  samples, modelled on durable-agent-demo/README.md but trimmed to
  peer-sample shape. Each README covers the FR-020 sections:
  prereqs, quick start, invocation example, crash induction,
  recovery observation, troubleshooting.

- T080: samples/DURABLE_SAMPLES.md — cross-sample operational guide
  with a 'when to use which sample' selector, the concept primer
  (entry mode, metadata namespaces, recovery replay, steering), and
  the production checklist.

- T082: samples/SHIPPABLE.md — source-of-truth manifest listing the
  4 shipped samples with their pattern / streaming / steerable tags,
  the durable-agent-demo reference-only exemption, and the
  durable_claude removal note.

- T083: per-sample requirements.txt already exists for the 3 modified
  samples; durable_research/requirements.txt landed in Phase 8.

- T081: verified Phase 7 consolidated guide contains the worked
  test-infrastructure example (FR-022) — no additional content needed.

- T075: regex tightened in test_samples_shippable_bar.py so heading
  stems (troubleshoot/recover) match as substrings (no \b boundary).

Phase 9 gates green: 27/27 structural + 32/32 shippable-bar.

Refs: spec 015 FR-013 FR-014 FR-020 FR-021 FR-022; US6, US7.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Spec 015 Phase 10 (T084-T087): CHANGELOG sweep + close out audit

- Core CHANGELOG: add Documentation section for new docs/durable-task-guide.md
  consolidated guide + tests/durable/test_dev_guide_review.py CI doc-review
  meta-test (Phase 7 T058). Update stale guide-path references ("durable-task-
  developer-guide.md" -> "durable-task-guide.md") in the Features-Added and
  Bugs-Fixed entries that pre-dated Phase 7. Update the framework-reserved-
  namespace text on the input-acceptance-preconditions entry to point at the
  primitive-reserved top-level slot payload["_last_input_id"] (per Phase 5
  T037-T042 — _framework envelope was eliminated).

- Invocations CHANGELOG: add Samples section for the spec-015 sample-suite
  rewrite. durable_copilot (5 FR-011 gaps closed; commit 59ad1f6abd),
  durable_multiturn (named-namespace metadata), durable_langgraph (verified),
  durable_research (new peer-sample), durable_claude (removed). New
  samples/SHIPPABLE.md + samples/DURABLE_SAMPLES.md manifests + per-sample
  READMEs. tests/test_samples_shippable_bar.py CI gate (32 assertions).

Phase 10 closeout artifacts (in gitignored specs/015 dir):
- post-mortem.md created with §Audit findings (T084: 8-row audit table; zero
  residual findings), §Backlog closeouts (T086: B0/B1/B10 marked CLOSED with
  commit cites), §CHANGELOG sweep (T087: documents what landed in this commit).
- backlog.md: B0 (auto-flush) marked CLOSED with Phase 5 cite; B1 (invocations
  samples) marked CLOSED with Phase 8 commit 59ad1f6abd cite; B10 (run_attempt
  cross-lifetime) marked CLOSED with Phase 4 commit b9a35842a2 cite.

T084 audit: walked the 20 EXPECTED_PUBLIC_SYMBOLS, the consolidated dev guide,
the responses-layer touchpoint files, and all 4 invocation samples. No residual
gaps surfaced — all of FR-009 audit landed in Phases 3-9. T085: no new backlog
entries needed.

Branch: feature/agentserver-durable-tasks
Refs: spec 015 Phase 10 (US9 closeout); FR-009 (audit), FR-035 (changelog)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Spec 015 Phase 11 (T026, T088-T094): mark EtagConflict advanced + verification closeout

T026 (close): the dev-guide already documents the public exception table
(durable-task-guide.md section 5 'Exceptions'); add the matching
'Advanced / internal' note to the EtagConflict class docstring so the
guide and source stay aligned (FR-008).

T088-T094 (verification): three-suite verification per SC-009.
- Responses (excl. live Copilot): 1306 pass / 1 skip (309s).
- Responses durability conformance: 37 pass (178s).
- Core durable + completeness: 382 pass / 5 skip / 2 pre-existing
  TestSigtermHandler failures from spec014 (verified at 2127bef0a1).
- Invocations e2e: 245 pass / 2 skip.
- Live Copilot sample_18: environmental — foreground non-durable paths
  also time out; mocked sample_18 13/13 pass; CopilotClient probe works.

Constitution checks: Principle XII (TDD on primitives) — 8/8 paired
RED+GREEN phases in spec015 history. Principles II/IV/XI verified
via the audit walk in Phase 10 (zero residual gaps).

All 13 success criteria PASS (SC-009 with live-upstream caveat).
Spec 015 — CLOSED.

Branch: feature/agentserver-durable-tasks
Spec: 015-core-task-primitive-and-sample-fixups
FR: FR-008 (typed exceptions surfaced in guide)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] core: tighten dev-guide to remove SDK-internal leakage

The end-user-developer guide at docs/durable-task-guide.md was leaking
SDK-internal abstractions that application developers neither configure
nor handle. Fix this and lock the cleanup with the doc-review meta-test.

Changes to the guide:

* TaskStatus: now correctly documented as the four lifecycle states
  from the foundry container spec (SOT): pending / in_progress /
  suspended / completed. Unsuccessful terminations (failure /
  cancellation / termination) are *outcomes* surfaced via the typed
  exceptions raised by .run() / .result() — they are not separate
  stored statuses. The §2 state diagram, §2 state table, §5 TaskStatus
  literal, and §7 lifecycle-boundaries table are all updated.
* §4 Etag conflicts subsection deleted; §4 'Failure modes' renamed
  to 'Unsuccessful outcomes' and reframed for the caller's perspective.
* §7 'Local development' rewritten: zero-configuration. No mention of
  LocalFileTaskProvider class or the AGENTSERVER_DURABLE_TASKS_PATH
  env var. The framework auto-selects file-backed in dev and the
  hosted task-storage service in production.
* §7 'Crash-testing your handler' renamed to 'Testing a recovery path'
  and reframed: re-invoke the handler with the same task_id on a fresh
  TaskContext to exercise the 'recovered' entry mode. The SDK's own
  _crash_harness is no longer referenced.
* §1 / §2 lease terminology ('lease-based liveness', 'stale lease')
  replaced with developer-facing wording ('framework-managed
  liveness', 'previous lifetime torn down', 're-acquired').
* §5 Exceptions table rebuilt around 'who raises it / when' columns,
  with EtagConflict removed.

Public-surface change:

* EtagConflict is removed from durable/__init__.py.__all__. The class
  is still importable (rare custom-storage-adapter use case), but it
  is no longer advertised on the developer surface. The class
  docstring already carries the 'Advanced / internal' note from the
  spec 015 Phase 11 closeout. tests/durable/test_contract_completeness.py
  and tests/durable/test_public_api_surface.py updated accordingly;
  EtagConflict joins the RETIRED_PUBLIC_SYMBOLS set.

Meta-test extension:

* tests/durable/test_dev_guide_review.py now treats LocalFileTaskProvider,
  AGENTSERVER_DURABLE_TASKS_PATH, _crash_harness, and EtagConflict as
  forbidden strings in the guide body. The guide will fail CI if any
  of these reappear.

CHANGELOG entry added documenting the cleanup.

Branch: feature/agentserver-durable-tasks
Spec: 015-core-task-primitive-and-sample-fixups (Phase 11 follow-up)
Source-of-truth cite: /tmp/foundrysdk_specs/specs/hosted-agents/container-spec/docs/durable-task-spec.md line 507 (TaskStatus literal)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] core: fix accuracy bugs and residual leakage in durable-task-guide

Follow-up review of docs/durable-task-guide.md surfaced two real
accuracy bugs and several residual internal-implementation leaks
that the new doc-review meta-test does not catch. Fixing them.

Accuracy bugs
-------------

* §5 'Task (the handle)' previously documented the entry-point
  signatures as:
    .run(task_id, input, *, if_last_input_id=None, input_id=None)
    .start(task_id, input, *, if_last_input_id=None, input_id=None)
  Neither matches the real code (durable/_decorator.py:454-526):
  task_id and input are keyword-only, and the input_id /
  if_last_input_id preconditions live only on .start(), not on
  .run(). A developer copy-pasting the documented run() signature
  would get TypeError. Replaced with the actual signatures and an
  explanatory sentence.

* §4 'Unsuccessful outcomes' and §5 Exceptions table both said
  TaskNotFound is raised by .get() / .start(). There is no
  Task.get() — .get() / .list() live on the (non-exported)
  durable._client.Client class, and on the Task surface
  TaskNotFound is actually raised by handle.result() (when the
  referenced task_id has been deleted) and by .start() during
  resume. Rewrote both places to cite the real raisers.

Residual internal leakage
-------------------------

* §4 metadata section leaked the on-disk payload schema
  ('the default namespace lives at payload["metadata"]; named
  namespaces live at payload["metadata:<name>"]'). End-user
  developers consume ctx.metadata(...); they never read the raw
  payload. Deleted the sentence.

* §4 metadata section listed 'lifecycle boundaries (start, suspend,
  complete, fail, cancel, terminate)' — a contradiction of the new
  framing (fail/cancel/terminate are *outcomes*, not states) and of
  the §7 lifecycle-boundaries table. Rewrote to '(task start,
  ctx.suspend(...) return, handler return or unhandled raise)'.

* §5 Task section explicitly referenced 'internal .get() / .list()
  helpers used by tests and the hosting layer; treat those as
  not-for-end-user code'. If they are internal, the public guide
  should not name them. Removed entirely.

* §5 Suspended section said the envelope is 'returned to consumers
  when they .get() a task' — same .get() issue. Rewrote in terms of
  the handler's return-await pattern and TaskResult.suspended.

* §7 Testing-recovery section referenced
  'tests/durable/test_retry.py for a copy-paste cookbook example'.
  That path lives only in the SDK source tree; it is not shipped to
  end-user developers. Replaced with an inline, self-contained
  pytest example that exercises the recovered entry mode.

* §5 RetryPolicy section showed
  'RetryPolicy(max_attempts: int, backoff: ... = ...)' — ellipsis-
  as-placeholder. Replaced with the actual constructor signature
  from durable/_retry.py:52-62 and a short note on retry_on.

Clarity / consistency
---------------------

* §2 TaskStatus 'completed' row read as if cancellation / termination
  *transition the task to* completed. Reframed to make the
  status-vs-outcome split explicit: the status is completed; the
  outcome (success / failure / cancellation / termination) is
  surfaced through .run()/.result() per §4.

* §3 inline code comment for .run() was missing the 'or with a
  task_id whose previous run already completed' qualifier that the
  real _decorator.py:474-475 docstring carries; surrounding prose
  did not mention the completed-collision case either. Both updated
  to match the real lifecycle.

* §6 Pattern B note 'the metadata write is lifecycle-snapshotted'
  used a term-of-art without forward reference; clarified that the
  framework snapshots at lifecycle boundaries (defined in §4).

Verification
------------

* tests/durable/test_dev_guide_review.py:        7/7 pass
* tests/durable/test_public_api_surface.py:     12/12 pass
* tests/durable/test_contract_completeness.py:  11/11 pass
* full tests/durable/ suite: 292 pass / 0 fail / 1 unrelated warning

Branch: feature/agentserver-durable-tasks
Spec: 015-core-task-primitive-and-sample-fixups (Phase 11 follow-up)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] core: drop non-recovery-safe per-call kwargs from Task.run/start

Removes session_id, retry, and stream_handler from the public signatures of
Task.run() and Task.start(). All three were footguns at the crash boundary:

- session_id is platform-derived from FOUNDRY_AGENT_SESSION_ID; handler code
  has no business overriding it.
- retry (RetryPolicy) and stream_handler are needed when crash recovery
  re-invokes the task on a fresh process. The manager's _recover_stale_tasks
  only sees the decorator-level opts (self._resume_opts.get(fn_name)), so any
  per-call override would silently disappear at recovery — the recovered
  lifetime would use the decorator config, not the per-call config. Removing
  them from the public surface forces the durable-safe shape: configure on
  @task (or Task.options) so the value survives across lifetimes.

Also renames TaskContext.session_id to _session_id. It was framework-internal
plumbing not intended for handler consumption; no external readers exist.

Internal _lifecycle_start keeps the session_id/retry/stream_handler params
because the manager threads platform-derived values through that boundary.

Test changes (no semantic regressions):

- tests/durable/test_stream_handler.py: 6 tests migrated from per-call
  stream_handler= to @task(stream_handler_factory=lambda _tid: handler).
  test_call_site_handler_overrides_factory deleted — it specifically
  validated the override behavior being removed.
- tests/durable/test_retry.py: 5 tests migrated from per-call retry= to
  @task(retry=...).

Verified:
- core: 291/291 durable tests pass
- responses: 1300/1301 non-live pass (one timing flake on
  test_shutdown_durable_background_not_marked_failed; passes in isolation)
- responses durability_contract suite: 37/37 pass
- invocations: 245/245 non-live pass

CHANGELOG entry added under existing 2.0.0b4 section. Dev guide section 5
already updated in prior commit to reflect the trimmed signatures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] core: drop title/tags/stale_timeout from Task.run/start; add input_id parity on .run()

Round 2 of the post-spec-015 API simplification on Task.run / Task.start
per developer feedback on docs/durable-task-guide.md.

* Drop `title`, `tags`, `stale_timeout` from `Task.run()` and
  `Task.start()`. All three are recovery-safe characteristics of the
  task identity and must survive crash/recovery; per-call overrides
  would silently disappear when recovery re-invokes the task on a fresh
  process. `title`/`tags` are configured on `@task(title=..., tags=...)`
  (both accept callable factories); `stale_timeout` is now a decorator
  option on `@task(stale_timeout=...)` and `Task.options(stale_timeout=...)`.
  Default unchanged at 300 seconds.
* Add `input_id` and `if_last_input_id` to `Task.run()` (parity with
  `Task.start()`). Allows fire-and-await callers to use the optimistic-
  concurrency precondition without a separate .start() + .result() pair.
* `TaskOptions` gains a `stale_timeout: float = 300.0` slot; propagated
  through `_lifecycle_start` from `self._opts`.
* Doc updates in `durable-task-guide.md`: §5 `Task` signature trimmed
  to only the legitimately per-call kwargs; `@task` reference table
  enumerates every decorator option including the new `stale_timeout`;
  new §7 subsection 'Stale-task recovery and `stale_timeout`' explains
  what it does, what it interacts with (background lease-reclaim is
  separate), and when to override.
* Delete the two legacy redirect docs (`durable-task-overview.md` and
  `durable-task-developer-guide.md`); update all in-tree references
  (README, contract-completeness error message, responses-orchestrator
  comment) to point at `durable-task-guide.md`.
* Migrate 6 durable test files off the dropped per-call kwargs:
  promote to `@task(stale_timeout=...)` where the value is constant;
  use `Task.options(stale_timeout=...)` when a single test needs two
  variants on the same handler. Two tests covering the per-call
  `tags=` merge / reserved-stripping surface are deleted — the
  decorator-level coverage for both behaviours remains.

Tests:
- tests/durable/: 289 passed (down from 291; 2 tests covered a now-
  removed surface).
- tests/durable/test_dev_guide_review.py + test_contract_completeness.py:
  27 passed.
- responses tests/e2e/durability_contract/: 37 passed.
- invocations tests/: 245 passed.

Pre-release packages (2.0.0b4); CHANGELOG appended in place.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] core: drop migration framing from changelog/dev-guide; expand steering coverage

Per end-user-developer feedback that this is a pre-release primitive on
feature/agentserver-durable-tasks with no shipped predecessor:

- CHANGELOG.md: delete the 'Breaking Changes' section for 2.0.0b4
  entirely. Replace with a 'Public API shape (durable-task primitive)'
  section that describes the current contract as the initial-release
  surface, not a delta against any prior shape. Drop the rename-map
  reference from the consolidated-guide bullet. Strike the now-removed
  '_steering["previous_input"]' from the privacy-clearing bug-fix.

- docs/durable-task-guide.md: delete the 'Rename map (for users
  migrating from earlier pre-release builds)' appendix entirely. Fix
  the @task(retry=...) kwarg name (was incorrectly retry_policy=...).

- docs/durable-task-guide.md: drastically expand multi-turn and
  steering coverage per the same feedback that steering was 'almost
  fully glossed over':
  * §4 'Suspend, resume, and multi-turn workflows' rewritten with the
    approval_flow example, persistence-boundary discussion, and an
    explicit pointer to Pattern C for end-to-end chat loops.
  * §4 'Steering' rewritten as a full subsection covering: what
    .start() does on an in-flight steerable task (queue + cancel +
    ack TaskRun + 'superseded' for displaced caller); what the handler
    must do (check ctx.cancel.is_set(), suspend with partial output);
    was_steered / pending_inputs / steering_generation semantics; the
    rapid-fire short-circuit drain shape; how multi-turn + steering
    compose orthogonally.
  * §4 'Results and runs' updated: TaskResult.status is now correctly
    documented as the THREE-value Literal['completed', 'suspended',
    'superseded'], distinct from the four-state TaskStatus literal.
    Documents is_completed / is_suspended / is_superseded properties
    and suspension_reason. §5 reference table for TaskResult / TaskRun /
    TaskStatus rewritten to spell out the same distinction and to
    document TaskRun's full surface (status, metadata, cancel,
    terminate, lease_expiry_count, async-for streaming).
  * Pattern C upgraded from a 6-line snippet into a full multi-turn
    chat pattern with metadata-based history, an explicit caller-side
    snippet showing turn 1 + turn 2 on the same task_id, and a
    bulletted explanation of why it works.
  * NEW Pattern F 'Steerable chat: preempting in-flight turns' showing
    the canonical ctx.cancel.is_set() short-circuit shape, the
    fast-suspend on was_steered+pending_inputs, and the caller-side
    is_superseded observation. Pairs with the new §4 steering text.

Confirms via tests/durable/test_dev_guide_review.py (7/7 pass) and full
tests/durable/ suite (289/289 pass).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] docs: correct TaskResult(status='superseded') output semantics

The previous wording 'TaskResult(status="superseded", output=None)'
overstated the contract. Per _manager.py:1465-1469 the displaced
generation's result_future is resolved with
'TaskResult(output=partial_output, status="superseded")' where
partial_output is:

- None when the displaced handler ended via ctx.suspend() (called
  from line 1158, no partial_output=... passed — the cooperative
  cancel path).
- The handler's return value when the handler completed normally
  before steering drained (called from lines 1212/1242 with
  partial_output=result — the rare 'returned just as steering
  arrived' path).

Updates the three doc sites that asserted output=None unconditionally:
the §4 'Steering' subsection, the §4 'Results and runs' bullet, and
the Pattern F caller-side snippet. is_superseded remains the correct
property to branch on.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] docs: clarify cooperative-cancellation handler strategies for steering

ctx.cancel is advisory — the handler decides what to do about it. The
previous wording implied steering forces an interrupt; that's wrong.
The handler picks one of three legitimate strategies:

- A: yield immediately on ctx.cancel.is_set() (lowest latency to the
  new turn; throws away in-flight partial work)
- B: wind down to a safe checkpoint, then suspend (one-checkpoint
  latency cost; keeps invariants clean for work with side effects)
- C: ignore cancel and run to completion (the queued input runs
  second, sequentially; required when the current input must be
  atomic — financial transaction, multi-step tool sequence)

Per the actual code at _manager.py:1155-1223, the displaced caller's
TaskResult.output depends on which strategy the handler chose:

- Strategies A and B both call ctx.suspend(...) → _try_drain_steering
  is called WITHOUT partial_output= → defaults to None → the suspend
  envelope's output=X is silently dropped on the floor when there's a
  queued steering input to drain instead.
- Strategy C calls return value → _try_drain_steering is called with
  partial_output=result → the displaced caller receives the full
  return value with status='superseded'.

Adds a new '#### Cooperative cancellation: the handler is in charge'
subsection between '#### What .start() does' and the worked example,
with a strategy table. Renames the example subsection to '#### Example:
cooperative suspend (strategy A)'. Updates the §4 Results-and-runs
bullet for status='superseded' to spell out the same A/B vs C split.
Updates the Pattern F caller-side comment to flag that r1.output=None
is a consequence of the handler's strategy choice, not an inherent
property of supersede.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: expand scope to also fix steering surface

Steering is plain multi-turn with a queueing mechanism on top. The
framework cannot observe whether a handler honored ctx.cancel — all
three handler strategies (yield immediately / wind-down-then-suspend
/ ignore) look identical at the framework boundary. A 'superseded'
status pretends the framework knows something it doesn't, and
dropping handler-emitted output on the floor (current behavior in
the suspend+queued case) leaks an implementation race into the
public surface.

Add to spec 016 (still on feature/agentserver-durable-tasks, no new
branch):

- Context: 'Scope expansion: steering is plain multi-turn' subsection
  explaining the model alignment.
- User Story 7 (P1): steering surface collapse, with 6 acceptance
  scenarios sweeping handler-end × steerer-timing.
- Edge Cases: handler-terminates-with-queued-input (cleanup in one
  store write, all queued steerers get TaskConflictError);
  suspend-persist-fails-with-queue; multiple-steerers FIFO.
- FR-020: remove 'superseded' from TaskResult.status Literal +
  remove is_superseded property.
- FR-021: suspend path delivers handler output unconditionally; drain
  runs strictly AFTER suspend resolution.
- FR-022: return/raise paths are terminal; queued inputs become
  unservicable and resolve as TaskConflictError with the appropriate
  current_status. Same store write persists the terminal transition
  and clears pending_inputs.
- FR-023: delete _pending_steering_futures; the steerer's future is
  the next generation's result future (no parallel queue).
- FR-024: _try_drain_steering is re-entry only; no partial_output
  parameter; never resolves caller-visible futures.
- SC-010 / SC-011: surface-search outcomes and a parametrized
  multi-turn-vs-steering equivalence sweep.
- Principle XII checklist updated with the 5 new affected symbols.
- 'What goes where' table updated for the steering rewrite + the
  TaskConflictError note.

No code changes in this commit. Implementation lands after the spec
is approved.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: add task API azure.core pipeline migration

Third scope expansion in spec 016. HostedTaskProvider currently uses
raw httpx.AsyncClient with no policy stack — no retry, no logging,
no distributed tracing, no request-id, no shared bearer-token
policy, no user-agent. The sibling FoundryStorageProvider already
runs on azure.core.AsyncPipelineClient and carries the
gzip-corruption lesson (ContentDecodePolicy excluded). Bring the
task client onto the same transport and inherit the same lesson.

Also: this migration is a *prerequisite* for FR-013 / FR-014 /
FR-016 / FR-017 (the eviction classifier and local-cleanup
sequence) — there's no clean seam in raw httpx for that work, and
implementing it without the pipeline would require re-inventing
azure.core's policy machinery.

Additions to spec 016:

- Context: 'Scope expansion: task API transport on azure.core
  pipeline' subsection. Calls out (a) policy chain rationale,
  (b) NO ContentDecodePolicy (gzip lesson), (c) replacement of
  raise_for_status with _classify_store_write_error funnel,
  (d) httpx dependency removal.
- User Story 8 (P2): 7 acceptance scenarios — policy chain
  composition, 503 retry behavior, 409 no-retry, gzip round-trip,
  non-JSON body classified error, distributed-tracing presence,
  httpx import removal.
- Edge cases: AsyncRetryPolicy 409 override (never retry on 409
  regardless of body); bearer-token refresh on 401 during retry;
  test-fixture migration from httpx to azure.core transport fakes.
- FR-025: AsyncPipelineClient replaces httpx.AsyncClient; per-request
  _get_headers removed in favor of AsyncBearerTokenCredentialPolicy.
- FR-026: explicit policy chain composition (RequestId, Headers,
  UserAgent, AsyncRetry with allow-list, AsyncBearerToken, task-API
  logging, DistributedTracing) — ContentDecodePolicy excluded.
- FR-027: task-API logging policy modeled on FoundryStorageLoggingPolicy
  with explicit header allow-list; no Authorization or body logs
  above DEBUG.
- FR-028: every call site funnels through _classify_store_write_error
  (FR-013); 404 → None / TaskNotFound branches preserved via
  permanent+404 mapping; non-JSON 409 classified as 'conflict' not
  'evicted' (binding_mismatch requires parseable body).
- FR-029: call-site body parsing wraps UnicodeDecodeError,
  JSONDecodeError, DecodeError — carry-forward of responses-storage
  gzip-fix invariant.
- FR-030: httpx import removal verification + pyproject.toml dep
  removal once nothing else imports it (test-only dev-dep OK).
- SC-012: surface-search assertions for import removal and policy
  chain presence.
- SC-013: behavioral assertions on fake transport — retry on 503,
  no-retry on 409, headers populated, gzip round-trip, non-JSON
  body classified error.
- 'What goes where' table: 2 new internal-only rows (pipeline =
  internal; ContentDecodePolicy ban = inline comment + spec).
- Principle XII checklist: HostedTaskProvider.__init__ credential
  re-typed to AsyncTokenCredential; bodies rewritten but public
  method signatures unchanged.

No code changes in this commit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: codify metadata auto-flush invariant across all turn boundaries

Doc claim verification: the developer guide promises 'writes you
forget to explicitly flush are still durable across a graceful
boundary' (durable-task-guide.md §4) and 'lifecycle-boundary
snapshots (framework-side)' (§5). Verified against _manager.py:

  Boundary                            Code site          Status
  ----------------------------------  ----------------   ------
  Normal suspend                      :1179              OK
  Normal completion                   :1227              OK
  Cooperative cancel / terminate      :1268              OK
  Unhandled exception (exhausted)     :1333              OK
  Suspend WITH queued steering input  :1156-1175         GAP
  Return WITH queued steering input   :1197-1223         GAP

The two steering-drain shortcuts 'continue' out of the loop without
running flush_all() AND without persisting the suspend/terminal
record. _try_drain_steering preserves the metadata buffer by sharing
the ctx.metadata reference into the new generation's context
(:1492), but if the process crashes between the drain and the next
generation's eventual terminal boundary, every unflushed write from
the displaced turn is lost (the persisted record is still the pre-
turn snapshot from the prior boundary).

This aligns naturally with FR-021 / FR-022 (steering-as-multi-turn
rewrite): the rewrite already requires the suspend / complete path
to resolve the current turn's future FIRST, before the drain may
re-enter. Tightening the same FRs to also require flush_all() at
that boundary closes the gap as a side effect.

Spec 016 edits:

- Context: scope-expansion #2 paragraph notes the verified flush gap
  with explicit line-number citations.
- FR-021: now mandates a precise 3-step ordering at the suspend
  boundary — (1) flush_all, (2) persist suspend record, (3) resolve
  result_future — with explicit pointer to _manager.py:1179 as the
  reference path that already works correctly. Calls out
  :1156-1175 as the path that MUST be replaced.
- FR-022: now mandates a precise 4-step ordering at the
  completion/raise boundary, with the same flush_all-first
  invariant and explicit pointer to _manager.py:1227. Calls out
  :1197-1223 as the path that MUST be replaced.
- FR-024: clarifies that _try_drain_steering MUST NOT touch
  ctx.metadata in any way — flush ownership belongs strictly to
  the FR-021/FR-022 boundary; the new generation reads metadata
  from the just-persisted record.
- FR-024a (NEW): codifies the metadata auto-flush invariant as
  load-bearing, lists all six boundaries that must satisfy it
  (4 already correct + 2 to be added by FR-021/FR-022), and ties
  the doc-guide claim to a testable assertion.
- SC-014 (NEW): parametrized 8-cell crash-and-reload sweep that
  asserts the marker written without explicit flush survives every
  boundary. Current code passes 4/8; after the rework lands all 8
  must pass.
- 'What goes where' table: steering row updated to call out the
  FR-024a flush invariant alongside the multi-turn framing.
- Principle XII checklist: explicitly mentions the lifecycle-flush
  invariant extension and the silent-metadata-loss behavior shift.

No code changes in this commit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: cancel signal carries reason; per-turn timeout budget

Three coupled fixes added to spec 016 (no code changes):

1. ctx.cancel becomes a CancelSignal (small public wrapper) with a
   .reason Literal['timeout', 'steering'] | None. Existing handler
   patterns (is_set(), wait()) keep working — purely additive surface.
   First-reason-wins on multiple .set() calls.

2. The timeout watchdog is respawned per LOGICAL TURN. Today it's
   spawned in _execute_task outside the steering-drain loop, so a
   steerable @task(timeout=timedelta(seconds=30)) whose first
   generation runs 25s before suspending and triggering a drain has
   only 5s left before the watchdog fires on generation 2. Per the
   'steering is plain multi-turn' framing (FR-020..FR-024a), each
   drain-driven generation IS a new turn and should get a fresh
   budget. Retries within the same generation continue to share
   the watchdog (intentional — retries don't get extra time).

3. The _timeout_watchdog docstring at _manager.py:1018-1021 claims
   the lease will eventually expire if the handler ignores cancel.
   That claim is false — renewal is driven by a separate event the
   watchdog does not touch. Per user direction we keep the watchdog
   cooperative-only and fix the docstring instead of changing
   behavior. If the handler ignores cancel, the task runs until
   process death or explicit terminate().

Additions to spec 016:

- Context: 'Scope expansion: cancel-signal carries a reason;
  per-turn timeout budget' subsection explaining all three concerns
  with line-number citations.
- US9 (P2) with 7 acceptance scenarios covering reason visibility
  under steering, reason visibility under timeout, fresh budget on
  fresh-turn re-entry, fresh budget on drain re-entry, accurate
  watchdog docstring, first-reason-wins, backward-compat.
- 4 new edge cases: watchdog respawn race (cancel previous before
  spawn); respawn-vs-retry distinction; ctx.cancel.set() ownership
  (framework-only, not handler); event-loop-shutdown cleanup.
- FR-031: CancelSignal class definition, backward-compat API,
  first-reason-wins semantics.
- FR-032: per-turn watchdog respawn — fresh handler invocation OR
  drain re-entry, NOT retry iteration; at most one live watchdog
  at a time; cleanup in finally block.
- FR-033: set reason at the source — _timeout_watchdog passes
  reason='timeout'; _try_drain_steering constructs the new ctx's
  CancelSignal already set with reason='steering' when
  cancel_requested.
- FR-034: rewrite the misleading _timeout_watchdog docstring;
  log-level stays INFO (timeout is a developer-handler concern,
  not a framework alarm); dev guide updated to match.
- SC-015: per-turn timeout budget test (regression guard for the
  shared-budget bug).
- SC-016: cancel reason visibility test (timeout / steering /
  timeout-races-steering deterministic).
- 'What goes where' table: 3 new rows for CancelSignal + per-turn
  budget + cooperative-only watchdog.
- Key Entities: CancelSignal added.
- Principle XII checklist: CancelSignal added to __all__;
  TaskContext.cancel type change documented; HostedTaskProvider
  credential re-typing already documented from Iter 10.

No code changes in this commit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: durable wall-clock per-turn timeout; recovery preserves budget

User direction: timeout should be per-turn, wall-clock, durable
across crashes within the turn. Recovery does NOT reset the budget.
New turns (fresh .run/.start, resume after suspend, drain re-entry)
DO get a fresh budget.

Today's behavior is per-invocation, in-process asyncio.sleep, with
no durable anchor: a process that crashes 25s into a 30s budget
recovers with a clean 30s. The store has created_at / updated_at /
started_at fields but the watchdog never consults any of them.

Refinements to spec 016 (no code changes):

- Context: scope-expansion #3 paragraph adds a third bullet
  explicitly calling out the non-durability gap, then states the
  desired semantic: per-turn, wall-clock, durable across crashes
  within the turn. Recovery formula spelled out as
  remaining = max(0, opts.timeout - (now - _turn_started_at)).
- US9: 3 new acceptance scenarios for the durable-recovery case
  (scenarios 8-10): mid-turn crash within budget (recovered with
  small remaining), mid-turn crash past budget (immediate cancel),
  suspended-idle-time-between-turns does not count.
- 3 new edge cases: recovery-between-turns is a new turn (re-stamp);
  legacy records without _turn_started_at fall back to full budget +
  DEBUG log; clock-skew bounds via clamping.
- FR-032 (revised): per-turn watchdog respawn now uses the durable
  remaining-budget formula with explicit case analysis for fresh /
  resume / drain / recovery / retry paths. Crash-recovery sub-case
  added with the 'fire immediately if remaining == 0' rule.
- FR-033 (revised): zero-budget crash-recovery case must pre-set the
  CancelSignal with reason='timeout' so the recovered handler sees
  the reason from the first checkpoint.
- FR-034: docstring replacement now mentions the corrected timeout
  contract ('per-turn, wall-clock, durable across crashes within
  the turn') so dev guide and source align.
- FR-035 (NEW): the durable _turn_started_at payload field — set
  sites (create_and_start, _start_existing_task on suspended->in_progress
  transition, _try_drain_steering's CAS write), explicit MUST NOT
  re-stamp on recovery, read site in watchdog spawn, clock-skew
  clamping to [0, opts.timeout], rollout fallback for legacy records.
- SC-015 (revised): 4 parametrized scenarios — fresh-turn, drain-
  re-entry, mid-turn-recovery-within-budget, mid-turn-recovery-past-
  budget. Test reads payload['_turn_started_at'] directly for
  assertions.
- SC-017 (NEW): clock-skew bounds — backwards and forwards skew
  both clamped.
- 'What goes where' table: per-turn-budget row rewritten with the
  durable-wall-clock semantic.
- Key Entities: _turn_started_at added.
- Principle XII checklist: enumerates all five new symbols and
  spells out the sharpened public contract of @task(timeout=...).

No code changes in this commit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: refresh Docs Loop section for full scope

The Authoritative-guides, Authoring-sequence, and Loop-completion-
criterion subsections were written when spec 016 covered only the
stale_timeout removal. They now reflect all 6 scope expansions:

- Authoritative guides: enumerates every public-surface contract
  that durable-task-guide.md must accurately reflect — recovery,
  TaskConflictError semantics, TaskResult.status narrowing, steering-
  as-plain-multi-turn, CancelSignal.reason, per-turn-durable-timeout,
  metadata-flush-invariant. Adds CHANGELOG.md, test_dev_guide_review.py,
  and the five source-docstring sites as additional authoritative
  surfaces.
- Authoring sequence: 5-step ordered authoring (guide → meta-test
  invariants → CHANGELOG → source docstrings → tests + code) with
  explicit per-guide-section edit list. Names the new invariants the
  meta-test must gain (zero matches for stale_timeout, superseded,
  is_superseded, _pending_steering_futures, 'lease will eventually
  expire'; presence of CancelSignal in §4 + §5; presence of 'per-turn'
  / 'wall-clock' / 'durable' in timeout description).
- Loop completion criterion: 7 concrete checks — six developer-FAQ
  questions the guide must answer correctly + the meta-test +
  package-surface grep for absent symbols + presence of new public
  symbols + CHANGELOG shape + tests free of removed symbol references
  + source-docstring vs guide agreement.

No FR changes; no SC changes; no code changes. This is purely
sharpening the doc-loop checkpoints so the implementation PR has a
concrete done-criterion for documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: close 4 constitutional review gaps

Constitutional review surfaced 4 gaps; all 4 closed in this commit.
No FR changes; no SC changes; no code changes — this is cross-doc
commitment work that the spec was deferring with TBD language.

Gap 1 (Principle IX — Samples Loop): the spec named the dev guide
and meta-test but never enumerated which samples are touched by the
contract changes. Added 'Samples affected' subsection enumerating
each surface change × each affected sample with required actions:
- FR-020 (no superseded): zero framework-level usage in samples;
  the 'superseded' string in durable_copilot/durable_langgraph/
  durable_research is an APPLICATION-level invocation_store status
  string, not the framework's TaskResult.status Literal. Verified
  via 'grep -rn TaskResult\|is_superseded\|.status ==' samples/.
  No required change; dev guide must still state the Literal is
  'completed' | 'suspended' only.
- FR-001 (no stale_timeout): zero matches in samples. No change.
- FR-031 (CancelSignal.reason): backward-compat. Recommended (not
  required) one worked example in durable_copilot.
- FR-024a (metadata-flush invariant): samples currently use
  explicit flush(); continues to work; auto-flush is additional
  guarantee not a replacement. No change.
- FR-032..FR-035 (per-turn durable timeout): zero samples set
  timeout=. Recommended one worked example.
- Transport migration (FR-025..FR-030): internal-only.
- FR-022 (TaskConflictError shape): recommended README updates in
  durable_copilot and durable_langgraph.
Loop completion criterion added: durability-sample-checklist runs
against any modified sample; deferrals recorded in tasks.md.

Gap 2 (Principle X — Contract change decision): the existing
checklist said 'Decision needed: add a Recovery subsection?
Recommend YES.' Locked in YES. The amendment is a CROSS-CUTTING
NOTE (not a new matrix row) covering binding_mismatch protocol and
the lease-state × steerable callsite outcome table. Lands in the
same PR per durability-contract.md § Change control.

Gap 3 (Principle X + XI — FR-024a boundary): FR-024a is a
durability claim but SC-014 lives in tests/durable/, not in
tests/e2e/durability_contract/. Added explicit justification: the
contract matrix is the response-stream surface; FR-024a's concern is
the core-primitive metadata namespace, one layer below. Therefore
FR-024a is in Principle XII scope (core-primitive), NOT Principle X
scope (response-stream durability matrix). The matrix does NOT need
a new row; the dev guide's 'What the framework persists at lifecycle
boundaries' table is the relevant doc surface. SC-014's home in
tests/durable/ is correct.

Gap 4 (Principle XII §5 — test-only hooks tension): FR-018
(_force_reclaim_orphans) and FR-019 (_PERIODIC_RECLAIM_INTERVAL_SECONDS
monkeypatch) appear to be _-prefixed APIs that the principle forbids
'to bypass public-surface contract enforcement'. Added per-FR
reconciliation paragraphs: these hooks make TIMING deterministic for
tests of contract BEHAVIOR; they do not bypass any contract. Tests
using them MUST assert on public-surface contract outcomes (caller-
visible TaskRun, ctx.entry_mode, store record state), never on
internal ReclaimOutcome variants returned by _reclaim_one.

Final scorecard after this commit: all 12 principles verified
compliant. Spec is ready for /speckit.plan.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [agentserver] spec 016: start cancel-surface proposal doc for iteration

User flagged on reflection that FR-031 (CancelSignal with .reason) may
duplicate signals already on TaskContext (ctx.shutdown,
ctx.pending_inputs, ctx.was_steered). Pausing FR-031 in spec 016 until
we iterate on a separate proposal that:

- Audits every public TaskContext field and what it signals today.
- Enumerates all 12 cancellation/cancel-adjacent scenarios a handler
  can face (steady state, steering pressure, timeout, shutdown,
  terminate, crash-recovery, multi-turn resume, steering re-entry,
  multiple-queued, hybrid steering+timeout, shutdown+steering,
  shutdown+t…
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.

2 participants