Skip to content

feat: implement scope organization runtime for RFC #1345 - #1401

Open
PsiACE wants to merge 9 commits into
masterfrom
codex/scope-organization-runtime
Open

feat: implement scope organization runtime for RFC #1345#1401
PsiACE wants to merge 9 commits into
masterfrom
codex/scope-organization-runtime

Conversation

@PsiACE

@PsiACE PsiACE commented Aug 30, 2026

Copy link
Copy Markdown
Member

Which issue or RFC does this PR close?

Implements the runtime design in #1345.

Rationale for this change

Scope is the durable boundary for memory ownership, isolation, sharing, and reporting. The runtime and Agent integrations need to use the same server-owned Scope model instead of Project, Workstream, or client-generated Scope identifiers.

What changes are included in this PR?

  • Adds durable Scope hierarchy, metadata, default selection, and session or workspace bindings.
  • Adds direct Context References and exact cross-Scope Artifact References with provenance.
  • Uses Scope selection for context reads, statistics, Handoff Reports, and artifact publication.
  • Removes the Project and Workstream report model and its compatibility paths.
  • Updates bundled Agent integrations to resolve, reuse, and derive server-owned Scopes.
  • Updates HTTP, MCP, generated clients, configuration, documentation, and acceptance coverage.
  • Makes the E2E harness provision real Scopes before running Agent workflows.

Are there any user-facing changes?

Yes. This is a breaking change:

  • Scope replaces Project and Workstream as the organization and reporting boundary.
  • Scope IDs are generated by the service; integrations must resolve or create a Scope before writing.
  • Context and report queries select all visible Scopes, one exact Scope, or a Scope subtree.
  • No compatibility or migration period is included.

How was this change tested?

  • make check
  • make test
  • make contract-test
  • make docs-test
  • make harness-check
  • GitHub Actions on Python 3.11, 3.12, 3.13, and 3.14
  • SQLite and OceanBase acceptance scenarios

AI usage statement

OpenAI Codex was used for code analysis, implementation, tests, and documentation editing.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

license-eye has checked 978 files.

Valid Invalid Ignored Fixed
704 21 253 0
Click to see the invalid file list
  • integrations/codex/plugins/powercontext/hooks/bind_tools.py
  • integrations/codex/plugins/powercontext/hooks/session_binding.py
  • integrations/codex/plugins/powercontext/scripts/scope_binding.py
  • src/powercontext/builtin/handoff_report/init.py
  • src/powercontext/builtin/handoff_report/adapters.py
  • src/powercontext/builtin/handoff_report/canonical.py
  • src/powercontext/builtin/handoff_report/errors.py
  • src/powercontext/builtin/handoff_report/protocols.py
  • src/powercontext/builtin/handoff_report/rendering.py
  • src/powercontext/builtin/scope/init.py
  • src/powercontext/builtin/scope/application.py
  • src/powercontext/builtin/scope/errors.py
  • src/powercontext/builtin/scope/models.py
  • src/powercontext/builtin/scope/repository.py
  • src/powercontext/server/static/handoff-report.js
  • src/powercontext/server/static/scope-selection.js
  • src/powercontext/server/templates/pages/handoff_report.html
  • tests/builtin/test_scope_application.py
  • tests/codex_plugin/test_scope_binding.py
  • tests/test_handoff_report.py
  • tests/test_scope_api.py
Use this command to fix any missing license headers
```bash

docker run -it --rm -v $(pwd):/github/workspace apache/skywalking-eyes header fix

</details>

@PsiACE PsiACE changed the title draft: evaluate scope organization runtime for RFC #1345 feat: implement scope organization runtime for RFC #1345 Sep 1, 2026
@PsiACE
PsiACE marked this pull request as ready for review September 1, 2026 08:22
github-actions[bot]

This comment was marked as outdated.

@PsiACE

PsiACE commented Sep 2, 2026

Copy link
Copy Markdown
Member Author

POWERCONTEXT: AGENT <-> SCOPE INTERACTION MAP

Transport
---------
Agent tool call ---- POST /mcp ----> OpenAPI bridge ----> /v1/...
Prompt hook --------------------------------------------> /v1/...

A Scope is server-owned. Agent, session, workspace, repository,
and branch are only external identities used to select a Scope.

SCENARIO 1: NEW AGENT SESSION

 [Agent A / Session A]
          |
          | POST /v1/scope-bindings/resolve
          | priority:
          | explicit > session > workspace > default
          v
     [Default Scope]
          ^
          |
          | PUT /v1/scope-bindings
          | Session A -> Default Scope
          |
 [Durable session binding]

First prompt:

 [Agent A]
     |
     +-- POST /v1/context/prepare
     |      scope_id = Default Scope
     |      result -> context injected into Agent turn
     |
     `-- POST /v1/sources/content
            scope_id = Default Scope
            result -> Source stored in Default Scope

SCENARIO 2: RESUME OR REUSE AN EXISTING SCOPE

Resume the same session:

 [Agent A / Session A]
          |
          | POST /v1/scope-bindings/resolve
          v
     [Scope X]
     session binding hit

