Skip to content

Show Python worker sessions in the guides #349

Closed

Description

@rmcdaniel

Delivered

Delivered in PR #377, merge 3688a9d115d772b80b05cf35f8463b8c9eb0d200.

Final exact-head qualification, artifact deployment and actual Pages publication passed. All sixteen live Python/worker-session routes return HTTP 200 with correct canonical/alternate links. All eight actual session-guide links navigate to their localized Python recipe, and the Python table-of-contents link works. The live example includes typed options, both activities, worker capabilities, independent resource rebuilding and handled ActivityFailed. English, Japanese and Simplified Chinese 390px light/dark views were inspected with legible fonts and no document overflow.

See the Python recipe and shared lifecycle cross-link. Verified locales: English, Ukrainian, Spanish, Brazilian Portuguese, Simplified Chinese, Japanese, French and German.

The published-package receipt preserves normal reuse, actual killed-holder/rebuilt-state recovery and explicit-close/handled-timeout controls against Python 2.9.0 / Server 2.11.0 with the published maintenance role. All three fresh originals complete within unchanged 45-second bounds. The API-only failed original remains separately recorded; explicit close has two normal scheduled repair passes, not a claimed zero. No durable-memory, terminal-session reopening or immediate session-closed exception is promised. Completed runtime, raw databases and installed fixture dependencies are retired after public audit reconciliation.

Original report and acceptance

Problem

Python supports worker sessions, but no guide shows how to use them.

  • The Python SDK exports WorkerSessionOptions, and schedule_activity takes worker_session=.
  • The affinity guide lists Python worker sessions as supported since 2.3.0.
  • The worker sessions guide shows only PHP, and the Python guide never mentions sessions. Python users who need sequential activities on one worker, for example for local files, can't find the feature.

Acceptance criteria

  • The worker sessions guide and the Python guide show a Python example: create the options, schedule several activities in one session, and handle the session ending or the worker being lost.
  • The example is checked against the published Python SDK.

