Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ Only updated when a feature introduces a technology not already listed here.
- TypeScript 5.x (strict; Article XV). No Python change. + `@debrief/stac-writer` (interface + core), `node:fs`/`node:crypto` (fs adaptor — existing), `idb` (web-shell adaptor — existing), `@debrief/schemas` (`FeatureCollection`, `StacItem`), VS Code Extension API (`window.showWarningMessage`). **No new runtime dependencies.** (268-save-atomicity)
- TypeScript 5.x (strict mode, Article XV); React 18.x. No + `golden-layout` v2 (analysis + catalog layouts), (281-ui-review-p1-p2-fixes)
- TypeScript 5.x (strict — Article XV) in `apps/vscode`; Python 3.11 unchanged (debrief-calc/debrief-stac consumed as-is) + VS Code Extension API — **Language Model Tools API** (`vscode.lm.registerTool` + `contributes.languageModelTools`); existing `calcService` (debrief-calc stdio), `stacService` (catalog), `resultsPanelService`, `openPlotsService`, `toolMatchAdapter`, `sessionManager`, `@debrief/schemas`, `@debrief/session-state` (`LogService`) (284-copilot-plot-editing)
- None new. Reads existing STAC catalog; workspace-level config files (`.github/`, `.vscode/`, `*.code-workspace`) are committed artefacts (285-copilot-best-practices)

## Before Pushing

Expand Down Expand Up @@ -305,6 +306,6 @@ Each wrapper:
Note: `vitest` does not catch TypeScript type errors — only `tsc` (run during typecheck) does. The `pnpm build` step also runs `tsc`, but typecheck is the explicit CI gate.

## Recent Changes
- 285-copilot-best-practices: Added TypeScript 5.x (strict — Article XV) in `apps/vscode`; Python 3.11 untouched (existing `debrief_stac.mcp_server` consumed as-is) + VS Code Extension API (existing ^1.99 engine; new API used behind capability checks: `McpServerDefinitionProvider`, custom agents/prompt files are host-side file conventions, not API); `@vscode/prompt-tsx` (**new dev/runtime dependency** — justified under Constitution Check Article IX); existing `src/copilot/` modules (`summarize.ts`, `resultHelpers.ts`, `runToolTool.ts`, `registerLmTools.ts`), `calcService`, `stacService`
- 284-copilot-plot-editing: Added TypeScript 5.x (strict — Article XV) in `apps/vscode`; Python 3.11 unchanged (debrief-calc/debrief-stac consumed as-is) + VS Code Extension API — **Language Model Tools API** (`vscode.lm.registerTool` + `contributes.languageModelTools`); existing `calcService` (debrief-calc stdio), `stacService` (catalog), `resultsPanelService`, `openPlotsService`, `toolMatchAdapter`, `sessionManager`, `@debrief/schemas`, `@debrief/session-state` (`LogService`)
- 281-ui-review-p1-p2-fixes: Added TypeScript 5.x (strict mode, Article XV); React 18.x. No + `golden-layout` v2 (analysis + catalog layouts),
- 256-prefix-aware-stac-typing: One schema-driven step in the LinkML `gen-typescript` post-processor (`shared/schemas/scripts/generate.py`) rewrites modelled slot keys to their on-disk `debrief:` `slot_uri` across `StacExtensionProperties`, `StacSummaries`, and `StacAsset`, so the STAC writers' `props['debrief:*']` / `asset['debrief:toolId']` access sites gain typed slots on read **and** write (both hosts' write-path `props` re-typed to `StacItemProperties`). Models `debrief:toolId` + `debrief:snapshotTimestamp` as `StacAsset` slots (additive Pydantic regen); `debrief:label` excluded (feature/annotation key, not STAC). On-disk JSON unchanged; reuses the existing `src/generated` drift gate.
48 changes: 48 additions & 0 deletions specs/285-copilot-best-practices/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Specification Quality Checklist: Copilot Chat Integration Best-Practices Upgrade

**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-07-11
**Feature**: [spec.md](../spec.md)

## Content Quality

- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified

## Feature Readiness

- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification

## Notes

