chati-dev 4.5.16 → 4.5.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +8 -3
  2. package/bin/chati.js +124 -66
  3. package/framework/agents/build/dev.md +5 -5
  4. package/framework/agents/deploy/devops.md +7 -7
  5. package/framework/agents/discover/brief.md +4 -4
  6. package/framework/agents/discover/brownfield-wu.md +3 -3
  7. package/framework/agents/discover/greenfield-wu.md +3 -3
  8. package/framework/agents/plan/architect.md +2 -2
  9. package/framework/agents/plan/detail.md +4 -4
  10. package/framework/agents/plan/phases.md +2 -2
  11. package/framework/agents/plan/tasks.md +2 -2
  12. package/framework/agents/plan/ux.md +2 -2
  13. package/framework/agents/quality/qa-implementation.md +11 -10
  14. package/framework/agents/quality/qa-planning.md +3 -3
  15. package/framework/agents/quality/qa-visual.md +1 -1
  16. package/framework/config.yaml +3 -3
  17. package/framework/constitution.md +18 -18
  18. package/framework/context/protocols.md +1 -1
  19. package/framework/context/quality.md +1 -1
  20. package/framework/context/root.md +4 -4
  21. package/framework/data/entity-registry.yaml +1 -1
  22. package/framework/domains/agents/orchestrator.yaml +2 -2
  23. package/framework/domains/constitution.yaml +1 -1
  24. package/framework/hooks/advance-trigger.js +4 -6
  25. package/framework/hooks/git-push-authority.js +45 -37
  26. package/framework/hooks/mode-governance.js +149 -40
  27. package/framework/hooks/model-governance.js +13 -20
  28. package/framework/hooks/prism-engine.js +74 -92
  29. package/framework/hooks/reasoning-escalator.js +23 -40
  30. package/framework/hooks/session-digest.js +12 -13
  31. package/framework/hooks/session-reader.js +224 -0
  32. package/framework/hooks/session-writer.js +195 -0
  33. package/framework/hooks/team-quality-gate.js +34 -24
  34. package/framework/i18n/en.yaml +2 -2
  35. package/framework/i18n/es.yaml +2 -2
  36. package/framework/i18n/fr.yaml +2 -2
  37. package/framework/i18n/pt.yaml +2 -2
  38. package/framework/intelligence/context-engine.md +4 -4
  39. package/framework/intelligence/memory-layer.md +1 -1
  40. package/framework/manifest.json +129 -119
  41. package/framework/manifest.sig +1 -1
  42. package/framework/orchestrator/chati-router.js +252 -25
  43. package/framework/orchestrator/chati.md +238 -70
  44. package/framework/schemas/session.schema.json +1 -1
  45. package/framework/tasks/orchestrator-deviation.md +1 -1
  46. package/framework/tasks/orchestrator-escalate.md +1 -1
  47. package/framework/tasks/orchestrator-handoff.md +6 -6
  48. package/framework/tasks/orchestrator-health.md +5 -9
  49. package/framework/tasks/orchestrator-mode-switch.md +3 -7
  50. package/framework/tasks/orchestrator-resume.md +10 -14
  51. package/framework/tasks/orchestrator-route.md +3 -3
  52. package/framework/tasks/orchestrator-spawn-terminal.md +1 -1
  53. package/framework/tasks/orchestrator-status.md +9 -9
  54. package/framework/tasks/orchestrator-suggest-mode.md +1 -1
  55. package/framework/tasks/qa-impl-consolidate.md +2 -2
  56. package/framework/tasks/qa-impl-performance-test.md +4 -4
  57. package/framework/tasks/qa-impl-regression-check.md +4 -4
  58. package/framework/tasks/qa-impl-sast-scan.md +1 -1
  59. package/framework/tasks/qa-impl-test-execute.md +1 -1
  60. package/framework/tasks/qa-impl-verdict.md +2 -2
  61. package/framework/tasks/qa-planning-consolidate.md +3 -3
  62. package/framework/tasks/qa-planning-coverage-plan.md +2 -2
  63. package/framework/tasks/qa-planning-gate-define.md +4 -4
  64. package/framework/tasks/qa-planning-risk-matrix.md +4 -4
  65. package/framework/tasks/qa-planning-test-strategy.md +2 -2
  66. package/node_modules/@chati/browser-capability/src/index.js +12 -2
  67. package/node_modules/@chati/planning/src/index.js +24 -4
  68. package/node_modules/@chati/provider-registry/src/index.js +11 -0
  69. package/node_modules/@chati/rail/src/index.js +1967 -83
  70. package/node_modules/@chati/release-lane/README.md +12 -8
  71. package/node_modules/@chati/release-lane/package.json +1 -1
  72. package/node_modules/@chati/release-lane/src/index.js +1426 -58
  73. package/node_modules/@chati/review-council/src/index.js +63 -0
  74. package/node_modules/@chati/tracking-clickup/README.md +13 -0
  75. package/node_modules/@chati/tracking-clickup/src/index.js +690 -30
  76. package/package-artifact-manifest.json +1 -0
  77. package/package-artifact-manifest.sig +1 -0
  78. package/package.json +16 -7
  79. package/scripts/verify-real-harness-e2e.js +1581 -0
  80. package/src/config/framework-adapter.js +4 -4
  81. package/src/installer/core.js +148 -53
  82. package/src/installer/manifest.js +140 -9
  83. package/src/installer/package-artifact.js +249 -0
  84. package/src/installer/templates.js +65 -20
  85. package/src/installer-v2/catalog-client.js +531 -23
  86. package/src/installer-v2/index.js +91 -34
  87. package/src/installer-v2/installation-authority.js +327 -0
  88. package/src/installer-v2/provider-executable.js +247 -0
  89. package/src/installer-v2/wizard-installation.js +1 -1
  90. package/src/orchestrator/browser-runtime.js +44 -13
  91. package/src/orchestrator/cli.js +1545 -174
  92. package/src/orchestrator/clickup-projection.js +43 -1
  93. package/src/orchestrator/clickup-runtime.js +355 -39
  94. package/src/orchestrator/doctor.js +16 -3
  95. package/src/orchestrator/index.js +16 -0
  96. package/src/orchestrator/planning-runtime.js +20 -2
  97. package/src/orchestrator/rail-adjudication-evidence.js +234 -0
  98. package/src/orchestrator/rail-evidence-authority.js +147 -0
  99. package/src/orchestrator/rail-execution-evidence.js +45 -0
  100. package/src/orchestrator/rail-runtime.js +836 -56
  101. package/src/orchestrator/release-runtime.js +65 -6
  102. package/src/orchestrator/review-runtime.js +186 -41
  103. package/src/orchestrator/runtime-installation-v2.js +236 -20
  104. package/src/orchestrator/session-manager.js +1167 -53
  105. package/src/terminal/adapters/claude-adapter.js +3 -1
  106. package/src/terminal/adapters/codex-adapter.js +2 -0
  107. package/src/terminal/adapters/grok-adapter.js +7 -4
  108. package/src/terminal/handoff-parser.js +19 -1
  109. package/src/terminal/prompt-builder.js +9 -1
  110. package/src/terminal/provider-preflight.js +36 -3
  111. package/src/terminal/rail-execution-worktree.js +213 -0
  112. package/src/terminal/rail-prompts.js +169 -0
  113. package/src/terminal/rail-readonly-workspace.js +324 -0
  114. package/src/terminal/run-agent.js +384 -24
  115. package/src/terminal/run-parallel.js +5 -0
  116. package/src/terminal/run-rail-adjudication.js +323 -0
  117. package/src/terminal/run-rail-review.js +291 -0
  118. package/src/terminal/run-rail-rework.js +325 -0
  119. package/src/terminal/run-rail-task.js +380 -0
  120. package/src/terminal/run-team.js +5 -0
  121. package/src/terminal/spawner.js +1225 -77
  122. package/src/wizard/index.js +3 -2
