Skip to content

feat(context): scoped context resolution + progressive disclosure of nested context files (GENAI-285) - #48

Open
obukhovaa wants to merge 7 commits into
mainfrom
feat-GENAI-285-scoped-context-files
Open

feat(context): scoped context resolution + progressive disclosure of nested context files (GENAI-285)#48
obukhovaa wants to merge 7 commits into
mainfrom
feat-GENAI-285-scoped-context-files

Conversation

@obukhovaa

Copy link
Copy Markdown
Owner

Implements the scoped-context-files OpenSpec change (GENAI-285): workspace context becomes a function of who is running and what they are running, and nested context files become discoverable without paying for them upfront.

What's in here

1. Scoped context resolution (internal/contextfile, new leaf package)

  • Agents (.opencode.json / markdown frontmatter) and flow steps declare context: { paths, mode, nested }; precedence step > agent > global with compositional replace/append semantics; unknown mode WARNs (naming the agent/step) and fails safe to append.
  • Shell-free templating in path entries — ${agent}, ${flow.id}, ${flow.step}, ${env.VAR} — with symlink-resolved workDir containment; escaping entries are rejected.
  • Keyed memoization (sync.Map + singleflight) replaces the process-global sync.Once; resolved blocks are byte-stable per session.
  • The flow-step context field is inheritable via include/extends with zero merge-code changes (reflection-driven), and ${flow.id}/${flow.step} are threaded explicitly from runStep through NewAgent (agent construction is context-free).

2. Progressive disclosure of nested context files

  • One bounded walk per process per workDir discovers context files strictly below root (hardcoded skip set + configured data dir; caps on depth/files). Only a compact, cache-stable manifest goes into the system prompt; labels are extracted once at discovery time.
  • A file's body is injected as a <system-reminder> appended to the first successful tool result touching its owning directory (triggers: read/write/edit/multiedit/patch/grep/glob/ls; not bash, not delete). Outermost-first layering, once per session, per-session byte budget, subagent sessions isolated.
  • The system prompt is never mutated between turns — the Anthropic single-block cache_control prefix stays intact (the load-bearing constraint of the whole design).

3. Hardening (from the adversarial review rounds)

  • Discovery rejects non-regular files and symlink escapes; activation reads go through kernel-enforced beneath-only resolution (os.Root, Go 1.25) with O_NOFOLLOW|O_NONBLOCK, fstat-on-fd size checks, and io.LimitReader — a repo-committed symlink to ~/.ssh/id_rsa (or /dev/zero, or a FIFO) can neither leak, OOM, nor hang, even under a check/open race (PoC-verified).
  • Injected bodies are sanitized so a repo file cannot forge </system-reminder> framing.
  • Case folding in owner matching is applied only on genuinely case-insensitive filesystems (probed per workDir via os.SameFile) — no cross-matching of case-differing sibling dirs on Linux.
  • Files already inlined by an agent's scoped layers are subtracted from that agent's manifest and injection set.

Backward compatibility

With no context config and no nested files on disk the assembled prompt is byte-identical to the pre-feature build — pinned by unit tests and the e2e A/B check (including the # From: header quirks).

Config surface

  • agents.<name>.context (also markdown frontmatter) and per-flow-step context
  • Top-level contextDiscovery { enabled, maxFiles, maxDepth, maxFileBytes, maxSessionBytes } (default on; opt out per agent/step with context.nested: false)
  • opencode-schema.json regenerated; viper round-trip test for the case-folding hazard per CLAUDE.md.

Tests

  • make test green (fmt + race + coverage). Unit coverage across resolver/templating/discovery/manifest/wrapper/flow-inheritance, including mutation-verified seam tests for the factory→provider prompt threading.
  • New e2e scripts/test/scoped_context.sh + hermetic cmd/context-e2e driver (isolated mktemp sandbox config, HOME/XDG overridden): byte-identical backward-compat A/B across processes, manifest rendering, first-touch injection, second-touch dedup, and the agent-level mode: replace override that motivated the change — 15/15 checks.
  • make test-e2e: all scripts pass except 3 live-model failures (attachments, deferred_tools_native, grep) reproduced byte-for-byte on base 6d8f8c7 — pre-existing, unrelated.

OpenSpec

Change validated (--strict), implemented task-by-task, and archived as 2026-09-04-scoped-context-files; the context-resolution and progressive-context-disclosure capabilities plus prompt-surface/flow-api deltas are applied to openspec/specs/. The spec was first verified claim-by-claim against HEAD and corrected (13+ drifted/contradictory items, incl. an unimplementable ctx-key token-sourcing plan and a nonexistent gitignore-library dependency) before implementation started.

Docs: docs/context.md (new), AGENTS.md/CLAUDE.md agent-fields entry, docs/flows.md step field, flow-creator skill step schema.

🤖 Generated with Claude Code

obukhovaa and others added 7 commits September 3, 2026 21:44
…fication

Verified every design/spec/tasks claim against HEAD with a 4-agent pass:
rebuilt both MODIFIED requirement blocks (validator blockers), dropped the
nonexistent gitignore-library dependency from v1 discovery, corrected the
patch-tool trigger (patch_text parsing via ExtractPathsFromCall), added
multiedit to the trigger set, re-homed AgentContext/StepContext/DiscoveryConfig
into the contextfile leaf, made disclosure state per-toolset (shared, deferSeq
pattern) with DeferredWrapper kept outermost, sourced flow template tokens
explicitly from f.ID/step.ID (NewAgent is context-free), fixed the budget-test
claims (prompt_budget_test.go measures base prompts only), and refreshed all
drifted line references.

GENAI-285

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…truction (GENAI-285)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ection (GENAI-285)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n reads, close review gaps (GENAI-285)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n reads, fs-aware case folding (GENAI-285)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Applies the context-resolution and progressive-context-disclosure capability
specs and the prompt-surface / flow-api deltas into openspec/specs/.

GENAI-285

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant