generated from coulomb/repo-seed
Add activity-core scope context API
This commit is contained in:
@@ -1,152 +1,178 @@
|
||||
---
|
||||
id: RREG-WP-0012
|
||||
type: workplan
|
||||
domain: custodian
|
||||
title: "Activity-Core Scope Context API"
|
||||
domain: capabilities
|
||||
repo: repo-scoping
|
||||
status: active
|
||||
state_hub_workstream_id: 83a43ab6-d566-41e0-afd7-f2833812564f
|
||||
tasks:
|
||||
- id: T01
|
||||
title: Define context query response schema for activity-core
|
||||
state_hub_task_id: 83482f1d-4f44-440d-a27f-0c375786b87f
|
||||
status: todo
|
||||
- id: T02
|
||||
title: Verify/implement GET /repos/{slug}/scope endpoint
|
||||
state_hub_task_id: 75f6123a-2703-42ec-9564-dd665e16c5ef
|
||||
status: todo
|
||||
- id: T03
|
||||
title: Add scope_md_exists boolean to scope response
|
||||
state_hub_task_id: cb0b17f4-30c4-4d68-b2ff-9a3fa9ef73a3
|
||||
status: todo
|
||||
- id: T04
|
||||
title: Write integration test for activity-core repo-scoping adapter
|
||||
state_hub_task_id: f70c1c58-b23f-4b61-adca-a02644b6ee7e
|
||||
status: todo
|
||||
owner: codex
|
||||
topic_slug: foerster-capabilities
|
||||
created: "2026-05-14"
|
||||
updated: "2026-05-15"
|
||||
state_hub_workstream_id: "83a43ab6-d566-41e0-afd7-f2833812564f"
|
||||
---
|
||||
|
||||
# RREG-WP-0012: Activity-Core Context API
|
||||
# Activity-Core Scope Context API
|
||||
|
||||
## Purpose
|
||||
activity-core's `RunActivityWorkflow` resolves repository context before
|
||||
evaluating rules and instructions. One of its context sources is repo-scoping:
|
||||
given a repo slug, activity-core needs a compact capability profile with
|
||||
capability names, classification tags, whether a `SCOPE.md` is known to exist,
|
||||
and a short scope summary when available.
|
||||
|
||||
activity-core's `RunActivityWorkflow` resolves context before evaluating rules
|
||||
and instructions. One of its context sources is repo-scoping: given a repo slug,
|
||||
it queries repo-scoping for the repo's capability profile (tags, capabilities,
|
||||
whether a SCOPE.md exists, etc.).
|
||||
This is a contract workplan. The goal is a stable JSON interface for
|
||||
activity-core, not new scope analysis functionality.
|
||||
|
||||
This workplan ensures repo-scoping exposes a stable, documented context API
|
||||
endpoint that activity-core can call reliably. It is a **contract workplan** —
|
||||
the goal is a stable interface, not new functionality.
|
||||
## Contract Decision
|
||||
|
||||
## Context
|
||||
Do not change `GET /repos/{repo_slug}/scope`. That endpoint already exists as
|
||||
the generated `SCOPE.md` Markdown preview endpoint, with sibling diff/write
|
||||
routes. Changing its success media type or response shape would break existing
|
||||
repo-scoping API clients and the OpenAPI contract policy.
|
||||
|
||||
- **activity-core WP-0003** (in progress): implements `RepoScopingContextResolver`
|
||||
in `src/activity_core/context_resolvers/repo_scoping.py` which calls
|
||||
`GET /repos/{slug}/scope` on the repo-scoping API.
|
||||
- **repo-scoping** already has a scope API; the question is whether it returns
|
||||
the exact fields activity-core needs, and whether those fields are stable.
|
||||
Add a new provider-side context endpoint instead:
|
||||
|
||||
See: `docs/adr/adr-001-event-bridge-architecture.md` in activity-core, section
|
||||
on context resolution adapters.
|
||||
```text
|
||||
GET /repos/{repo_slug}/scope/context
|
||||
```
|
||||
|
||||
## Scope
|
||||
|
||||
**In scope:**
|
||||
- Documenting and stabilizing the `/repos/{slug}/scope` endpoint response schema
|
||||
- Adding `scope_md_exists` if not present
|
||||
- Contract/integration test
|
||||
|
||||
**Out of scope:**
|
||||
- Dynamic operational state (that is the state hub's domain, not repo-scoping's)
|
||||
- NATS-based context queries (REST only for now)
|
||||
- Any new scope analysis features
|
||||
|
||||
## Contract
|
||||
|
||||
The endpoint `GET /repos/{slug}/scope` must return:
|
||||
The endpoint returns `application/json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"repo_slug": "string",
|
||||
"capabilities": ["string"],
|
||||
"tags": ["string"],
|
||||
"repo_slug": "repo-scoping",
|
||||
"capabilities": ["Generate SCOPE.md"],
|
||||
"tags": ["api", "generation", "scope"],
|
||||
"scope_md_exists": true,
|
||||
"scope_summary": "string or null"
|
||||
"scope_summary": "Repository Scoping maps repositories into reviewable scope graphs."
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Notes |
|
||||
| Field | Type | Required | Source |
|
||||
|---|---|---|---|
|
||||
| `repo_slug` | string | yes | URL-safe identifier |
|
||||
| `capabilities` | string[] | yes | Declared capability types |
|
||||
| `tags` | string[] | yes | Free-form classification tags |
|
||||
| `scope_md_exists` | boolean | yes | True if SCOPE.md present in repo root |
|
||||
| `scope_summary` | string or null | no | First paragraph of SCOPE.md if present |
|
||||
| `repo_slug` | string | yes | Slug requested by the caller after normal slugification |
|
||||
| `capabilities` | string[] | yes | Approved capability names from the repository ability map |
|
||||
| `tags` | string[] | yes | Stable, sorted union of approved ability and capability `primary_class` values plus their `attributes` |
|
||||
| `scope_md_exists` | boolean | yes | True when repo-scoping can inspect a local or cached checkout and root `SCOPE.md` exists; false when absent or unknown |
|
||||
| `scope_summary` | string or null | yes | First non-empty paragraph of root `SCOPE.md` when inspectable; otherwise approved scope description, repository description, or null |
|
||||
|
||||
This schema is the contract. Changes must be versioned and communicated to the
|
||||
activity-core agent before deployment.
|
||||
The `scope_md_exists` field is intentionally conservative. The provider must
|
||||
not clone or fetch remote repositories merely to answer this lightweight context
|
||||
query. If no local or cached checkout is available, the value is `false` and
|
||||
`scope_summary` falls back to registry metadata.
|
||||
|
||||
## Tasks
|
||||
activity-core should call this new endpoint, not the Markdown preview endpoint.
|
||||
If a future contract needs an unknown/absent distinction for `SCOPE.md`, add a
|
||||
new optional field such as `scope_md_status` rather than changing the boolean.
|
||||
|
||||
### T01 — Define context query response schema for activity-core
|
||||
|
||||
Write a JSON Schema file (`docs/schemas/repo-scope-context-response.json`) that
|
||||
formalizes the response shape above. Include field descriptions and examples.
|
||||
This becomes the machine-readable contract between repo-scoping and activity-core.
|
||||
|
||||
### T02 — Verify/implement GET /repos/{slug}/scope endpoint
|
||||
|
||||
Check the existing API for `GET /repos/{slug}/scope`. Verify it returns all
|
||||
required fields. If missing fields, implement them. If the endpoint does not
|
||||
exist, implement it.
|
||||
|
||||
The endpoint is called by activity-core's `RepoScopingContextResolver` and
|
||||
must be stable — no breaking changes without coordinating with activity-core.
|
||||
|
||||
### T03 — Add scope_md_exists boolean to scope response
|
||||
|
||||
Ensure `scope_md_exists` is present and accurate: `true` if a `SCOPE.md` file
|
||||
exists in the repo's root directory on the default branch, `false` otherwise.
|
||||
|
||||
This field is used by activity-core rules to decide whether to emit a
|
||||
generate-SCOPE.md task for a repo.
|
||||
|
||||
### T04 — Write integration test for activity-core repo-scoping adapter
|
||||
|
||||
Write a contract test that:
|
||||
1. Calls `GET /repos/{slug}/scope` with a known test repo slug
|
||||
2. Asserts all required fields are present
|
||||
3. Asserts types match the schema (scope_md_exists is bool, capabilities is list, etc.)
|
||||
|
||||
This test lives in repo-scoping as the provider-side contract test. It should
|
||||
run in CI so contract drift is caught before it breaks activity-core.
|
||||
|
||||
**Test file**: `tests/test_scope_context_api.py` (or alongside existing API tests)
|
||||
|
||||
## Build Order
|
||||
## T01: Define Context Query Response Schema
|
||||
|
||||
```task
|
||||
id: RREG-WP-0012-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "83482f1d-4f44-440d-a27f-0c375786b87f"
|
||||
```
|
||||
T01 (schema) → T02 (implement) → T03 (add field) → T04 (test)
|
||||
|
||||
Write `docs/schemas/repo-scope-context-response.json` to formalize the response
|
||||
shape above. Include field descriptions, required fields, `additionalProperties:
|
||||
false`, and at least one complete example.
|
||||
|
||||
Acceptance criteria:
|
||||
- The schema describes `repo_slug`, `capabilities`, `tags`, `scope_md_exists`,
|
||||
and `scope_summary`.
|
||||
- Required fields match the contract table.
|
||||
- The schema is easy for activity-core to vendor or validate against.
|
||||
|
||||
## T02: Implement Scope Context Endpoint
|
||||
|
||||
```task
|
||||
id: RREG-WP-0012-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "75f6123a-2703-42ec-9564-dd665e16c5ef"
|
||||
```
|
||||
|
||||
Implement `GET /repos/{repo_slug}/scope/context` in repo-scoping. The endpoint
|
||||
must return the JSON contract above and must preserve the existing
|
||||
`GET /repos/{repo_slug}/scope` Markdown behavior.
|
||||
|
||||
Acceptance criteria:
|
||||
- The endpoint resolves repositories with the same slug rules as the existing
|
||||
scope endpoints.
|
||||
- Repositories without approved capabilities still return a valid context
|
||||
response with empty `capabilities` and `tags`.
|
||||
- Missing repository slugs return the existing `404` error shape.
|
||||
- The OpenAPI snapshot includes the new endpoint and response model.
|
||||
|
||||
## T03: Resolve SCOPE.md Presence And Summary
|
||||
|
||||
```task
|
||||
id: RREG-WP-0012-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "cb0b17f4-30c4-4d68-b2ff-9a3fa9ef73a3"
|
||||
```
|
||||
|
||||
Populate `scope_md_exists` and `scope_summary` without performing network
|
||||
operations. Reuse local source paths, cached checkouts, and State Hub local path
|
||||
lookup where available.
|
||||
|
||||
Acceptance criteria:
|
||||
- A local registered repo with root `SCOPE.md` returns `scope_md_exists: true`.
|
||||
- A local registered repo without root `SCOPE.md` returns `scope_md_exists:
|
||||
false`.
|
||||
- A remote repo with no cached checkout returns `scope_md_exists: false` and a
|
||||
metadata fallback summary when available.
|
||||
- `scope_summary` extracts the first non-empty paragraph after headings or
|
||||
frontmatter noise when a `SCOPE.md` file is inspectable.
|
||||
|
||||
## T04: Add Provider-Side Contract Tests
|
||||
|
||||
```task
|
||||
id: RREG-WP-0012-T04
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "f70c1c58-b23f-4b61-adca-a02644b6ee7e"
|
||||
```
|
||||
|
||||
Add `tests/test_scope_context_api.py` or equivalent focused API coverage for
|
||||
the new context endpoint.
|
||||
|
||||
Acceptance criteria:
|
||||
- Tests assert all required fields and types.
|
||||
- Tests cover at least three repository cases: local with `SCOPE.md`, local
|
||||
without `SCOPE.md`, and remote/uncached.
|
||||
- Tests assert the existing Markdown `/scope` endpoint still returns Markdown.
|
||||
- Tests assert the OpenAPI contract exposes the new response model.
|
||||
|
||||
## Completion Criteria
|
||||
|
||||
1. `GET /repos/{slug}/scope` returns all five required fields
|
||||
2. `scope_md_exists` is accurate for at least three test repos
|
||||
3. JSON Schema file committed to `docs/schemas/`
|
||||
4. Contract test passes in CI
|
||||
5. activity-core agent confirmed the `RepoScopingContextResolver` integration works
|
||||
- `GET /repos/{repo_slug}/scope/context` returns the five-field JSON contract.
|
||||
- Existing `GET /repos/{repo_slug}/scope` Markdown preview behavior is unchanged.
|
||||
- `docs/schemas/repo-scope-context-response.json` exists.
|
||||
- Provider-side contract tests pass in CI.
|
||||
- activity-core updates `RepoScopingContextResolver` to call `/scope/context`.
|
||||
|
||||
Implementation note 2026-05-15: repo-scoping provider work is complete. Added
|
||||
`GET /repos/{repo_slug}/scope/context`, the Pydantic response model, the JSON
|
||||
Schema artifact, focused provider-side contract tests, and OpenAPI snapshot
|
||||
coverage. Full repo test suite passed locally with `.venv/bin/python -m pytest`
|
||||
(`140 passed`). Workplan remains active until activity-core updates and confirms
|
||||
its resolver.
|
||||
|
||||
## Notes
|
||||
|
||||
- The local agent implementing this should coordinate with the activity-core agent
|
||||
to confirm the exact field names and types before implementing T02.
|
||||
- Do **not** add dynamic operational state to this endpoint (e.g., last_commit_at,
|
||||
open_issues_count) — that belongs to the state hub context adapter, not repo-scoping.
|
||||
- `scope_summary` is optional (null OK) — do not block on extracting it if the
|
||||
SCOPE.md parsing is complex.
|
||||
- Dynamic operational state such as last commit time, open issues, active tasks,
|
||||
or runtime health belongs to the State Hub context adapter, not this endpoint.
|
||||
- This endpoint should be cheap and deterministic. It must not trigger scans,
|
||||
clones, LLM calls, or SCOPE.md generation.
|
||||
- Backward-compatible additions can be optional fields. Required field changes
|
||||
need coordination with activity-core.
|
||||
|
||||
## Change History
|
||||
|
||||
- v0.1 (2026-05-14): Stub created by activity-core agent during WP-0003 planning.
|
||||
Local agent to flesh out and implement.
|
||||
- v0.2 (2026-05-15): Revised by repo-scoping agent to avoid breaking the
|
||||
existing Markdown `/scope` endpoint, define `/scope/context`, and normalize
|
||||
ADR-001 task blocks.
|
||||
|
||||
Reference in New Issue
Block a user