@@ -20,21 +20,18 @@ criteria:
20
20
  Restore session context from previous work, determine pipeline position, and prepare to continue.
21
21
 
22
22
  ## Prerequisites
23
- - Session file exists at `.chati/session.yaml`
23
+ - Installed provider-native entrypoint and deterministic router
24
24
  - Handoff artifacts in `.chati/artifacts/handoffs/`
25
25
  - Constitution at `chati.dev/constitution.md`
26
26
  - Project configuration at `chati.dev/config.yaml`
27
27
 
28
28
  ## Steps
29
29
 
30
- ### 1. Locate Session File
31
- Check for existing session at `.chati/session.yaml`:
32
- - If found: Load and validate
33
- - If not found: This is a new session, initialize instead
34
- - If corrupted: Attempt recovery from handoffs
30
+ ### 1. Activate Through the Router
31
+ Run the provider-native entrypoint, which invokes `chati-router.js --harness <active-harness>`. Consume only the returned JSON. If `ok` is false, report the exact error and stop. Never locate, read or reconstruct `.chati/session.yaml` directly.
35
32
 
36
33
  ### 2. Load Session State
37
- Parse the YAML session file and extract:
34
+ Use the validated `session` object returned by the router to extract:
38
35
  - Project metadata (name, type, language)
39
36
  - Current mode (planning/build/deploy)
40
37
  - Pipeline position (phase, last agent)
@@ -121,16 +118,15 @@ If last agent is complete but handoff is absent:
121
118
  ## Error Handling
122
119
 
123
120
  ### Session File Not Found
124
- If `.chati/session.yaml` doesn't exist:
121
+ If the router reports that no session exists:
125
122
  - Check if this is initial installation
126
123
  - Look for backup in `.chati/backups/`
127
124
  - Offer to initialize new session
128
125
 
