From b157241325a8fbc1c7ebbb2df864afe3d38bc3e1 Mon Sep 17 00:00:00 2001 From: Chris Engelhard <34413331+digi4care@users.noreply.github.com> Date: Wed, 11 Mar 2026 19:58:08 +0100 Subject: [PATCH] fix: correct task-delegation reference in session-context-pattern (#218) * fix: correct task-delegation reference in session-context-pattern - Changed outdated reference from task-delegation.md to task-delegation-basics.md - The file task-delegation-basics.md exists, task-delegation.md does not - This caused 'file not found' errors during installation via install.sh * feat: add install-fork.sh for fork-based installation - Creates install-fork.sh that installs from digi4care/OpenAgentsControl fork - Allows users to install the forked version with fixes before upstream merge - Usage: bash install-fork.sh or curl directly from fork repo * docs: add root README.md and CONTRIBUTING.md for GitHub best practices - Add README.md in repository root (GitHub requirement) - Add CONTRIBUTING.md in repository root with contribution guidelines - Both files redirect to detailed documentation in docs/ directory - Fixes installer 404 error for readme config item - Follows GitHub community standards for repository structure * chore: remove fork-specific files per maintainer request --------- Co-authored-by: Chris Engelhard --- .../core/workflows/session-context-pattern.md | 224 +++++++++++------- 1 file changed, 140 insertions(+), 84 deletions(-) diff --git a/.opencode/context/core/workflows/session-context-pattern.md b/.opencode/context/core/workflows/session-context-pattern.md index b5bdef2..6042a39 100644 --- a/.opencode/context/core/workflows/session-context-pattern.md +++ b/.opencode/context/core/workflows/session-context-pattern.md @@ -1,4 +1,5 @@ + # Session Context Pattern ## Problem @@ -13,6 +14,7 @@ When orchestrating complex features across multiple agents (TaskManager → Code - **Orchestrator** has to manually pass context in every delegation This leads to: + - ❌ Repeated context discovery (inefficient) - ❌ Inconsistent decisions (agents don't see previous choices) - ❌ Lost architectural context (bounded contexts, contracts, ADRs) @@ -54,57 +56,71 @@ Created: {timestamp} Status: in_progress | completed | blocked ## Current Request + {Original user request - what we're building} ## Context Files to Load + - {Standards paths - coding conventions, patterns, security rules} ## Reference Files + - {Source material - existing project files to look at} ## Architecture + - Bounded Context: {DDD context from ArchitectureAnalyzer} - Module: {Package/module name} - Vertical Slice: {Feature slice from StoryMapper} ## User Stories + - {Story 1 from StoryMapper} - {Story 2} ## Priorities + - RICE Score: {score from PrioritizationEngine} - WSJF Score: {score} - Release Slice: {v1.0.0, Q1-2026, MVP} ## Contracts + - {type}: {name} ({status}) Path: {contract file path} ## Architectural Decision Records + - {ADR-ID}: {title} Path: {adr file path} ## Progress + Current Stage: {Stage N: Name} Completed Stages: + - {Stage 0: Context Loading} - {Stage 1: Planning} Stage Outputs: + - {Stage 0}: - {Output 1} - {Output 2} ## Key Decisions + - [{timestamp}] {decision} Rationale: {why this choice was made} ## Files Created + - {file path 1} - {file path 2} ## Exit Criteria + - [ ] {criterion 1} - [ ] {criterion 2} - [x] {completed criterion} @@ -132,16 +148,16 @@ Stage Outputs: **Stage 0: Initialize Session** ```typescript -import { createSession } from '.opencode/skill/task-management/scripts/session-context-manager'; +import { createSession } from ".opencode/skill/task-management/scripts/session-context-manager"; const result = createSession(feature, request, { contextFiles: [], // Will be populated by ContextScout referenceFiles: [], exitCriteria: [ - 'All subtasks completed', - 'Tests passing', - 'Documentation updated' - ] + "All subtasks completed", + "Tests passing", + "Documentation updated", + ], }); const sessionId = result.sessionId; @@ -151,35 +167,35 @@ const sessionId = result.sessionId; **Between Stages: Update Context** ```typescript -import { updateSession, markStageComplete } from './session-context-manager'; +import { updateSession, markStageComplete } from "./session-context-manager"; // After ContextScout completes updateSession(sessionId, { contextFiles: [ - '.opencode/context/core/standards/code-quality.md', - '.opencode/context/core/standards/security-patterns.md' - ] + ".opencode/context/core/standards/code-quality.md", + ".opencode/context/core/standards/security-patterns.md", + ], }); // After ArchitectureAnalyzer completes updateSession(sessionId, { architecture: { - boundedContext: 'authentication', - module: '@app/auth' - } + boundedContext: "authentication", + module: "@app/auth", + }, }); // Mark stage complete -markStageComplete(sessionId, 'Stage 1: Planning', [ - '.tmp/tasks/auth-system/task.json', - '.tmp/tasks/auth-system/subtask_01.json' +markStageComplete(sessionId, "Stage 1: Planning", [ + ".tmp/tasks/auth-system/task.json", + ".tmp/tasks/auth-system/subtask_01.json", ]); ``` **Final Stage: Complete Session** ```typescript -updateSession(sessionId, { status: 'completed' }); +updateSession(sessionId, { status: "completed" }); ``` ### TaskManager @@ -187,7 +203,7 @@ updateSession(sessionId, { status: 'completed' }); **Stage 0: Load Session Context** ```typescript -import { loadSession } from '.opencode/skill/task-management/scripts/session-context-manager'; +import { loadSession } from ".opencode/skill/task-management/scripts/session-context-manager"; const result = loadSession(sessionId); if (!result.success) { @@ -222,11 +238,11 @@ const adrs = session.adrs; // Architectural decisions **Stage 3: Update Progress** ```typescript -import { addDecision } from './session-context-manager'; +import { addDecision } from "./session-context-manager"; addDecision(sessionId, { - decision: 'Split authentication into 3 subtasks: schema, service, middleware', - rationale: 'Each subtask is atomic (1-2 hours) and has clear dependencies' + decision: "Split authentication into 3 subtasks: schema, service, middleware", + rationale: "Each subtask is atomic (1-2 hours) and has clear dependencies", }); ``` @@ -235,18 +251,18 @@ addDecision(sessionId, { **Before Coding: Load Session Context** ```typescript -import { loadSession } from '.opencode/skill/task-management/scripts/session-context-manager'; +import { loadSession } from ".opencode/skill/task-management/scripts/session-context-manager"; const result = loadSession(sessionId); const session = result.session; // Read context files (standards) -session.contextFiles.forEach(file => { +session.contextFiles.forEach((file) => { // Load coding standards, security patterns }); // Read reference files (existing code) -session.referenceFiles.forEach(file => { +session.referenceFiles.forEach((file) => { // Study existing patterns }); @@ -259,10 +275,10 @@ const adrs = session.adrs; // Architectural decisions to follow **After Coding: Track Files Created** ```typescript -import { addFile } from './session-context-manager'; +import { addFile } from "./session-context-manager"; -addFile(sessionId, 'src/auth/jwt.service.ts'); -addFile(sessionId, 'src/auth/jwt.service.test.ts'); +addFile(sessionId, "src/auth/jwt.service.ts"); +addFile(sessionId, "src/auth/jwt.service.test.ts"); ``` ### ContextScout @@ -270,18 +286,18 @@ addFile(sessionId, 'src/auth/jwt.service.test.ts'); **After Discovery: Update Session** ```typescript -import { updateSession } from './session-context-manager'; +import { updateSession } from "./session-context-manager"; updateSession(sessionId, { contextFiles: [ - '.opencode/context/core/standards/code-quality.md', - '.opencode/context/core/standards/security-patterns.md', - '(example: .opencode/context/core/standards/naming-conventions.md)' + ".opencode/context/core/standards/code-quality.md", + ".opencode/context/core/standards/security-patterns.md", + "(example: .opencode/context/core/standards/naming-conventions.md)", ], referenceFiles: [ - 'src/middleware/auth.middleware.ts', - 'src/config/jwt.config.ts' - ] + "src/middleware/auth.middleware.ts", + "src/config/jwt.config.ts", + ], }); ``` @@ -290,19 +306,20 @@ updateSession(sessionId, { **After Analysis: Update Session** ```typescript -import { updateSession, addDecision } from './session-context-manager'; +import { updateSession, addDecision } from "./session-context-manager"; updateSession(sessionId, { architecture: { - boundedContext: 'authentication', - module: '@app/auth', - verticalSlice: 'user-login' - } + boundedContext: "authentication", + module: "@app/auth", + verticalSlice: "user-login", + }, }); addDecision(sessionId, { - decision: 'Place authentication in separate bounded context', - rationale: 'Auth is a core domain with clear boundaries, used by multiple features' + decision: "Place authentication in separate bounded context", + rationale: + "Auth is a core domain with clear boundaries, used by multiple features", }); ``` @@ -311,23 +328,23 @@ addDecision(sessionId, { **After Contract Definition: Update Session** ```typescript -import { updateSession } from './session-context-manager'; +import { updateSession } from "./session-context-manager"; updateSession(sessionId, { contracts: [ { - type: 'api', - name: 'AuthAPI', - path: 'src/api/auth.contract.ts', - status: 'defined' + type: "api", + name: "AuthAPI", + path: "src/api/auth.contract.ts", + status: "defined", }, { - type: 'interface', - name: 'JWTService', - path: 'src/auth/jwt.service.ts', - status: 'draft' - } - ] + type: "interface", + name: "JWTService", + path: "src/auth/jwt.service.ts", + status: "draft", + }, + ], }); ``` @@ -338,6 +355,7 @@ updateSession(sessionId, { Initialize a new session with context.md file. **Parameters:** + - `feature` (string) - Feature name (kebab-case) - `request` (string) - Original user request - `options` (object) - Optional configuration @@ -351,14 +369,16 @@ Initialize a new session with context.md file. - `adrs` (array) - Architectural decision records **Returns:** + ```typescript { success: boolean; sessionId?: string; error?: string } ``` **Example:** + ```typescript -const result = createSession('auth-system', 'Implement JWT authentication', { - exitCriteria: ['All tests passing', 'JWT tokens signed with RS256'] +const result = createSession("auth-system", "Implement JWT authentication", { + exitCriteria: ["All tests passing", "JWT tokens signed with RS256"], }); // result.sessionId = "auth-system-2026-02-15T10-30-00-000Z" ``` @@ -368,16 +388,19 @@ const result = createSession('auth-system', 'Implement JWT authentication', { Read session context from context.md. **Parameters:** + - `sessionId` (string) - Session identifier **Returns:** + ```typescript { success: boolean; session?: SessionContext; error?: string } ``` **Example:** + ```typescript -const result = loadSession('auth-system-2026-02-15T10-30-00-000Z'); +const result = loadSession("auth-system-2026-02-15T10-30-00-000Z"); if (result.success) { const contextFiles = result.session.contextFiles; const architecture = result.session.architecture; @@ -389,6 +412,7 @@ if (result.success) { Append new information to session context. **Parameters:** + - `sessionId` (string) - Session identifier - `updates` (object) - Fields to update - `status` - 'in_progress' | 'completed' | 'blocked' @@ -401,20 +425,27 @@ Append new information to session context. - `adrs` - Add ADRs **Returns:** + ```typescript { success: boolean; error?: string } ``` **Example:** + ```typescript updateSession(sessionId, { architecture: { - boundedContext: 'authentication', - module: '@app/auth' + boundedContext: "authentication", + module: "@app/auth", }, contracts: [ - { type: 'api', name: 'AuthAPI', path: 'src/api/auth.contract.ts', status: 'defined' } - ] + { + type: "api", + name: "AuthAPI", + path: "src/api/auth.contract.ts", + status: "defined", + }, + ], }); ``` @@ -423,21 +454,24 @@ updateSession(sessionId, { Mark a workflow stage as complete and record outputs. **Parameters:** + - `sessionId` (string) - Session identifier - `stage` (string) - Stage name (e.g., "Stage 1: Planning") - `outputs` (string[]) - Files/artifacts created in this stage **Returns:** + ```typescript { success: boolean; error?: string } ``` **Example:** + ```typescript -markStageComplete(sessionId, 'Stage 1: Planning', [ - '.tmp/tasks/auth-system/task.json', - '.tmp/tasks/auth-system/subtask_01.json', - '.tmp/tasks/auth-system/subtask_02.json' +markStageComplete(sessionId, "Stage 1: Planning", [ + ".tmp/tasks/auth-system/task.json", + ".tmp/tasks/auth-system/subtask_01.json", + ".tmp/tasks/auth-system/subtask_02.json", ]); ``` @@ -446,21 +480,25 @@ markStageComplete(sessionId, 'Stage 1: Planning', [ Log a key decision with rationale. **Parameters:** + - `sessionId` (string) - Session identifier - `decision` (object) - `decision` (string) - What was decided - `rationale` (string) - Why this choice was made **Returns:** + ```typescript { success: boolean; error?: string } ``` **Example:** + ```typescript addDecision(sessionId, { - decision: 'Use RS256 for JWT signing instead of HS256', - rationale: 'RS256 (asymmetric) is more secure for distributed systems where tokens are verified by multiple services' + decision: "Use RS256 for JWT signing instead of HS256", + rationale: + "RS256 (asymmetric) is more secure for distributed systems where tokens are verified by multiple services", }); ``` @@ -469,18 +507,21 @@ addDecision(sessionId, { Track a file created during the session. **Parameters:** + - `sessionId` (string) - Session identifier - `filePath` (string) - Path to created file **Returns:** + ```typescript { success: boolean; error?: string } ``` **Example:** + ```typescript -addFile(sessionId, 'src/auth/jwt.service.ts'); -addFile(sessionId, 'src/auth/jwt.service.test.ts'); +addFile(sessionId, "src/auth/jwt.service.ts"); +addFile(sessionId, "src/auth/jwt.service.test.ts"); ``` ### getSessionSummary(sessionId) @@ -488,9 +529,11 @@ addFile(sessionId, 'src/auth/jwt.service.test.ts'); Get current session state summary. **Parameters:** + - `sessionId` (string) - Session identifier **Returns:** + ```typescript { success: boolean; @@ -510,11 +553,14 @@ Get current session state summary. ``` **Example:** + ```typescript const result = getSessionSummary(sessionId); console.log(`Progress: ${result.summary.completedStages} stages complete`); console.log(`Files: ${result.summary.filesCreated} created`); -console.log(`Exit Criteria: ${result.summary.exitCriteriaMet}/${result.summary.exitCriteriaTotal}`); +console.log( + `Exit Criteria: ${result.summary.exitCriteriaMet}/${result.summary.exitCriteriaTotal}`, +); ``` ## CLI Usage @@ -542,70 +588,80 @@ npx ts-node session-context-manager.ts summary auth-system-2026-02-15T10-30-00-0 ## Best Practices ### 1. Initialize Early + Create session at the start of orchestration, before any agent work begins. ### 2. Update After Each Stage + Every agent that completes work should update the session context. ### 3. Read Before Acting + Every agent should load session context before starting work. ### 4. Track Decisions + Use `addDecision()` for any architectural or design choice. ### 5. Track Files + Use `addFile()` for every file created (helps with cleanup, rollback). ### 6. Use Exit Criteria + Define clear, binary exit criteria at session creation. ## Example: Full Orchestration Flow ```typescript // Orchestrator: Initialize -const { sessionId } = createSession('auth-system', 'Implement JWT authentication', { - exitCriteria: ['All tests passing', 'JWT tokens signed with RS256'] -}); +const { sessionId } = createSession( + "auth-system", + "Implement JWT authentication", + { + exitCriteria: ["All tests passing", "JWT tokens signed with RS256"], + }, +); // Stage 0: ContextScout discovers context updateSession(sessionId, { - contextFiles: ['.opencode/context/core/standards/code-quality.md'], - referenceFiles: ['src/middleware/auth.middleware.ts'] + contextFiles: [".opencode/context/core/standards/code-quality.md"], + referenceFiles: ["src/middleware/auth.middleware.ts"], }); -markStageComplete(sessionId, 'Stage 0: Context Loading', []); +markStageComplete(sessionId, "Stage 0: Context Loading", []); // Stage 1: ArchitectureAnalyzer analyzes updateSession(sessionId, { - architecture: { boundedContext: 'authentication', module: '@app/auth' } + architecture: { boundedContext: "authentication", module: "@app/auth" }, }); addDecision(sessionId, { - decision: 'Separate bounded context for auth', - rationale: 'Core domain with clear boundaries' + decision: "Separate bounded context for auth", + rationale: "Core domain with clear boundaries", }); -markStageComplete(sessionId, 'Stage 1: Architecture Analysis', []); +markStageComplete(sessionId, "Stage 1: Architecture Analysis", []); // Stage 2: TaskManager creates tasks const { session } = loadSession(sessionId); // Use session.contextFiles, session.architecture in task.json -markStageComplete(sessionId, 'Stage 2: Task Planning', [ - '.tmp/tasks/auth-system/task.json' +markStageComplete(sessionId, "Stage 2: Task Planning", [ + ".tmp/tasks/auth-system/task.json", ]); // Stage 3: CoderAgent implements const { session } = loadSession(sessionId); // Read session.contextFiles, session.contracts -addFile(sessionId, 'src/auth/jwt.service.ts'); -markStageComplete(sessionId, 'Stage 3: Implementation', [ - 'src/auth/jwt.service.ts' +addFile(sessionId, "src/auth/jwt.service.ts"); +markStageComplete(sessionId, "Stage 3: Implementation", [ + "src/auth/jwt.service.ts", ]); // Stage 4: Complete -updateSession(sessionId, { status: 'completed' }); +updateSession(sessionId, { status: "completed" }); ``` ## Related - `.opencode/skill/task-management/scripts/session-context-manager.ts` - Implementation - `.opencode/context/core/task-management/standards/task-schema.md` - Task JSON schema -- `.opencode/context/core/workflows/task-delegation.md` - Multi-agent orchestration +- `.opencode/context/core/workflows/task-delegation-basics.md` - Multi-agent orchestration - `.tmp/sessions/test-task-manager/context.md` - Example session context