Activity

  1. added
    documentationImprovements or additions to documentation
    priority:P3Lower-priority product improvement
    on Oct 21, 2026
  2. rmcdaniel commented on Oct 21, 2026

    @rmcdaniel
    MemberAuthor

    Accepted as documentation for an existing Python capability. Check the options and session-loss behavior against the published SDK, then add runnable sequential activity examples to the worker-session and Python guides with parity in all seven translated locales and their source hashes.

    If that published-package check exposes missing or incorrect session behavior, retain the failed example and open/link the product defect instead of documenting it as supported. No SDK feature or runtime acceptance is claimed by this intake. This follows the current security-release work.

  3. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    Taking the website implementation and published-package qualification. The product decision remains documentation for existing worker-session behavior. I will check Python SDK 2.9.0 against the published Server, preserve any failed originals, and add a runnable sequential-session recipe plus a concise cross-link from the embedded session guide in all eight locales. The recipe must show that worker-local state is disposable and must be rebuilt after holder loss; session affinity is not durable storage or transparent resource migration.

  4. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    Published-package qualification for the recipe in draft #377:

    • Python SDK 2.9.0, normally installed wheel SHA256 1e7547e895485dc8f670bd1b9cc34184b135f249db8da98b16b250bfc6002f73; its source identity was independently verified in SDK #186. The existing installed package was mounted read-only; no editable install or SDK source overlay.
    • Published PHP Server 2.11.0, durableworkflow/server@sha256:b29157eb2cf844916debbbb3c01b3257672e0dece778a9c6fa539043a3038f02, SQLite / Python3.12 / amd64. Isolated internal network, no host ports or production access.
    • All three fresh originals retain their authored 45-second run/execution, 40-second worker observation, activity 5-second start-to-close / 12-second schedule-to-start / 20-second schedule-to-close, session 5-second lease / 60-second TTL, and one activity attempt policy. No deadline was extended or failed original repaired to obtain acceptance.
    Control Verified outcome
    Normal Two completed activities on one holder; second reuses the process-local cache.
    Holder loss First holder is actually killed after its first activity completion. A replacement reacquires after lease expiry, rebuilds its own cache from the durable job id, completes the second activity, and the workflow succeeds.
    Explicit close The original holder explicitly closes the session. No second activity attempt is admitted. Normal runtime maintenance records ActivityTimedOut; the workflow catches ActivityFailed and completes with resource_unavailable. The session remains closed.

    The complete-role fixture uses the scheduler loop from the published 2.11.0 Compose recipe: schedule evaluation, repair pass, activity-timeout enforcement and history pruning, every10 seconds. The normal and holder-loss originals have zero repairs. The explicit-close original has two normal scheduled repair passes; they are recorded rather than reported as zero. There was no manual database write or special repair command outside the published scheduler role.

    The first API-only fixture omitted that required role. Its normal and holder-loss controls passed, but the closed-session original did not become terminal within its original40-second observation bound and remained waiting beyond its45-second runtime deadlines. That failed observation is preserved, not relabeled by the new complete-role controls. The API-only database was stopped and frozen before the fresh database was created. A failed venv launcher and missing auth-driver setting occurred before workflow admission and are separate fixture errors.

    Both current runtime processes are retired. API stopped0; the scheduler shell required termination after its10-second stop grace (137, no OOM). The final SELECT-only audit ran after both were stopped and preserves the database SHA256 f7fce5df896e1bb97c98dfb0a6ea61a3dd84da820f2b7b97c01caf4ed2f9db14. API-only snapshot SHA256 a1bb5a1a940110357a66c16e50d3121227b8a5f0a4c3157afd0d5daa6971b608 is separately preserved.

    Original results and read-only audit

    {
      "python": "2.9.0",
      "server": "2.11.0",
      "read_only_hash_preserved": true,
      "db_sha256": "f7fce5df896e1bb97c98dfb0a6ea61a3dd84da820f2b7b97c01caf4ed2f9db14",
      "originals": [
        {
          "case": "normal",
          "run_id": "01m5m0y0sk7vnvz2rzresx7kvg",
          "status": "completed",
          "closed_at": "2026-10-23 09:19:40.527648",
          "run_deadline_at": "2026-10-23 09:20:21.754318",
          "execution_deadline_at": "2026-10-23 09:20:21.754318",
          "activity_attempts": [
            {
              "activity_execution_id": "01m5m0y246c0a0yvc4htqfa5d9",
              "attempt_number": 1,
              "lease_owner": "website349-normal-a2644af1-reader",
              "status": "completed"
            },
            {
              "activity_execution_id": "01m5m0y3crvahjn0zk3k0ptxhg",
              "attempt_number": 1,
              "lease_owner": "website349-normal-a2644af1-reader",
              "status": "completed"
            }
          ],
          "repair_count": 0,
          "events": [
            "StartAccepted",
            "WorkflowStarted",
            "ActivityScheduled",
            "ActivityStarted",
            "ActivityCompleted",
            "ActivityScheduled",
            "ActivityStarted",
            "ActivityCompleted",
            "WorkflowCompleted"
          ],
          "output": {
            "status": "inspected",
            "prepared": {
              "holder": "website349-normal-a2644af1-reader",
              "rebuilt": true
            },
            "inspected": {
              "holder": "website349-normal-a2644af1-reader",
              "rebuilt": false,
              "text": "document:website349-normal-a2644af1"
            }
          }
        },
        {
          "case": "holder-loss",
          "run_id": "01m5m0y55s3pqbjrpza8y1rptq",
          "status": "completed",
          "closed_at": "2026-10-23 09:19:50.044843",
          "run_deadline_at": "2026-10-23 09:20:26.241050",
          "execution_deadline_at": "2026-10-23 09:20:26.241050",
          "activity_attempts": [
            {
              "activity_execution_id": "01m5m0y6caj38z3c20pe29matp",
              "attempt_number": 1,
              "lease_owner": "website349-holder-loss-e8d9facb-holder",
              "status": "completed"
            },
            {
              "activity_execution_id": "01m5m0y8qm5xme39r839v6cpqe",
              "attempt_number": 1,
              "lease_owner": "website349-holder-loss-e8d9facb-reader",
              "status": "completed"
            }
          ],
          "repair_count": 0,
          "events": [
            "StartAccepted",
            "WorkflowStarted",
            "ActivityScheduled",
            "ActivityStarted",
            "ActivityCompleted",
            "ActivityScheduled",
            "ActivityStarted",
            "ActivityCompleted",
            "WorkflowCompleted"
          ],
          "output": {
            "status": "inspected",
            "prepared": {
              "holder": "website349-holder-loss-e8d9facb-holder",
              "rebuilt": true
            },
            "inspected": {
              "holder": "website349-holder-loss-e8d9facb-reader",
              "rebuilt": true,
              "text": "document:website349-holder-loss-e8d9facb"
            }
          }
        },
        {
          "case": "closed",
          "run_id": "01m5m0yeexeqs6mrkt02wh3pgd",
          "status": "completed",
          "closed_at": "2026-10-23 09:20:17.177913",
          "run_deadline_at": "2026-10-23 09:20:35.740211",
          "execution_deadline_at": "2026-10-23 09:20:35.740211",
          "activity_attempts": [
            {
              "activity_execution_id": "01m5m0yfphynem3dadmf5k8zp8",
              "attempt_number": 1,
              "lease_owner": "website349-closed-8a7e142c-holder",
              "status": "completed"
            }
          ],
          "repair_count": 2,
          "events": [
            "StartAccepted",
            "WorkflowStarted",
            "ActivityScheduled",
            "ActivityStarted",
            "ActivityCompleted",
            "ActivityScheduled",
            "ActivityTimedOut",
            "WorkflowCompleted"
          ],
          "output": {
            "status": "resource_unavailable",
            "job_id": "website349-closed-8a7e142c"
          }
        }
      ]
    }

    Reproducible fixture

    Bootstrap a fresh database with the exact Server image, DB_CONNECTION=sqlite, DB_DATABASE=/data/database.sqlite, DW_AUTH_DRIVER=none and DW_WORKER_POLL_TIMEOUT=1. Authentication is disabled only inside this isolated, portless fixture. Run the API and the published singleton scheduler against that database. In a clean Python3.12 environment, normally install durable-workflow==2.9.0, put the following files in /task and run python -u /task/probe.py. The probe's database access only observes the first completed activity through a read-only SQLite connection; all workflow/session mutations use SDK calls. Stop both Server roles before python /task/audit.py.

    example.py

    from durable_workflow import ActivityFailed, WorkerSessionOptions, activity, workflow
    
    # Disposable process-local state. Rebuild it from durable business input.
    documents = {}
    
    def ensure_document(job_id):
        rebuilt = job_id not in documents
        if rebuilt:
            documents[job_id] = {"text": "document:" + job_id}
        return documents[job_id], rebuilt
    
    @activity.defn(name="prepare_document")
    async def prepare_document(job_id):
        document, rebuilt = ensure_document(job_id)
        return {"holder": activity.context().info.worker_id, "rebuilt": rebuilt}
    
    @activity.defn(name="inspect_document")
    async def inspect_document(job_id):
        document, rebuilt = ensure_document(job_id)
        return {"holder": activity.context().info.worker_id,
                "rebuilt": rebuilt, "text": document["text"]}
    
    @workflow.defn(name="inspect_document_workflow")
    class InspectDocumentWorkflow:
        def run(self, ctx, job_id):
            session = WorkerSessionOptions(
                session_id="documents:" + job_id,
                requirements=("fs:documents",),
                lease_seconds=5,
                ttl_seconds=60,
                max_concurrent_activities=1,
                allow_reacquire_after_failure=True,
            )
            options = dict(worker_session=session,
                           start_to_close_timeout=5,
                           schedule_to_start_timeout=12,
                           schedule_to_close_timeout=20,
                           retry_policy={"max_attempts": 1})
            try:
                prepared = yield ctx.schedule_activity("prepare_document", [job_id], **options)
                inspected = yield ctx.schedule_activity("inspect_document", [job_id], **options)
            except ActivityFailed as error:
                if error.activity_type not in {"prepare_document", "inspect_document"}:
                    raise
                return {"status": "resource_unavailable", "job_id": job_id}
            return {"status": "inspected", "prepared": prepared, "inspected": inspected}

    probe.py

    import asyncio, importlib.metadata, json, os, sqlite3, sys, uuid
    from pathlib import Path
    from durable_workflow import Client, Worker
    from example import InspectDocumentWorkflow, prepare_document, inspect_document
    
    ROOT=Path('/task')
    def prepared_completed(run_id):
        with sqlite3.connect('file:/task/data/database.sqlite?mode=ro',uri=True) as c:
            return c.execute("select count(*) from activity_executions where workflow_run_id=? and activity_type='prepare_document' and status='completed'",[run_id]).fetchone()[0] == 1
    
    async def holder(identity):
        async with Client('http://api:8080') as client:
            worker=Worker(client,task_queue=identity,worker_id=identity+'-holder',activities=[prepare_document],capabilities=['fs:documents'],poll_timeout=1)
            await worker.run_until(workflow_id=identity,timeout=40,poll_interval=.05)
    
    async def main():
        assert importlib.metadata.version('durable-workflow')=='2.9.0'
        records=[]
        async with Client('http://api:8080') as client:
            for case in ['normal','holder-loss','closed']:
                identity='website349-'+case+'-'+uuid.uuid4().hex[:8]
                handle=await client.start_workflow(workflow_type='inspect_document_workflow',task_queue=identity,workflow_id=identity,input=[identity],run_timeout_seconds=45,execution_timeout_seconds=45)
                state=await handle.describe()
                child=None
                if case!='normal':
                    child=await asyncio.create_subprocess_exec(sys.executable,__file__,'holder',identity,stdout=asyncio.subprocess.DEVNULL)
                worker=Worker(client,task_queue=identity,worker_id=identity+'-reader',workflows=[InspectDocumentWorkflow],activities=[prepare_document,inspect_document] if case=='normal' else [inspect_document],capabilities=['fs:documents'],poll_timeout=1)
                running=asyncio.create_task(worker.run_until(workflow_id=identity,timeout=40,poll_interval=.05))
                try:
                    if child:
                        async with asyncio.timeout(10):
                            while not prepared_completed(state.run_id):
                                if child.returncode is not None:raise AssertionError(('holder exited early',child.returncode))
                                await asyncio.sleep(.05)
                        if case=='holder-loss':
                            child.kill();await child.wait()
                        else:
                            receipt=await client.close_worker_session(identity+'-holder','documents:'+identity,'qualification_explicit_close')
                            (ROOT/'closed-receipt.json').write_text(json.dumps(receipt,indent=2)+'\n')
                    await running
                    result=await handle.result(timeout=2)
                    if case=='closed':assert result=={'status':'resource_unavailable','job_id':identity},result
                    else:
                        assert result['status']=='inspected',result
                        assert result['inspected']['text']=='document:'+identity,result
                        assert result['inspected']['rebuilt'] is (case=='holder-loss'),result
                        assert (result['prepared']['holder']==result['inspected']['holder']) is (case=='normal'),result
                    record={'case':case,'workflow_id':identity,'run_id':state.run_id,'output':result}
                    records.append(record);print(json.dumps(record),flush=True)
                    (ROOT/'outcomes.json').write_text(json.dumps(records,indent=2)+'\n')
                finally:
                    if not running.done():
                        await worker.stop();await asyncio.gather(running,return_exceptions=True)
                    if child and child.returncode is None:
                        child.terminate();await child.wait()
    
    if __name__=='__main__':
        asyncio.run(holder(sys.argv[2]) if len(sys.argv)>1 else main())

    audit.py

    from pathlib import Path
    import sqlite3,json,hashlib
    root=Path(__file__).parent;db=root/'data/database.sqlite'
    before=hashlib.sha256(db.read_bytes()).hexdigest()
    c=sqlite3.connect('file:'+str(db)+'?mode=ro',uri=True);c.row_factory=sqlite3.Row
    audited=[]
    for original in json.loads((root/'outcomes.json').read_text()):
        run=c.execute('select * from workflow_runs where id=?',[original['run_id']]).fetchone()
        assert run['status']=='completed'
        assert run['closed_at']<=run['run_deadline_at'] and run['closed_at']<=run['execution_deadline_at']
        acts=c.execute('select * from activity_executions where workflow_run_id=? order by sequence',[run['id']]).fetchall()
        assert len(acts)==2 and acts[0]['status']=='completed' and acts[0]['attempt_count']==1
        second=acts[1];closed=original['case']=='closed'
        assert second['status']==('failed' if closed else 'completed')
        assert second['attempt_count']==(0 if closed else 1)
        opts=json.loads(second['activity_options'])
        assert opts['worker_session']['session_id']=='documents:'+original['workflow_id']
        assert opts['schedule_to_start_timeout']==12 and opts['schedule_to_close_timeout']==20
        events=[r[0] for r in c.execute('select event_type from workflow_history_events where workflow_run_id=? order by sequence',[run['id']])]
        assert events.count('WorkflowCompleted')==1 and 'WorkflowFailed' not in events
        assert events.count('ActivityTimedOut')==(1 if closed else 0)
        session=c.execute('select * from workflow_worker_sessions where session_id=?',['documents:'+original['workflow_id']]).fetchone()
        assert session['status']=='closed'
        attempts=[dict(r) for r in c.execute('select activity_execution_id,attempt_number,lease_owner,status from activity_attempts where activity_execution_id in (?,?)',[a['id'] for a in acts])]
        repairs=sum(r[0] for r in c.execute('select repair_count from workflow_tasks where workflow_run_id=?',[run['id']]))
        audited.append({'case':original['case'],'run_id':run['id'],'status':run['status'],'closed_at':run['closed_at'],'run_deadline_at':run['run_deadline_at'],'execution_deadline_at':run['execution_deadline_at'],'activity_attempts':attempts,'repair_count':repairs,'events':events,'output':original['output']})
    c.close();assert before==hashlib.sha256(db.read_bytes()).hexdigest()
    receipt={'python':'2.9.0','server':'2.11.0','read_only_hash_preserved':True,'db_sha256':before,'originals':audited}
    (root/'audit.json').write_text(json.dumps(receipt,indent=2)+'\n')
    print(json.dumps(receipt))

    Frozen API-only original observations

    The following read-only snapshot retains the failed closed-session original and the two successful API-only controls. It is separate from complete-role acceptance. Raw fixture databases are retired after recording these hashes, observations and reproducible sources; no failed original is relabeled or reopened.

    {
      "db_sha256": "a1bb5a1a940110357a66c16e50d3121227b8a5f0a4c3157afd0d5daa6971b608",
      "hash_preserved": true,
      "runs": [
        {
          "id": "01m5m0sgddadsknsa6c6wy9gmk",
          "status": "completed",
          "run_deadline_at": "2026-10-23 09:17:53.908688",
          "execution_deadline_at": "2026-10-23 09:17:53.908688",
          "closed_at": "2026-10-23 09:17:13.138364"
        },
        {
          "id": "01m5m0snbbh49p9dgfne8dx5tv",
          "status": "completed",
          "run_deadline_at": "2026-10-23 09:17:58.963021",
          "execution_deadline_at": "2026-10-23 09:17:58.963021",
          "closed_at": "2026-10-23 09:17:21.960562"
        },
        {
          "id": "01m5m0sy1ajxmx8gv6fcmrf690",
          "status": "waiting",
          "run_deadline_at": "2026-10-23 09:18:07.858257",
          "execution_deadline_at": "2026-10-23 09:18:07.858257",
          "closed_at": null
        }
      ],
      "activities": [
        {
          "id": "01m5m0sjasbc41nhgyvkd69n6z",
          "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk",
          "activity_type": "prepare_document",
          "status": "completed",
          "attempt_count": 1,
          "schedule_to_close_deadline_at": "2026-10-23 09:17:30.871705"
        },
        {
          "id": "01m5m0skfy7ansd6s4ftzbmksj",
          "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk",
          "activity_type": "inspect_document",
          "status": "completed",
          "attempt_count": 1,
          "schedule_to_close_deadline_at": "2026-10-23 09:17:32.061721"
        },
        {
          "id": "01m5m0spqe9bykcs7vvk89agcj",
          "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv",
          "activity_type": "prepare_document",
          "status": "completed",
          "attempt_count": 1,
          "schedule_to_close_deadline_at": "2026-10-23 09:17:35.374060"
        },
        {
          "id": "01m5m0srte260rm68xfkpc8gc2",
          "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv",
          "activity_type": "inspect_document",
          "status": "completed",
          "attempt_count": 1,
          "schedule_to_close_deadline_at": "2026-10-23 09:17:37.518061"
        },
        {
          "id": "01m5m0sz4krpatd38ethpb3pn3",
          "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690",
          "activity_type": "prepare_document",
          "status": "completed",
          "attempt_count": 1,
          "schedule_to_close_deadline_at": "2026-10-23 09:17:43.986724"
        },
        {
          "id": "01m5m0t1ke53hawq741wpjpvkw",
          "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690",
          "activity_type": "inspect_document",
          "status": "pending",
          "attempt_count": 0,
          "schedule_to_close_deadline_at": "2026-10-23 09:17:46.509846"
        }
      ],
      "tasks": [
        {
          "id": "01m5m0sgm1n81k20qjr7yxqgsp",
          "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0sjbf98k5jzdswdgwbybk",
          "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0sk36efrr1mr68ssc3g6y",
          "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0skg3w64jwckddgq0s7jj",
          "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0sm3pr48njjv69c5ygw8r",
          "workflow_run_id": "01m5m0sgddadsknsa6c6wy9gmk",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0snbpq8pvzdkffyw7mw48",
          "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0spqmgb73ve0szg5cwjxm",
          "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0srafjwrkfpy9zy9bef92",
          "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0srtpnywf7n674h64y3s7",
          "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0swkgzr6dk8ycsdce9ha6",
          "workflow_run_id": "01m5m0snbbh49p9dgfne8dx5tv",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0sy1t3fasza3heeyvxwcf",
          "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0sz4tqa6pavte9vd5b7d3",
          "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0t0zw9z0pe9e6eanqqg2q",
          "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690",
          "repair_count": 0,
          "status": "completed"
        },
        {
          "id": "01m5m0t1kmph9sjnwsqb7wgjmq",
          "workflow_run_id": "01m5m0sy1ajxmx8gv6fcmrf690",
          "repair_count": 0,
          "status": "ready"
        }
      ],
      "session_tables": [
        "workflow_worker_sessions"
      ]
    }
  5. rmcdaniel commented on Oct 23, 2026

    @rmcdaniel
    MemberAuthor

    Delivered in PR #377, merge 3688a9d115d772b80b05cf35f8463b8c9eb0d200.

    Final exact-head qualification, artifact deployment and actual Pages publication passed. All sixteen live Python/worker-session routes return HTTP 200 with correct canonical/alternate links. All eight actual session-guide links navigate to their localized Python recipe, and the Python table-of-contents link works. The live example includes typed options, both activities, worker capabilities, independent resource rebuilding and handled ActivityFailed. English, Japanese and Simplified Chinese 390px light/dark views were inspected with legible fonts and no document overflow.

    See the Python recipe and shared lifecycle cross-link. Verified locales: English, Ukrainian, Spanish, Brazilian Portuguese, Simplified Chinese, Japanese, French and German.

    The published-package receipt preserves normal reuse, actual killed-holder/rebuilt-state recovery and explicit-close/handled-timeout controls against Python 2.9.0 / Server 2.11.0 with the published maintenance role. All three fresh originals complete within unchanged 45-second bounds. The API-only failed original remains separately recorded; explicit close has two normal scheduled repair passes, not a claimed zero. No durable-memory, terminal-session reopening or immediate session-closed exception is promised. Completed runtime, raw databases and installed fixture dependencies are retired after public audit reconciliation.

  6. added
    status:doneDerived from the authoritative closed issue state
    completion:evidence-verifiedAcceptance, fixed version, and required operational evidence are publicly verified
    and removed
    status:readyReady for implementation
    completion:evidence-requiredClose only after all explicit acceptance and operational evidence is public
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    completion:evidence-verifiedAcceptance, fixed version, and required operational evidence are publicly verifieddocumentationImprovements or additions to documentationpriority:P3Lower-priority product improvementstatus:doneDerived from the authoritative closed issue state

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions