Skip to content

Commit d5a86ff

Browse files
mason5052claude
authored andcommitted
feat: add evidence receipt hash chain prototype (#279)
Disabled-by-default audit feature (EVIDENCE_RECEIPTS_ENABLED): appends a hash-chained JSONL receipt per finished/failed toolcall under <DATA_DIR>/flow-<id>/evidence/receipts.jsonl, recording toolcall provenance plus SHA-256 hashes of args/result (no raw content). Integration adapted to current main: the original PR built the receipt from a database.Toolcall returned by ce.db.UpdateToolcall*Result, which the executor no longer uses after the ToolCallLogProvider (tclp) refactor. Receipts are now built from the in-scope toolcall data at the tclp log sites and recorded non-fatally, so a receipt failure is logged and never fails an otherwise-successful toolcall. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 2a4ff3d commit d5a86ff

9 files changed

Lines changed: 693 additions & 35 deletions

File tree

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ EXECUTION_MONITOR_ENABLED=
100100
EXECUTION_MONITOR_SAME_TOOL_LIMIT=
101101
EXECUTION_MONITOR_TOTAL_TOOL_LIMIT=
102102

103+
## Evidence receipt hash chain
104+
EVIDENCE_RECEIPTS_ENABLED=false
105+
103106
## Agent execution tool calls limit
104107
MAX_GENERAL_AGENT_TOOL_CALLS=
105108
MAX_LIMITED_AGENT_TOOL_CALLS=

backend/docs/config.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,18 @@ The environment variables documented below remain the source of truth for config
127127

128128
These settings control basic application behavior and are foundational for the system's operation.
129129

130-
| Option | Environment Variable | Default Value | Description |
131-
| ---------------- | --------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
132-
| DatabaseURL | `DATABASE_URL` | `postgres://pentagiuser:pentagipass@pgvector:5432/pentagidb?sslmode=disable` | Connection string for the PostgreSQL database with pgvector extension |
133-
| DBMaxOpenConns | `DATABASE_MAX_OPEN_CONNS` | `25` | Maximum open connections in the shared `sql.DB` pool (sqlc + GORM combined). See [database.md §Connection Pooling](database.md#connection-pooling). |
134-
| DBMaxIdleConns | `DATABASE_MAX_IDLE_CONNS` | `5` | Maximum idle connections kept open between requests |
135-
| DBVectorMaxConns | `DATABASE_VECTOR_MAX_CONNS` | `10` | Maximum connections in the shared `pgxpool` for all pgvector stores |
136-
| Debug | `DEBUG` | `false` | Enables debug mode with additional logging |
137-
| DataDir | `DATA_DIR` | `./data` | Directory for storing persistent data |
138-
| AskUser | `ASK_USER` | `false` | When enabled, requires explicit user confirmation for certain operations |
139-
| InstallationID | `INSTALLATION_ID` | *(none)* | Unique installation identifier for PentAGI Cloud API communication |
140-
| LicenseKey | `LICENSE_KEY` | *(none)* | License key for PentAGI Cloud API authentication and feature activation |
130+
| Option | Environment Variable | Default Value | Description |
131+
| ----------------------- | --------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
132+
| DatabaseURL | `DATABASE_URL` | `postgres://pentagiuser:pentagipass@pgvector:5432/pentagidb?sslmode=disable` | Connection string for the PostgreSQL database with pgvector extension |
133+
| DBMaxOpenConns | `DATABASE_MAX_OPEN_CONNS` | `25` | Maximum open connections in the shared `sql.DB` pool (sqlc + GORM combined). See [database.md §Connection Pooling](database.md#connection-pooling). |
134+
| DBMaxIdleConns | `DATABASE_MAX_IDLE_CONNS` | `5` | Maximum idle connections kept open between requests |
135+
| DBVectorMaxConns | `DATABASE_VECTOR_MAX_CONNS` | `10` | Maximum connections in the shared `pgxpool` for all pgvector stores |
136+
| Debug | `DEBUG` | `false` | Enables debug mode with additional logging |
137+
| DataDir | `DATA_DIR` | `./data` | Directory for storing persistent data |
138+
| AskUser | `ASK_USER` | `false` | When enabled, requires explicit user confirmation for certain operations |
139+
| EvidenceReceiptsEnabled | `EVIDENCE_RECEIPTS_ENABLED` | `false` | Enables export-only toolcall evidence receipts |
140+
| InstallationID | `INSTALLATION_ID` | *(none)* | Unique installation identifier for PentAGI Cloud API communication |
141+
| LicenseKey | `LICENSE_KEY` | *(none)* | License key for PentAGI Cloud API authentication and feature activation |
141142

142143
### Usage Details
143144

@@ -1845,6 +1846,10 @@ The supervision settings work together as a comprehensive system:
18451846
```
18461847
Disabled supervision for debugging to observe natural agent behavior.
18471848

1849+
## Evidence Receipt Settings
1850+
1851+
When `EVIDENCE_RECEIPTS_ENABLED=true`, PentAGI writes hash-chain-only JSONL receipts for finished and failed tool calls to `<DATA_DIR>/flow-<flow_id>/evidence/receipts.jsonl`. Receipts include toolcall provenance metadata plus hashes of arguments and results, not raw argument or result content. Ed25519 signing and report bundle export are deferred to a later evidence-chain milestone.
1852+
18481853
## Observability Settings
18491854

18501855
These settings control the observability and monitoring capabilities, including telemetry and trace collection for system performance and debugging.

backend/pkg/config/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ type Config struct {
2323
DataDir string `env:"DATA_DIR" envDefault:"./data"`
2424
AskUser bool `env:"ASK_USER" envDefault:"false"`
2525

26+
// === Evidence Receipt Prototype ===
27+
EvidenceReceiptsEnabled bool `env:"EVIDENCE_RECEIPTS_ENABLED" envDefault:"false"`
28+
2629
// === PentAGI Cloud Service Integration ===
2730
InstallationID string `env:"INSTALLATION_ID"`
2831
LicenseKey string `env:"LICENSE_KEY"`

backend/pkg/config/config_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func clearConfigEnv(t *testing.T) {
269269
t.Helper()
270270

271271
envVars := []string{
272-
"DATABASE_URL", "DEBUG", "DATA_DIR", "ASK_USER", "INSTALLATION_ID", "LICENSE_KEY",
272+
"DATABASE_URL", "DEBUG", "DATA_DIR", "ASK_USER", "EVIDENCE_RECEIPTS_ENABLED", "INSTALLATION_ID", "LICENSE_KEY",
273273
"DOCKER_INSIDE", "DOCKER_NET_ADMIN", "DOCKER_SOCKET", "DOCKER_NETWORK",
274274
"DOCKER_PUBLIC_IP", "DOCKER_WORK_DIR", "DOCKER_DEFAULT_IMAGE", "DOCKER_DEFAULT_IMAGE_FOR_PENTEST", "TERMINAL_TOOL_TIMEOUT",
275275
"SERVER_PORT", "SERVER_HOST", "SERVER_USE_SSL", "SERVER_SSL_KEY", "SERVER_SSL_CRT",
@@ -331,6 +331,7 @@ func TestNewConfig_Defaults(t *testing.T) {
331331
assert.Equal(t, "0.0.0.0", config.ServerHost)
332332
assert.Equal(t, false, config.Debug)
333333
assert.Equal(t, "./data", config.DataDir)
334+
assert.Equal(t, false, config.EvidenceReceiptsEnabled)
334335
assert.Equal(t, false, config.ServerUseSSL)
335336
assert.Equal(t, "openai", config.EmbeddingProvider)
336337
assert.Equal(t, 512, config.EmbeddingBatchSize)
@@ -511,6 +512,20 @@ func TestNewConfig_CorsOrigins(t *testing.T) {
511512
assert.Equal(t, []string{"*"}, config.CorsOrigins)
512513
}
513514

515+
func TestNewConfig_EvidenceReceipts(t *testing.T) {
516+
clearConfigEnv(t)
517+
t.Chdir(t.TempDir())
518+
519+
config, err := NewConfig()
520+
require.NoError(t, err)
521+
assert.Equal(t, false, config.EvidenceReceiptsEnabled)
522+
523+
t.Setenv("EVIDENCE_RECEIPTS_ENABLED", "true")
524+
config, err = NewConfig()
525+
require.NoError(t, err)
526+
assert.Equal(t, true, config.EvidenceReceiptsEnabled)
527+
}
528+
514529
func TestNewConfig_OllamaDefaults(t *testing.T) {
515530
clearConfigEnv(t)
516531
t.Chdir(t.TempDir())

0 commit comments

Comments
 (0)