Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Private security reporting instructions
url: https://github.com/ashishki/gdev-agent/security/policy
about: Use the policy's private email path; do not open a public issue.
96 changes: 96 additions & 0 deletions .github/ISSUE_TEMPLATE/reproducible-bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Reproducible defect
description: Report a deterministic defect in the supported local reference workload.
title: "[bug]: "
body:
- type: markdown
attributes:
value: |
Use this form only for reproducible defects in the supported local boundary. Do not include credentials, private data, or vulnerability details. Security concerns must use the private path in [SECURITY.md](https://github.com/ashishki/gdev-agent/security/policy).

- type: dropdown
id: surface
attributes:
label: Affected surface
description: Choose the narrowest surface that reproduces the defect.
options:
- Default Docker Compose or tenant/RLS proof
- Signed webhook, guard, routing, or approval flow
- Internal deterministic eval or evidence command
- API, CLI, or local demo
- Documentation or evidence provenance
validations:
required: true

- type: input
id: revision
attributes:
label: Exact commit SHA
description: Run `git rev-parse HEAD` in the checkout that reproduced the defect.
placeholder: 40-character commit SHA
validations:
required: true

- type: textarea
id: environment
attributes:
label: Sanitized environment
description: Include OS, Python and Docker versions, run mode, and relevant non-secret configuration.
placeholder: |
OS:
Python:
Docker / Compose:
LLM_MODE:
Relevant configuration (redacted):
validations:
required: true

- type: textarea
id: prerequisites
attributes:
label: Minimal prerequisites
description: State the clean-checkout setup and synthetic fixtures needed before reproduction.
validations:
required: true

- type: textarea
id: reproduction
attributes:
label: Reproduction commands
description: Provide the shortest deterministic command sequence, including every required environment variable with values redacted.
render: shell
validations:
required: true

- type: textarea
id: observed
attributes:
label: Observed result
description: Include the exit code, failing assertion or sanitized response, and a link to any evidence artifact.
validations:
required: true

- type: textarea
id: expected
attributes:
label: Expected result
description: Point to the repository contract, test, or documented behavior that differs from the observation.
validations:
required: true

- type: textarea
id: additional
attributes:
label: Additional sanitized evidence
description: Optional logs, traceback, minimal fixture, or regression-test sketch. Remove tokens, credentials, user content, and tenant data.

- type: checkboxes
id: boundary
attributes:
label: Boundary confirmation
options:
- label: I reproduced this at the exact commit above with synthetic or sanitized data.
required: true
- label: This is a defect report, not a feature or hosted-product roadmap request.
required: true
- label: This report contains no vulnerability details, credentials, private data, or secrets.
required: true
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,25 @@ For a claim-by-claim proof map, start with
| Three-project stack map | [docs/STACK_OVERVIEW.md](docs/STACK_OVERVIEW.md) | Explains how gdev-agent, Eval Ground Truth Lab, and Agent Runtime Grid fit together as workflow, quality, and runtime layers |
| One-page engineering story | [docs/CASE_STUDY.md](docs/CASE_STUDY.md) | Evidence-backed case study for problem, architecture, controls, eval, load, trade-offs, and production changes |
| Architecture and workflow boundaries | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md), [docs/architecture-diagram.md](docs/architecture-diagram.md) | Implemented local stack with documented gaps and ADRs |
| Human approval decision path | [docs/APPROVAL_FLOW.md](docs/APPROVAL_FLOW.md) | Code-and-test-backed risk, tenant, TTL, reject, and one-time execution flow; not an operator UI or routing-quality claim |
| Agent harness boundary | [docs/HARNESS_CARD.md](docs/HARNESS_CARD.md), [docs/TRACE_SCHEMA.md](docs/TRACE_SCHEMA.md), [AGENTS.md](AGENTS.md) | Model + prompt/tool loop + guards + approvals + trace + eval are reviewed as one bounded harness |
| Repeatable demo path | [docs/DEMO.md](docs/DEMO.md) | Local Compose demo with deterministic/free mode |
| Evaluation discipline | [docs/EVALUATION.md](docs/EVALUATION.md), [docs/EVAL_REPORT.md](docs/EVAL_REPORT.md), [docs/EVAL_SCOPE_RECONCILIATION.md](docs/EVAL_SCOPE_RECONCILIATION.md) | 180-case internal smoke eval, 55-case Eval Lab conformance baseline, and a canonical 100-case challenge run whose stricter gate failed |
| Canonical failure preview | [docs/evidence/GDEV_EVAL_FAILURE_PREVIEW_2026-07-13.md](docs/evidence/GDEV_EVAL_FAILURE_PREVIEW_2026-07-13.md) | Rendered from Eval Lab `v0.2.0` content-addressed raw JSON; five failed thresholds remain visible and limitations are explicit |
| Observability | [docs/observability.md](docs/observability.md) | Metrics, traces, logs, and alerting design for local evidence |
| Load profile | [docs/load-profile.md](docs/load-profile.md), [docs/LOAD_TEST_REPORT.md](docs/LOAD_TEST_REPORT.md) | Local deterministic/synthetic report and scenario targets; not production capacity claims |
| Tenant isolation and security | [docs/TENANT_ISOLATION.md](docs/TENANT_ISOLATION.md), [docs/data-map.md#6-tenant-isolation-model](docs/data-map.md#6-tenant-isolation-model), [docs/ARCHITECTURE.md#7-security-model](docs/ARCHITECTURE.md#7-security-model) | RLS, tenant-scoped JWT, webhook signature, secrets, approval, and cost ledger boundaries |
| Tests | [Current State](#current-state) | 2026-07-13 local baseline: 310 passing tests; rerun locally before relying on it |
| Tests | [Current State](#current-state), [maintainer-surface verification](docs/evidence/GDEV_MAINTAINER_SURFACE_2026-07-13.md) | P0 code baseline: 310 passing tests at `0e4c5f0`; 2026-07-13 maintainer-surface verification: 312 passing tests after two documentation contract tests |
| Failure modes and SLO/runbook | [docs/FAILURE_MODES.md](docs/FAILURE_MODES.md), [docs/SLO_RUNBOOK.md](docs/SLO_RUNBOOK.md), [docs/observability.md#alert-runbooks](docs/observability.md#alert-runbooks) | Local taxonomy and runbook evidence; external incident evidence is out of scope |
| Deployment readiness boundaries | [docs/DEPLOYMENT_READINESS.md](docs/DEPLOYMENT_READINESS.md), [Known Limits](#known-limits) | Secrets checklist, backup/restore notes, local production-like config, and known limitations without production readiness claims |
| Known limits and production changes | [Known Limits](#known-limits), [docs/DEPLOYMENT_READINESS.md](docs/DEPLOYMENT_READINESS.md) | Explicitly bounded as local reference evidence, not production SaaS readiness |

[![Canonical Eval Lab challenge failure preview](docs/assets/gdev-eval-lab-challenge-fail.svg)](docs/evidence/GDEV_EVAL_FAILURE_PREVIEW_2026-07-13.md)

The image is a preview of pinned negative evidence, not a current quality-pass
badge. Follow it to the exact Eval Lab tag, raw JSON hashes, rendering command,
and interpretation boundary.

## Why This Project Exists

The synthetic reference scenario covers billing disputes, account-access
Expand Down Expand Up @@ -248,6 +256,9 @@ Most endpoints outside `/health`, `/webhook`, and `/metrics` require JWT auth pl
- [docs/HARNESS_CARD.md](docs/HARNESS_CARD.md): agent harness boundary across model, tools, memory, retries, permissions, HITL, trace, and eval.
- [docs/TRACE_SCHEMA.md](docs/TRACE_SCHEMA.md): trace completeness contract for debugging, eval, audit, and approval retrospectives.
- [docs/architecture-diagram.md](docs/architecture-diagram.md): GitHub-rendered architecture diagram for the main workflow.
- [docs/APPROVAL_FLOW.md](docs/APPROVAL_FLOW.md): implemented human-approval decision path with focused regression commands and limits.
- [docs/evidence/GDEV_EVAL_FAILURE_PREVIEW_2026-07-13.md](docs/evidence/GDEV_EVAL_FAILURE_PREVIEW_2026-07-13.md): content-addressed preview of the canonical failed Eval Lab challenge.
- [docs/evidence/GDEV_MAINTAINER_SURFACE_2026-07-13.md](docs/evidence/GDEV_MAINTAINER_SURFACE_2026-07-13.md): local receipt for the maintainer, visual, full-suite, eval, and Compose gates.
- [docs/CASE_STUDY.md](docs/CASE_STUDY.md): concise evidence-backed engineering case study.
- [docs/spec.md](docs/spec.md): product scope, API intent, and behavioral contract.
- [docs/N8N.md](docs/N8N.md): n8n integration and approval workflow blueprint.
Expand All @@ -261,6 +272,17 @@ Most endpoints outside `/health`, `/webhook`, and `/metrics` require JWT auth pl
- [n8n/README.md](n8n/README.md): workflow assets committed in this repository.
- [AGENTS.md](AGENTS.md): operating rules for coding/ops agents working in this repo.

## Maintainer Paths

- Suspected vulnerabilities must follow the private path in
[SECURITY.md](SECURITY.md); do not disclose them in a public issue.
- Supported local defects use the
[reproducible bug form](https://github.com/ashishki/gdev-agent/issues/new?template=reproducible-bug.yml)
with an exact commit, sanitized environment, and deterministic commands.
- There is no generic feature or hosted-product roadmap intake. The maintained
boundary is the current local reference workload described in
[Current Maturity](#current-maturity).

## Known Limits

- The project is a tested local reference workload. It has no claimed external
Expand Down Expand Up @@ -303,4 +325,10 @@ demo eval gate and a clean Compose auth/approval demo. Exact commands and
bounded outputs are recorded in
[docs/evidence/GDEV_P0_TRUTH_REPAIR_2026-07-13.md](docs/evidence/GDEV_P0_TRUTH_REPAIR_2026-07-13.md).

The later maintainer/evidence-surface tranche added two focused documentation
contracts and reran the complete local suite at 312 passing tests, along with
Ruff, the non-writing 180-case eval gate, and an isolated default-Compose RLS
and approval demo. Its bounded receipt is
[docs/evidence/GDEV_MAINTAINER_SURFACE_2026-07-13.md](docs/evidence/GDEV_MAINTAINER_SURFACE_2026-07-13.md).

The main value is the governed request pipeline: webhook in → guardrails → LLM-assisted triage → human approval where needed → auditable execution throughout, with tenant isolation enforced at the database layer and observable at every step.
54 changes: 54 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Security Policy

`gdev-agent` is a maintained local reference workload, not a hosted service.
Security reports are welcome when they affect the supported boundary below.

## Supported Boundary

| Surface | Support status |
| --- | --- |
| Current `master` at an identified commit SHA | Supported |
| Documented default local Docker Compose topology | Supported |
| Signed webhook, JWT/RBAC, approval, tenant/RLS, secrets, and output-guard paths | Supported |
| Older commits, unmerged branches, and forks | Not supported |
| Operator-modified deployments and third-party infrastructure | Not supported |
| Live-provider, customer-data, or production operations | No supported deployment exists |

There is no tagged stable product release or production security SLA. A report
should name the exact commit and demonstrate impact with synthetic or sanitized
data whenever possible.

Security-relevant examples include cross-tenant access, bypass of JWT/RBAC or
webhook-signature checks, execution without required approval, disclosure of
stored secrets, an output-guard bypass, and unsafe default Compose role or RLS
configuration. Ordinary reproducible defects belong in the
[bug form](https://github.com/ashishki/gdev-agent/issues/new?template=reproducible-bug.yml).

## Report Privately

Do **not** open a public issue for a suspected vulnerability.

1. Email `verter25@gmail.com` with subject `gdev-agent security report`.
Include the affected commit, prerequisites, a minimal reproduction, impact,
and any suggested mitigation. Keep the first message minimal and do not
attach secrets, tokens, customer data, or an exploit against a system you do
not own. A safer detail-transfer channel can be agreed before sending
sensitive material.
2. GitHub private vulnerability reporting is not enabled for this repository
as of 2026-07-13. If the repository's
[Security page](https://github.com/ashishki/gdev-agent/security) later shows
a **Report a vulnerability** button, that enabled private form is also an
acceptable path. Do not rely on the direct advisory URL unless GitHub shows
the feature as enabled.

Please allow coordinated remediation before public disclosure. This
maintainer-run reference project cannot promise a response or fix deadline, but
reports will be triaged against the explicit support boundary above. Never test
against infrastructure or data without authorization.

## Public Disclosure

After a fix is available, the maintainer may publish a GitHub Security Advisory
with affected commits, impact, remediation, and credit if requested. Public
write-ups must not expose credentials, private data, or instructions that would
put an unpatched deployment at avoidable risk.
74 changes: 74 additions & 0 deletions docs/APPROVAL_FLOW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Human Approval Flow

This diagram maps the implemented local decision path from a signed webhook to
one-time human approval. It is a code-and-test-backed control-flow view, not an
operator UI, production deployment claim, or proof that every policy decision
is correct.

```mermaid
flowchart TD
webhook[POST /webhook\nsynthetic or operator request] --> ingress[Per-tenant HMAC + input guard]
ingress --> propose[Classify, extract, propose action\nand apply output/exemplar guards]
propose --> route{Risky action, approval-required tool,\nor bulk/destructive side effect?}

route -->|No| execute[Execute registered tool]
route -->|Yes| pending[Create tenant-scoped PendingDecision\nRedis TTL + durable pending row]
pending --> response[Return pending_id + draft\nwithout executing the tool]
response --> review[POST /approve\nJWT support_agent or tenant_admin\n+ X-Approve-Secret when configured]

review --> tenant{JWT tenant owns\npending_id?}
tenant -->|No / missing / expired| deny[401 / 403 / 404\nno action execution]
tenant -->|Yes| consume[Atomic GETDEL\nconsume one time]
consume --> decision{Reviewer decision}
decision -->|Reject| rejected[Record rejection\nno action execution]
decision -->|Approve| approved[Execute original action\nfor original user]

execute --> audit[Persist audit / action evidence]
rejected --> audit
approved --> audit
```

## Implementation Map

| Diagram boundary | Authoritative implementation | Focused proof |
| --- | --- | --- |
| Risk and tool-side-effect gate | `AgentService.needs_approval()` in `app/agent.py` | `tests/test_agent.py`, `tests/test_tool_registry.py` |
| Tenant-scoped pending state and TTL | `RedisApprovalStore` in `app/approval_store.py` | `tests/test_redis_approval_store.py` |
| JWT role and tenant context | `JWTMiddleware` and `require_role()` | `tests/test_auth.py`, `tests/test_rbac.py` |
| Optional approval secret | `ApprovalService.verify_hmac()` | `tests/test_approval_service.py::test_handle_rejects_wrong_approve_secret` |
| Cross-tenant, expired, reject, and one-time behavior | `AgentService.approve()` | `tests/test_approval_flow.py` |
| Approval/rejection audit records | `_record_approval_event()` and event store calls | `tests/test_approval_flow.py`, `tests/test_approval_service.py` |

Run the control-flow regression proof from the repository root:

```bash
PYTHONDONTWRITEBYTECODE=1 LLM_MODE=demo \
python -m pytest \
tests/test_approval_flow.py \
tests/test_approval_service.py \
tests/test_redis_approval_store.py \
tests/test_rbac.py -q
```

The default local Compose proof additionally checks database role flags, forced
RLS, tenant-A reads, and cross-tenant write rejection:

```bash
bash scripts/verify_compose_rls.sh
```

## Boundaries and Known Limits

- The diagram shows the repository's current local path. n8n/Telegram button
rendering and external identity-provider controls are outside this proof.
- `X-Approve-Secret` is a defense-in-depth check only when `APPROVE_SECRET` is
configured. JWT role and tenant ownership remain required for `/approve`.
- A wrong tenant receives no pending object because Redis keys are tenant
scoped. Expired and already-consumed decisions also return not found.
- Redis coordinates one-time consumption; Postgres stores durable pending and
approval records in the configured Compose path. This is not a proof of
failover behavior for an externally operated deployment.
- The canonical Eval Lab challenge still reports failed human-routing quality
thresholds. See the [failure preview](evidence/GDEV_EVAL_FAILURE_PREVIEW_2026-07-13.md);
implemented approval mechanics do not imply that candidate policy routes
every risky input correctly.
Loading