Start a new session with a workspace binding:

 [Agent B / Session B]
          |
          | resolve: session miss -> workspace hit
          | POST /v1/scope-bindings/resolve
          v
     [Scope X]
          ^
          |
          | PUT /v1/scope-bindings
          | Session B -> Scope X

Explicitly reuse or switch to Scope Y:

 [Agent A / Session A]
          |
          | set_scope_binding via POST /mcp
          | PUT /v1/scope-bindings
          v
     [Scope Y]

Next request uses Scope Y:

 [Agent A] -- POST /v1/context/prepare --> [Scope Y]
 [Agent A] -- POST /v1/sources/content --> [Scope Y]

SCENARIO 3: CREATE A NEW ISOLATED SCOPE

 [Agent A]
     |
     | create_scope via POST /mcp
     | POST /v1/scopes
     v
 [New Scope Y]
     |
     | server generates opaque scp_* ID
     | creation does NOT change Agent binding
     v
 [Agent A still bound to Scope X]

Explicit switch:

 [Agent A]
     |
     | set_scope_binding via POST /mcp
     | PUT /v1/scope-bindings
     v
 [Scope Y becomes current]

 [Agent A] -- POST /v1/sources/content --> [Scope Y]

SCENARIO 4: MULTIPLE AGENTS

Share all state:

 [Agent A / Session A] ----+
                           |
                           v
                        [Scope X]
                           ^
                           |
 [Agent B / Session B] ----+

Both sessions are bound separately to Scope X.

Shared inside Scope X:

  • Source journal
  • Memory head
  • Artifact families
  • Handoff lifecycle
  • Statistics

Isolate independently continuable work:

                    [Root Scope]
                         |
             +-----------+-----------+
             |                       |
             v                       v
      [Agent A Scope]          [Agent B Scope]
      independent state        independent state

Create children:
POST /v1/scopes
parent_scope_id = Root Scope

Parent means organization only. It does not inherit or share data.

SCENARIO 5: READ FROM OR DELIVER ACROSS SCOPES

Direct Context Reference:

 [Agent A] ---> [Child Scope] -- context reference --> [Shared Scope]
                     |
                     | POST /v1/context/prepare
                     | reads Child + direct references
                     |
                     `-- POST /v1/sources/content
                         writes only to Child Scope

Deliver one accepted result:

 [Child Scope]
      |
      | exact Artifact revision
      | POST /v1/artifact-publications
      v
 [Target Scope]

Publication copies only the selected Artifact revision.
It does not move Sources, other revisions, Memory, or Handoff history.

KEY RULES

  1. One Agent request has one current Scope.
  2. Bindings select a Scope; they do not create data partitions.
  3. POST /v1/scopes creates a Scope but never binds the Agent.
  4. PUT /v1/scope-bindings changes the Agent session's current Scope.
  5. Parent organizes Scopes but grants no data inheritance.
  6. Context References add direct reads; writes remain in current Scope.
  7. Artifact publication is exact, explicit cross-Scope delivery.

@PsiACE
PsiACE requested a review from Teingi September 2, 2026 08:54
@PsiACE
PsiACE force-pushed the codex/scope-organization-runtime branch from 907b730 to 605701b Compare September 2, 2026 08:55
try:
scope = await self._runtime.scopes.get(self.scope_id)
except ScopeNotFoundError:
pass

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Swallowing ScopeNotFoundError makes an unregistered Scope behave like a valid legacy partition. On this head, capturing a Source under project:orphan succeeded, but list_scopes and an all selection contained only the default Scope, leaving the durable data invisible to Statistics, Dashboard, and Handoff Report. Please validate every current-scope data-plane operation through ScopeApplication (with an explicit migration path for legacy partitions) instead of continuing after this exception.

_allow(dict(tool_input))
return 0
if operation not in _SCOPE_BOUND_OPERATIONS:
return 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This pass-through leaves 14 OpenAPI operations marked x-powercontext-scope-mode: current outside the binding guard, including prepare_context, flush_memory, and prepare_handoff. A prepare_context PreToolUse payload with scope_id: "agent-selected" produces no hook output, so the model-supplied Scope is neither replaced nor denied. Please derive or validate this set against the generated OpenAPI metadata and add a contract test that every current operation is guarded.

target_scope_id,
artifact_type,
ref,
source.content,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copying only source.content is insufficient for the Memory family. Publishing an exact Memory revision on this head returned a new memory/pub_*@1, but reading an entry through that target citation raised ArtifactNotFoundError, and the target Scope still had no current Memory. The entry versions/heads and target head integration were not copied. Please make Memory publication family-aware and atomic, or reject it until the complete target state can be created.

self._database = database
self._repository = ScopeRepository() if repository is None else repository
self._id_factory = generate_scope_id if id_factory is None else id_factory
self._write_lock = asyncio.Lock()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This lock only serializes writes within one ScopeApplication instance. With two server instances sharing OceanBase, concurrent A.parent=B and B.parent=A updates can both validate the old graph and commit different rows; the FK and per-row version checks do not detect the resulting cycle. Please serialize relationship mutations at the database level (or use a retryable serializable/locked ancestor check) and cover this race with two application instances.

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