- The spec names existing artefacts (the four `debrief_*` tool ids, the #284
priming file path, "MCP", "Code Server") where they ARE the subject of the
requirement rather than an implementation choice — consistent with project
precedent for successor-to-spike specs (#284, #235). Specific host API
identifiers (`chat.tools.eligibleForAutoApproval`, `.agent.md`, prompt-tsx,
`McpServerDefinitionProvider`) are deliberately kept OUT of FRs and left to
plan.md; they appear only in the user description quoted in the header.
- SC-005's ≥15% compact-serialization target is measurable against the
committed #284 token-probe fixtures.
- No [NEEDS CLARIFICATION] markers were required: scope boundaries came from
the #284 findings report and the user's explicit deferral of local-model
work; the pinned-model choice and built-in tool set are documented as
implementation-time decisions in Assumptions.
- Not a UI feature (configuration, tool-result contract, and research
deliverables); User Interface Flow section omitted per template guidance.
70 changes: 70 additions & 0 deletions specs/285-copilot-best-practices/contracts/customization-pack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Contract: Copilot Customization Pack (US1–US3)

Binding placement, format, and sync rules for the workspace artefacts. The
drift check and unit tests enforce this contract in CI.

## Placement matrix

| Artefact | Canonical | Synced copy (preview workspace root) |
|---|---|---|
| Priming | `.github/copilot-instructions.md` | `preview/workspace/samples/.github/copilot-instructions.md` |
| Agent | `.github/agents/debrief-analyst.agent.md` | `preview/workspace/samples/.github/agents/debrief-analyst.agent.md` |
| Prompts ×8 | `.github/prompts/demo-*.prompt.md` | `preview/workspace/samples/.github/prompts/demo-*.prompt.md` |

Rules:
- Canonical is the only hand-edited location. Copies are byte-identical.
- `scripts/check-copilot-customization-drift.mjs` exits non-zero on any hash
mismatch or missing copy; wired into `task lint` / CI lint step.
- `apps/vscode/.github/copilot-instructions.md` is deleted (content relocated).

## Agent file format (`debrief-analyst.agent.md`)

```markdown
---
name: Debrief Analyst
description: <one sentence, analyst-facing>
model: <pinned Sonnet-class picker id>
tools: ['debrief_searchPlots', 'debrief_summarizeCurrentPlot',
'debrief_listTools', 'debrief_runTool'<, minimal built-ins>]
---
<embedded conventions: summarise-before-edit; list-before-run;
never fabricate ids/params; edits are unsaved>
```

## Prompt file format (`demo-<n>-<slug>.prompt.md`)

```markdown
---
agent: Debrief Analyst
description: <scenario title from #284>
---
<scenario utterance — verbatim-equivalent to the transcript-replay corpus>
```

Parity rule: a unit test asserts each prompt body matches the corresponding
utterance in `apps/vscode/tests/unit/copilot/scenarios.transcript.test.ts`'s
corpus (single source of scenario truth).

## Approval policy declaration

`apps/vscode/package.json`:

```jsonc
"contributes": {
"configurationDefaults": {
"chat.tools.eligibleForAutoApproval": { "debrief_runTool": false }
}
}
```

Echoed in `preview/workspace/debrief-preview.code-workspace` `settings`.
The extension MUST NOT set any read-only tool to auto-approved; pre-approval
is a documented user action only (quickstart §Approvals).

## Degradation guarantees

- Hosts < 1.106: agent/prompt files inert; approval-eligibility key ignored;
`prepareInvocation` confirmation + invoke-time mutation guard still gate
every mutating run (unchanged #284 behaviour).
- Pinned model unavailable: host falls back to the user's default model with
visible indication; no extension code involved.
57 changes: 57 additions & 0 deletions specs/285-copilot-best-practices/contracts/plot-summary-v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Contract: Plot Summary v2 — budget-aware tool result (US4)

The result contract for `debrief_summarizeCurrentPlot` (and the compact-
serialization rule for all four tools). This is the tool-result contract the
E13 offline panel inherits.

## Serialization (all tools)

- All JSON text-part results are compact (no indentation/pretty-printing).
- `approxTokens` is computed over the emitted payload.
- Gate: fixture test asserts ≥15% payload reduction vs #284 pretty-printed
baseline at each probe size (8 / 32 / 100 / 250 features).

## Summary rendering modes

| Host capability | Result part | Behaviour |
|---|---|---|
| `tokenizationOptions` supplied | prompt-tsx part | priority-pruned to the caller's budget |
| absent (older host / direct invokeTool) | compact-JSON text part | full content; `INVENTORY_CAP` backstop only |

Parity rule: at unconstrained budget both modes carry identical field content.

## Priority order (highest survives longest)

1. Plot identity (`plotId`, `title`, `timeSpan`), feature counts, `openPlots`,
and the `shedding` notice itself
2. Per-feature `id`, `name`, `type`, `platform`, `pointCount`
3. Per-feature `timeSpan`
4. Per-feature `spatialDigest`

## Shedding notice

Whenever any content is shed (budget pruning or cap):

- `truncated: true`
- `shedding.omitted`: content classes dropped, in shed order
- `shedding.guidance`: instructs the model to narrow scope via selection,
`debrief_searchPlots`, or `featureNames`/`featureIds`

Minimum-budget floor: plot identity + counts + guidance are always emitted;
never an empty or malformed result.

## Spatial digest

- Format: `"<sector>/<extent>"`, sector ∈ {N, NE, E, SE, S, SW, W, NW, C}
(feature bbox centroid vs 3×3 grid over plot bbox), extent ∈ {pt, local,
wide} (feature/plot bbox diagonal ratio).
- Omitted (field absent) for features without geometry — never fabricated.
- Deterministic for identical inputs.
- Acceptance: "the northern track" resolves to the correct feature id from the
summary alone in the scenario replay (SC-006).

## Evidence regeneration

`evidence/token-budget-v2.md` re-tabulates the four probe sizes (now with
digests, compact form) against 4k / 8k / 32k local-model context windows,
superseding the #284 table for the E13 record (FR-018).
109 changes: 109 additions & 0 deletions specs/285-copilot-best-practices/data-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Data Model: Copilot Chat Integration Best-Practices Upgrade (285)

No LinkML schema changes. All entities are either workspace configuration
artefacts (validated by drift check + unit tests) or TypeScript view types
local to `apps/vscode/src/copilot/` (extension-internal, not cross-boundary —
Article II untouched; the summary view is extended per the derived-not-rewritten
rule where it mirrors existing types).

## 1. PrimingInstructions (workspace artefact)

| Field | Notes |
|---|---|
| canonical path | `.github/copilot-instructions.md` (repo root) |
| synced copies | `preview/workspace/samples/.github/copilot-instructions.md` |
| content | Debrief vocabulary, tool conventions (summarise-before-edit, list-before-run, never fabricate, edits-are-unsaved) — carried over from #284 file |
| validation | drift check: SHA-256 of each copy == canonical (CI-fatal) |

## 2. DebriefAnalystAgent (workspace artefact — `.agent.md`)

| Front-matter field | Value / constraint |
|---|---|
| `name` | `Debrief Analyst` |
| `description` | analyst-facing, one sentence |
| `model` | pinned Sonnet-class picker id (implementation-time choice) |
| `tools` | exactly: 4 `debrief_*` tools + documented minimal built-ins |
| body | embedded conventions (subset of PrimingInstructions) |

Placement mirrors PrimingInstructions (canonical + synced copy, same drift check).

## 3. ScenarioPrompt (workspace artefact — `.prompt.md` × 8)

| Field | Notes |
|---|---|
| filename | `demo-<n>-<slug>.prompt.md`, n = 1..8 (5 happy, 3 fail-safe) |
| front matter | `agent: Debrief Analyst` (inherits model + tools) |
| body | scenario utterance, verbatim-equivalent to replay-corpus utterance |
| validation | unit test: body ↔ `scenarios.transcript.test.ts` corpus parity |

## 4. ApprovalPolicyDeclaration (configuration)

| Field | Notes |
|---|---|
| mechanism | `configurationDefaults` → `chat.tools.eligibleForAutoApproval` |
| `debrief_runTool` | `false` (never auto-approvable) |
| read-only tools | absent (host/user discretion; pre-approval documented, never granted by extension) |
| echo | same keys in `debrief-preview.code-workspace` settings |
| backstop | existing `prepareInvocation` confirmation + invoke-time mutation guard (unchanged) |

## 5. PlotSummaryView v2 (TypeScript view type — extends #284 shape)

```
PlotSummaryView {
plotId, title,
timeSpan: { start, end } | null,
features: FeatureInventoryEntry[],
truncated: boolean, // now: true when ANY content was shed (budget or cap)
shedding?: SheddingNotice, // NEW — present when truncated
approxTokens: number, // computed over emitted payload (compact)
openPlots: OpenPlotView[],
selectionOnly?: true
}

FeatureInventoryEntry {
id, name, type, platform,
timeSpan, // priority: shed 2nd
pointCount,
spatialDigest?: string // NEW — "sector/extent" e.g. "NW/wide"; omitted
// when feature has no geometry; priority: shed 1st
}

SheddingNotice {
omitted: string[] // which content classes were shed, in order
guidance: string // how to narrow scope (selection / search / featureNames)
}
```

**Priority order (highest survives longest)**: plot identity + counts +
SheddingNotice → feature id/name/type → per-feature timeSpan → spatialDigest.
`INVENTORY_CAP = 200` retained as final backstop only.

**State/rendering**: rendered via prompt-tsx element (`summaryPrompt.tsx`) when
the host supplies `tokenizationOptions`; compact-JSON text part otherwise
(identical field content at full budget — parity asserted in tests).

## 6. SpatialDigest (derived value)

| Component | Domain | Derivation |
|---|---|---|
| sector | `N NE E SE S SW W NW C` | feature bbox centroid vs 3×3 grid over plot bbox |
| extent | `pt | local | wide` | feature bbox diagonal / plot bbox diagonal buckets |

Deterministic (Article I.4). Undefined (omitted) for zero-geometry features.

## 7. McpServerRegistration (extension config + provider)

| Field | Notes |
|---|---|
| provider id | `debrief.stacMcp` |
| definition | stdio: resolved Python interpreter → `python -m debrief_stac.mcp_server` |
| env/args | catalog path from `debrief.stacCatalogPath` |
| gate | `debrief.mcp.autoStart` setting (existing, default false) |
| failure mode | log diagnostic; LM tools unaffected (never an error dialog) |

## 8. ComparisonFindingsNote (evidence artefact)

`evidence/mcp-vs-lmtool-comparison.md`: query-matrix parity table (FR-020),
per-scenario routing outcome + latency under config A/B (R9), setup-friction
notes, recommendation for the E13 tool-surface contract. Follows the #284
findings-report structure.
Loading
Loading