129
- ### Session File Corrupted
130
- If YAML parsing fails:
131
- - Try JSON parse (in case of format change)
132
- - Load most recent backup
133
- - Escalate to user with corruption details
126
+ ### Session State Rejected
127
+ If the router rejects session state:
128
+ - Report the exact router error and relevant diagnostic detail
129
+ - Stop without fallback parsing, backup substitution or reconstruction
134
130
 
135
131
  ### Handoff Chain Broken
136
132
  If handoff sequence has gaps:
@@ -155,7 +151,7 @@ If pipeline position is ambiguous:
155
151
  ```yaml
156
152
  session_state:
157
153
  loaded_at: "2026-02-13T10:30:00Z"
158
- session_file: ".chati/session.yaml"
154
+ session_source: "router_validated_context"
159
155
  session_age_hours: 8
160
156
  project:
161
157
  name: "HealthCare Portal"
@@ -20,7 +20,7 @@ criteria:
20
20
  Analyze user input, classify intent, determine pipeline position, and route to the appropriate agent.
21
21
 
22
22
  ## Prerequisites
23
- - Session state loaded from `.chati/session.yaml`
23
+ - Validated session state returned by `chati-router.js status`
24
24
  - Constitution available at `chati.dev/constitution.md`
25
25
  - Agent definitions in `chati.dev/agents/`
26
26
  - User input captured
@@ -34,7 +34,7 @@ Extract the core intent from user message. Identify:
34
34
  - Context changes (e.g., "actually, let's change the database")
35
35
 
36
36
  ### 2. Load Session Context
37
- Read `.chati/session.yaml` to understand:
37
+ Run `node chati.dev/orchestrator/chati-router.js status` and consume only its validated JSON. If `ok` is false, report the exact error and stop. Never read `.chati/session.yaml` directly. Use the returned context to understand:
38
38
  - Current mode (planning/build/deploy)
39
39
  - Last completed agent
40
40
  - Pipeline position
@@ -91,7 +91,7 @@ Dispatch to the selected destination:
91
91
  - For deviations: Trigger deviation protocol
92
92
 
93
93
  ### 10. Log Routing Action
94
- Update session state with routing information:
94
+ Execute the router-returned action so the CLI session manager records:
95
95
  - Timestamp
96
96
  - Source (user input)
97
97
  - Target (agent/action)
@@ -23,7 +23,7 @@ Coordinate parallel execution of independent tasks across multiple terminal inst
23
23
  ## Prerequisites
24
24
  - Multi-terminal IDE support (Claude Code, VS Code, Cursor, Windsurf)
25
25
  - Task definitions with `parallelizable: true` flag
26
- - Session state at `.chati/session.yaml`
26
+ - Router-validated canonical session context
27
27
  - Agent definitions in `chati.dev/agents/`
28
28
 
29
29
  ## Steps
@@ -21,15 +21,15 @@ criteria:
21
21
  Generate a comprehensive status report of the current project, showing pipeline progress, agent completion, and next steps.
22
22
 
23
23
  ## Prerequisites
24
- - Session file at `.chati/session.yaml`
24
+ - Installed `chati-router.js` with the `status` command
25
25
  - Agent definitions in `chati.dev/agents/`
26
26
  - Constitution at `chati.dev/constitution.md`
27
27
  - Artifacts in `.chati/artifacts/`
28
28
 
29
29
  ## Steps
30
30
 
31
- ### 1. Load Session State
32
- Read `.chati/session.yaml` to get current project state:
31
+ ### 1. Load Validated Session State
32
+ Run `node chati.dev/orchestrator/chati-router.js status` and consume only its validated JSON. If `ok` is false, report the exact error and stop. Never read `.chati/session.yaml` directly. Use the returned fields for:
33
33
  - Project metadata (name, type, language)
34
34
  - Current mode and phase
35
35
  - Agent statuses with timestamps
@@ -124,7 +124,7 @@ If no activity in last 7+ days:
124
124
  ## Error Handling
125
125
 
126
126
  ### Session File Missing
127
- If `.chati/session.yaml` doesn't exist:
127
+ If the router reports that no session exists:
128
128
  - Report "No active session"
129
129
  - Suggest running `/chati` to initialize
130
130
  - Check for backup session files
@@ -141,11 +141,11 @@ If handoff or artifact files can't be read:
141
141
  - Continue with available data
142
142
  - Log warning for investigation
143
143
 
144
- ### Corrupted Session Data
145
- If session YAML is malformed:
146
- - Attempt partial parsing
147
- - Report known good data
148
- - Flag corruption clearly
144
+ ### Unsafe or Corrupted Session Data
145
+ If the router rejects session state:
146
+ - Report its exact error and diagnostic detail
147
+ - Run the router `doctor` command only when instructed by the orchestration contract
148
+ - Stop without partial parsing, reconstruction or direct file access
149
149
 
150
150
  ## Output Format
151
151
 
@@ -21,7 +21,7 @@ criteria:
21
21
  Analyze session state to determine if mode transition conditions are met, calculate confidence, and either suggest to user or autonomously execute the transition.
22
22
 
23
23
  ## Prerequisites
24
- - Session state at `.chati/session.yaml`
24
+ - Router-validated canonical session context
25
25
  - Constitution Article XI at `chati.dev/constitution.md`
26
26
  - Agent completion data
27
27
  - Quality scores from QA agents
@@ -95,7 +95,7 @@ Compile the final QA implementation report synthesizing all testing, analysis, a
95
95
  - Include quick-reference guide to QA reports
96
96
 
97
97
  12. **Execute Handoff**
98
- - Update session.yaml with QA implementation completion
98
+ - Return QA implementation completion in the handoff; the orchestrator persists it through the session manager
99
99
  - Log handoff decision (to devops, dev, or orchestrator)
100
100
  - If autonomous gate (PASS verdict), trigger next agent automatically
101
101
  - If manual approval needed, prompt orchestrator
@@ -133,7 +133,7 @@ Compile the final QA implementation report synthesizing all testing, analysis, a
133
133
  - If autonomous gate should trigger but handoff fails, log error
134
134
  - Do not proceed automatically
135
135
  - Escalate to orchestrator for manual handoff
136
- - Document failure in session.yaml
136
+ - Return the failure in the structured handoff so the orchestrator records it canonically
137
137
 
138
138
  ## Output Format
139
139
 
@@ -37,7 +37,7 @@ Execute performance benchmarks to measure CLI startup time, agent execution time
37
37
  2. **Define Performance Metrics**
38
38
  - **CLI Startup Time**: Time from `npx chati-dev` invocation to first output
39
39
  - **Agent Execution Time**: Time per agent task (avg, p50, p95, p99)
40
- - **File Operations**: Read/write time for session.yaml, config.yaml
40
+ - **File Operations**: Canonical session-manager read/write time and config.yaml access
41
41
  - **YAML Parsing**: Time to parse task definitions, config files
42
42
  - **Memory Usage**: Peak memory during CLI execution, agent workflows
43
43
  - **State Operations**: Time for state read, write, validation
@@ -62,8 +62,8 @@ Execute performance benchmarks to measure CLI startup time, agent execution time
62
62
  - Calculate agent execution time distribution (avg, p50, p95, p99)
63
63
 
64
64
  6. **Execute File Operation Benchmarks**
65
- - Benchmark session.yaml read (cold and warm cache)
66
- - Benchmark session.yaml write (atomic write with backup)
65
+ - Benchmark the canonical session reader (cold and warm cache)
66
+ - Benchmark session-manager atomic persistence and backup behavior
67
67
  - Benchmark config.yaml read and merge
68
68
  - Benchmark task definition loading (all .md files in chati.dev/tasks/)
69
69
  - Measure filesystem sync overhead
@@ -374,7 +374,7 @@ threshold_compliance:
374
374
 
375
375
  file_operations:
376
376
  threshold: 50ms
377
- max_current: 35ms (session.yaml write)
377
+ max_current: 35ms (canonical session-manager write)
378
378
  status: PASS
379
379
  margin: 15ms (30% under threshold)
380
380
 
@@ -50,7 +50,7 @@ Execute regression tests to ensure new changes have not broken existing function
50
50
  - **Test status changes**: Tests that were passing now fail, or vice versa
51
51
  - **Output differences**: stdout/stderr changes, different error messages
52
52
  - **Behavior changes**: Different execution paths, timing differences
53
- - **File artifact changes**: session.yaml structure, config format, generated files
53
+ - **File artifact changes**: canonical session schema, config format, generated files
54
54
 
55
55
  5. **Categorize Differences**
56
56
  - **True regressions**: Unintended breakage of existing functionality
@@ -208,7 +208,7 @@ regressions:
208
208
  severity: HIGH
209
209
  type: functional
210
210
  feature: Session state persistence
211
- description: "session.yaml no longer includes mode_transitions array"
211
+ description: "canonical session schema no longer includes mode_transitions array"
212
212
  baseline_behavior: "mode_transitions[] populated with audit trail"
213
213
  current_behavior: "mode_transitions[] empty or missing"
214
214
  root_cause: "State schema update removed array initialization"
@@ -258,7 +258,7 @@ intentional_changes:
258
258
 
259
259
  - id: CHANGE-003
260
260
  feature: State schema version
261
- description: "session.yaml schema version updated to 2.0"
261
+ description: "canonical session schema version advanced to 2.0"
262
262
  baseline: "version: 1.0"
263
263
  current: "version: 2.0"
264
264
  justification: "Schema breaking change for mode governance"
@@ -336,7 +336,7 @@ smoke_tests:
336
336
  command: npx chati-dev init
337
337
  status: PASS
338
338
  execution_time: 8.2s
339
- notes: "Completed successfully, session.yaml created"
339
+ notes: "Completed successfully, canonical session state created by the session manager"
340
340
 
341
341
  agent_handoff:
342
342
  workflow: "greenfield-wu -> brief -> detail"
@@ -104,7 +104,7 @@ Run static analysis security testing (SAST) to identify security vulnerabilities
104
104
  - List all CRITICAL and HIGH findings with details
105
105
  - Provide overall gate status (PASS, FAIL, CONDITIONAL)
106
106
  - Include remediation roadmap
107
- - Update session.yaml with scan results
107
+ - Return scan results in the handoff; the orchestrator persists them through the session manager
108
108
 
109
109
  ## Decision Points
110
110
 
@@ -105,7 +105,7 @@ Execute the complete test suite (unit and integration tests) for the implemented
105
105
 
106
106
  12. **Log Results and Next Steps**
107
107
  - Save test-results.yaml to session
108
- - Update session.yaml with test execution status
108
+ - Return test execution status in the handoff; the orchestrator persists it through the session manager
109
109
  - If all tests pass and coverage meets targets: proceed to SAST scan
110
110
  - If failures exist: flag for dev agent remediation, then re-run
111
111
 
@@ -108,7 +108,7 @@ Issue the final QA verdict by synthesizing all QA implementation results (tests,
108
108
 
109
109
  12. **Log Verdict and Update Session**
110
110
  - Save qa-verdict.yaml with complete verdict
111
- - Update session.yaml with QA implementation status
111
+ - Return QA implementation status in the handoff; the orchestrator persists it through the session manager
112
112
  - If PASS (autonomous gate), trigger handoff to qa-impl-consolidate
113
113
  - If FAIL, flag for orchestrator to return to dev
114
114
  - If CONDITIONAL, prompt orchestrator for user decision
@@ -145,7 +145,7 @@ Issue the final QA verdict by synthesizing all QA implementation results (tests,
145
145
  - If autonomous gate should trigger but handoff fails, log error
146
146
  - Do not proceed to next agent automatically
147
147
  - Escalate to orchestrator for manual handoff
148
- - Document failure in session.yaml
148
+ - Return the failure in the structured handoff so the orchestrator records it canonically
149
149
 
150
150
  ## Output Format
151
151
 
@@ -101,7 +101,7 @@ Compile all QA planning outputs into a final qa-plan.yaml document, calculate an
101
101
  - Document any open questions or assumptions
102
102
 
103
103
  12. **Log Completion and Next Steps**
104
- - Update session.yaml with qa-planning completion status
104
+ - Return qa-planning completion status in the handoff; the orchestrator persists it through the session manager
105
105
  - Log overall score and autonomous transition decision
106
106
  - If autonomous transition approved, trigger dev agent
107
107
  - If manual approval needed, prompt orchestrator for user input
@@ -137,7 +137,7 @@ Compile all QA planning outputs into a final qa-plan.yaml document, calculate an
137
137
  - If overall score < 90%, compilation succeeds but transition fails
138
138
  - Generate detailed gap analysis with prioritized action items
139
139
  - Escalate to orchestrator for user decision (remediate or override via deviation protocol)
140
- - Log decision and rationale in session.yaml
140
+ - Return the decision and rationale in the structured handoff so the orchestrator records it through the session manager
141
141
 
142
142
  ## Output Format
143
143
 
@@ -234,7 +234,7 @@ executive_summary:
234
234
  handoff_to_dev:
235
235
  priority_1_tests:
236
236
  - Mode transition validation (state management, orchestrator)
237
- - session.yaml write operations (state management)
237
+ - canonical session-manager operations (state management)
238
238
  - Version migration execution (upgrade system)
239
239
 
240
240
  priority_2_tests:
@@ -31,7 +31,7 @@ Create a detailed test coverage plan with specific targets for each module, comp
31
31
  - Identify all modules: orchestrator, agents (13), state management, file operations, CLI, validators, parsers
32
32
  - List core utilities: YAML handlers, i18n, error handling, logging
33
33
  - Note external interfaces: MCP tools, IDE integration, package managers
34
- - Document data structures: session.yaml schema, config.yaml, task definitions
34
+ - Catalog data structures: canonical session schema, config.yaml, task definitions
35
35
 
36
36
  2. **Categorize Components by Testability**
37
37
  - **High Testability**: Pure functions (validators, parsers, formatters, calculators)
@@ -47,7 +47,7 @@ Create a detailed test coverage plan with specific targets for each module, comp
47
47
 
48
48
  4. **Set Module-Specific Targets**
49
49
  - **Orchestrator**: 85% (critical routing and mode governance logic)
50
- - **State Management**: 90% (session.yaml read/write, consistency checks)
50
+ - **State Management**: 90% (canonical session-manager reads/writes and consistency checks)
51
51
  - **Agent Task Execution**: 75% (task loading, validation, execution)
52
52
  - **File Operations**: 80% (read/write/create, permission handling, error recovery)
53
53
  - **Validators**: 90% (schema validation, input sanitization)
@@ -49,7 +49,7 @@ Define quality gates and enforcement thresholds for each stage of the chati.dev
49
49
  - **Enforcement**: Orchestrator validation before mode transition
50
50
 
51
51
  4. **Define Build Phase Gates**
52
- - **Implementation Complete**: All tasks marked done in session.yaml
52
+ - **Implementation Complete**: All tasks reported complete in the router-validated task state
53
53
  - **Test Execution**: All unit + integration tests passing
54
54
  - **SAST Clean**: Zero critical vulnerabilities, high vulnerabilities < 3
55
55
  - **No Regressions**: All regression checks passing vs baseline
@@ -80,7 +80,7 @@ Define quality gates and enforcement thresholds for each stage of the chati.dev
80
80
  - **Automated**: CI/CD pipeline checks, pre-commit hooks
81
81
  - **Agent-Enforced**: Orchestrator mode governance, qa-planning consolidation score
82
82
  - **Manual**: Human review for override decisions, complex risk assessment
83
- - **Audit Trail**: All gate passes/failures logged in session.yaml mode_transitions
83
+ - **Audit Trail**: All gate passes/failures returned in the handoff for canonical session-manager persistence under `mode_transitions`
84
84
 
85
85
  9. **Create Gate Bypass Procedures**
86
86
  - **Deviation Protocol**: Orchestrator-managed with user confirmation
@@ -183,7 +183,7 @@ pipeline_stages:
183
183
  gates:
184
184
  - name: Implementation Complete
185
185
  threshold: All tasks done
186
- enforcement: session.yaml validation
186
+ enforcement: canonical session-manager validation
187
187
  bypass: deviation_protocol
188
188
 
189
189
  - name: Test Suite
@@ -267,7 +267,7 @@ bypass_procedures:
267
267
  trigger: orchestrator
268
268
  requires: user confirmation
269
269
  documentation: [reason, risk assessment, mitigation plan]
270
- audit: logged in session.yaml mode_transitions
270
+ audit: returned in the handoff for canonical session-manager persistence under mode_transitions
271
271
  expiration: 24 hours
272
272
 
273
273
  manual_approval:
@@ -30,7 +30,7 @@ Build a comprehensive risk matrix mapping all features, components, and workflow
30
30
  1. **Enumerate All System Features**
31
31
  - Core workflows: greenfield pipeline, brownfield pipeline, mode transitions
32
32
  - Agent operations: task execution, handoffs, validation
33
- - State management: session.yaml CRUD, consistency checks, concurrency
33
+ - State management: canonical session-manager CRUD, consistency checks, concurrency
34
34
  - File operations: create, read, write, delete, permissions
35
35
  - CLI commands: /chati, npx chati-dev *, help, status
36
36
  - Configuration: config.yaml loading, merging, validation
@@ -156,7 +156,7 @@ features:
156
156
  rationale: Invalid mode transitions can corrupt workflow state
157
157
  mitigation:
158
158
  - Strict validation in mode-governance.js
159
- - Audit trail in session.yaml mode_transitions
159
+ - Audit trail persisted by the canonical session manager under `mode_transitions`
160
160
  - Rollback mechanism for failed transitions
161
161
  testing_priority: 1
162
162
  coverage_target: 95%
@@ -194,7 +194,7 @@ features:
194
194
  gate_enforcement: critical
195
195
 
196
196
  # STATE MANAGEMENT
197
- - feature: session.yaml write operations
197
+ - feature: canonical session-manager write operations
198
198
  area: state_management
199
199
  impact: critical
200
200
  likelihood: high
@@ -534,7 +534,7 @@ testing_priorities:
534
534
  gate_enforcement: blocker
535
535
  features:
536
536
  - Mode transition validation
537
- - session.yaml write operations
537
+ - canonical session-manager write operations
538
538
  - Concurrent state access
539
539
  - File write with permissions
540
540
  - Version migration execution
@@ -47,7 +47,7 @@ Define a comprehensive testing strategy covering unit, integration, end-to-end,
47
47
  - **Manual Tests**: IDE compatibility, internationalization, accessibility
48
48
 
49
49
  4. **Identify Risk Areas**
50
- - State management corruption (session.yaml consistency)
50
+ - State management corruption (canonical session consistency through the session manager)
51
51
  - File system operations (permissions, race conditions)
52
52
  - Agent handoff logic (transition validation)
53
53
  - Mode governance enforcement (unauthorized transitions)
@@ -169,7 +169,7 @@ testing_pyramid:
169
169
 
170
170
  risk_areas:
171
171
  critical:
172
- - State corruption in session.yaml
172
+ - Canonical session corruption reported by the router
173
173
  - Mode governance bypass
174
174
  - File system race conditions
175
175
  high:
@@ -5,6 +5,7 @@ const TOOLS = new Set(['playwright-cli', 'playwright-mcp', 'chrome-devtools-mcp'
5
5
  const CLASSIFICATIONS = new Set(['internal', 'confidential', 'client-restricted', 'personal-restricted']);
6
6
  const ACTION_CONFIRMATIONS = new Set(['required', 'not-required-by-policy']);
7
7
  const ARTIFACT_KINDS = new Set(['screenshot', 'dom', 'network', 'trace', 'download', 'console']);
8
+ const EVIDENCE_CLASSES = new Set(['delegation-only', 'browser-simulation', 'real-browser']);
8
9
 
9
10
  function fail(code, message, details = {}) { throw new ContractError(code, message, details); }
10
11
  function object(value, code, label) {
@@ -70,7 +71,7 @@ export function assertBrowserCapabilityForTask(task = {}) {
70
71
  return policy;
71
72
  }
72
73
 
73
- function validateLaunchRequest(input, policy) {
74
+ export function validateBrowserLaunchRequest(input, policy) {
74
75
  object(input, 'INVALID_BROWSER_REQUEST', 'browser launch request');
75
76
  string(input.browser_session_id, 'INVALID_BROWSER_REQUEST', 'browser_session_id');
76
77
  string(input.task_id, 'INVALID_BROWSER_REQUEST', 'task_id');
@@ -117,7 +118,7 @@ export class BrowserCapability {
117
118
 
118
119
  preflight(input = {}) {
119
120
  const policy = validateBrowserPolicy(input.policy);
120
- const request = validateLaunchRequest(input, policy);
121
+ const request = validateBrowserLaunchRequest(input, policy);
121
122
  const manifestInput = {
122
123
  schema_version: 1,
123
124
  manifest_type: 'BrowserEvidenceManifest',
@@ -129,6 +130,7 @@ export class BrowserCapability {
129
130
  allowed_domain: request.hostname,
130
131
  profile_isolation: policy.profile_isolation,
131
132
  classification: request.classification,
133
+ evidence_class: 'browser-simulation',
132
134
  artifact_policy: policy.artifact_policy,
133
135
  action_confirmation: policy.action_confirmation,
134
136
  artifacts: [],
@@ -163,3 +165,11 @@ export class BrowserCapability {
163
165
  return this.#issue(output);
164
166
  }
165
167
  }
168
+
169
+ export function validateBrowserEvidenceClass(value) {
170
+ string(value, 'INVALID_BROWSER_EVIDENCE_CLASS', 'browser evidence_class');
171
+ if (!EVIDENCE_CLASSES.has(value)) {
172
+ fail('INVALID_BROWSER_EVIDENCE_CLASS', 'browser evidence_class must distinguish delegation, simulation, or real browser execution');
173
+ }
174
+ return value;
175
+ }
@@ -9,6 +9,16 @@ function fail(code, message, details = {}) {
9
9
  throw new ContractError(code, message, details);
10
10
  }
11
11
 
12
+ function trustedGitEnvironment(source = process.env) {
13
+ const environment = Object.fromEntries(Object.entries(source).filter(([key]) => !key.startsWith('GIT_')));
14
+ return {
15
+ ...environment,
16
+ GIT_CONFIG_NOSYSTEM: '1',
17
+ GIT_CONFIG_GLOBAL: process.platform === 'win32' ? 'NUL' : '/dev/null',
18
+ GIT_TERMINAL_PROMPT: '0',
19
+ };
20
+ }
21
+
12
22
  function assertObject(value, code, label) {
13
23
  if (!value || typeof value !== 'object' || Array.isArray(value)) fail(code, `${label} must be an object`);
14
24
  }
@@ -47,6 +57,9 @@ function validateTask(task, knownTaskIds) {
47
57
  assertStringArray(task.acceptance_criteria_refs, 'MISSING_ACCEPTANCE_CRITERIA', 'task.acceptance_criteria_refs', { allowEmpty: false });
48
58
  assertImmutableRef(task.execution_scope_ref, 'INVALID_HANDOFF_TASK', 'task.execution_scope_ref');
49
59
  assertImmutableRef(task.routing_constraints_ref, 'INVALID_HANDOFF_TASK', 'task.routing_constraints_ref');
60
+ if (task.required_independence_level !== undefined && !['A', 'B', 'C'].includes(task.required_independence_level)) {
61
+ fail('INVALID_HANDOFF_TASK', 'task.required_independence_level must be A, B or C');
62
+ }
50
63
  assertObject(task.execution_binding, 'TASK_EXECUTION_BINDING_REQUIRED', 'task.execution_binding');
51
64
  for (const field of ['provider_id', 'harness_id', 'model_id', 'reasoning_configuration']) {
52
65
  assertString(task.execution_binding[field], 'TASK_EXECUTION_BINDING_REQUIRED', `task.execution_binding.${field}`);
@@ -91,7 +104,8 @@ export function buildCanonicalManifest(handoff) {
91
104
  assertObject(handoff, 'INVALID_HANDOFF', 'handoff');
92
105
  const { seal, ...rest } = handoff;
93
106
  assertObject(seal, 'INVALID_HANDOFF', 'seal');
94
- const { manifest_digest, ...sealWithoutDigest } = seal;
107
+ const sealWithoutDigest = { ...seal };
108
+ delete sealWithoutDigest.manifest_digest;
95
109
  return canonicalize({ ...rest, seal: sealWithoutDigest });
96
110
  }
97
111
 
@@ -152,7 +166,9 @@ export function verifyLocalGitCommit({ git_dir, git_commit_ref }) {
152
166
  assertString(git_commit_ref, 'INVALID_GIT_COMMIT_REF', 'git_commit_ref');
153
167
  if (!GIT_OBJECT_ID.test(git_commit_ref)) fail('INVALID_GIT_COMMIT_REF', 'git_commit_ref must be an immutable Git object id');
154
168
  try {
155
- execFileSync('git', ['-C', git_dir, 'cat-file', '-e', `${git_commit_ref}^{commit}`], { stdio: 'ignore' });
169
+ execFileSync('git', ['-C', git_dir, 'cat-file', '-e', `${git_commit_ref}^{commit}`], {
170
+ stdio: 'ignore', env: trustedGitEnvironment(),
171
+ });
156
172
  } catch {
157
173
  fail('GIT_COMMIT_NOT_FOUND', 'sealed git_commit_ref is unavailable in the supplied local repository', { git_commit_ref });
158
174
  }
@@ -181,6 +197,7 @@ export function assertDispatchable({ handoff, task_id, completed_task_ids = [],
181
197
  manifest_digest: validated.seal.manifest_digest,
182
198
  git_commit_ref: validated.seal.git_commit_ref,
183
199
  task_id: task.task_id,
200
+ execution_binding: task.execution_binding,
184
201
  }));
185
202
  }
186
203
 
@@ -196,16 +213,19 @@ export function validateAttemptBinding({ attempt, handoff }) {
196
213
  for (const field of ['attempt_id', 'handoff_id', 'handoff_version', 'manifest_digest', 'git_commit_ref', 'task_id']) {
197
214
  assertString(attempt[field], 'INVALID_ATTEMPT_BINDING', field);
198
215
  }
216
+ assertObject(attempt.execution_binding, 'INVALID_ATTEMPT_BINDING', 'execution_binding');
199
217
  if (attempt.handoff_id !== validated.handoff_id || attempt.handoff_version !== validated.version || attempt.manifest_digest !== validated.seal.manifest_digest || attempt.git_commit_ref !== validated.seal.git_commit_ref) {
200
218
  fail('ATTEMPT_HANDOFF_DRIFT', 'attempt is not bound to this exact sealed handoff', { attempt_id: attempt.attempt_id });
201
219
  }
202
- if (!validated.tasks.some((task) => task.task_id === attempt.task_id)) fail('ATTEMPT_TASK_DRIFT', 'attempt task is not part of bound handoff');
220
+ const task = validated.tasks.find((candidate) => candidate.task_id === attempt.task_id);
221
+ if (!task) fail('ATTEMPT_TASK_DRIFT', 'attempt task is not part of bound handoff');
222
+ if (sha256(attempt.execution_binding) !== sha256(task.execution_binding)) fail('ATTEMPT_EXECUTION_BINDING_DRIFT', 'attempt execution binding differs from the sealed task');
203
223
  return deepFreeze(canonicalize(attempt));
204
224
  }
205
225
 
206
226
  function legacyValue(value, label) {
207
227
  if (typeof value === 'string' && value.trim() !== '') return value;
208
- fail('INVALID_LEGACY_PLANNING_ARTIFACT', `${label} must provide an immutable reference`);
228
+ return fail('INVALID_LEGACY_PLANNING_ARTIFACT', `${label} must provide an immutable reference`);
209
229
  }
210
230
 
211
231
  function legacyCriteriaRefs(task, taskId) {
@@ -98,6 +98,17 @@ export function validateInstallation(installation, snapshot, { bindingMap = DEFA
98
98
  throw new ContractError('INVALID_INSTALLATION', 'allowed_reasoning_configurations must be an array of non-empty strings');
99
99
  }
100
100
  }
101
+ const hasExecutablePath = binding.executable_path !== undefined;
102
+ const hasExecutableDigest = binding.executable_sha256 !== undefined;
103
+ if (hasExecutablePath !== hasExecutableDigest) {
104
+ throw new ContractError('INVALID_INSTALLATION', 'provider executable path and digest must be selected together');
105
+ }
106
+ if (hasExecutablePath) {
107
+ assertString(binding.executable_path, 'INVALID_INSTALLATION', 'executable_path');
108
+ if (!binding.executable_path.startsWith('/') || !/^[a-f0-9]{64}$/.test(binding.executable_sha256 || '')) {
109
+ throw new ContractError('INVALID_INSTALLATION', 'provider executable binding must contain an absolute path and SHA-256 digest');
110
+ }
111
+ }
101
112
  selectedHarnesses.add(binding.harness_id);
102
113
  selectedBindings.set(`${binding.provider_id}:${binding.harness_id}`, binding);
103
114
  }