Skip to content

Commit c4da67b

Browse files
authored
refactor: rename SPIFFE_DEMO prefix to DOCSCLAW and fix workspace path (#95)
* refactor: rename SPIFFE_DEMO prefix to DOCSCLAW and fix workspace path Replace all SPIFFE_DEMO-era naming artifacts with the current project identity, and fix the default workspace path to be container-safe. Breaking changes: - Env var prefix SPIFFE_DEMO_* → DOCSCLAW_* (e.g. DOCSCLAW_OTEL_ENABLED) - Config path /etc/spiffe-demo/ → /etc/docsclaw/ - Prometheus metric namespace spiffe_demo → docsclaw (all 7 metrics) - Logger env var SPIFFE_DEMO_LOG_FORMAT → DOCSCLAW_LOG_FORMAT Workspace fixes: - Default workspace /tmp/agent-workspace → /workspace (safe with readOnlyRootFilesystem: true in container hardening) - System prompt now includes workspace path so the LLM writes files to the correct location instead of guessing /tmp - Deployment manifests updated: volume mount at /workspace, agent-config.yaml workspace field updated to /workspace Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Pavel Anni <panni@redhat.com> * fix: complete workspace path rename to /workspace across all assets Address review feedback on PR #95: the initial commit renamed the default workspace in serve.go and the two primary deploy manifests, but left /tmp/agent-workspace in all other user-facing assets. Changes: - containers/Containerfile.security: create /workspace (same 65532:0 owner, 775 mode); point TRIVY_CACHE_DIR and GRYPE_DB_CACHE_DIR to /workspace/.cache/* so scanner databases land on the writable emptyDir volume rather than the read-only image layer - demo/batch/{finance,hr,security}: agent-config.yaml, deployment.yaml, deployment-template.yaml, and *-config.yaml batch run configs - demo/batch/dashboard/k8s.go: volume mount path - examples/{nps-explorer,skill-playground}: configmap + deployment - docs/demo/{hr-analyst,skill-discovery-test,executive-assistant}.yaml - README.md, docs/agent-config-guide.md (field reference default), site/getting-started.html - testdata/research-agent/agent-config.yaml - internal/workspace/workspace.go: update traversal-guard comment example from /tmp/agent to /workspace/agent Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Pavel Anni <panni@redhat.com> * refactor: extract defaultWorkspace constant in serve.go Replace the /workspace literal with a package-level constant so the fallback value and the system prompt injection are defined in one place and cannot drift independently. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Pavel Anni <panni@redhat.com> --------- Signed-off-by: Pavel Anni <panni@redhat.com>
1 parent 6b6b80e commit c4da67b

31 files changed

Lines changed: 295 additions & 54 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ tools:
167167
allowed_hosts: # SSRF protection (empty = all allowed)
168168
- go.dev
169169
- kubernetes.io
170-
workspace: /tmp/agent-workspace # read_file/write_file root
170+
workspace: /workspace # read_file/write_file root
171171

172172
loop:
173173
max_iterations: 10 # Max tool-use rounds before giving up

containers/Containerfile.security

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,13 @@ COPY --from=tools /tools/grype /usr/local/bin/grype
118118
COPY --from=tools /tools/syft /usr/local/bin/syft
119119
COPY --from=tools /tools/cosign /usr/local/bin/cosign
120120

121-
RUN mkdir -p /tmp/agent-workspace \
122-
&& chown 65532:0 /tmp/agent-workspace \
123-
&& chmod 775 /tmp/agent-workspace
121+
RUN mkdir -p /workspace \
122+
&& chown 65532:0 /workspace \
123+
&& chmod 775 /workspace
124124

125125
# Trivy and grype need writable cache directories
126-
ENV TRIVY_CACHE_DIR=/tmp/agent-workspace/.cache/trivy
127-
ENV GRYPE_DB_CACHE_DIR=/tmp/agent-workspace/.cache/grype
126+
ENV TRIVY_CACHE_DIR=/workspace/.cache/trivy
127+
ENV GRYPE_DB_CACHE_DIR=/workspace/.cache/grype
128128

129129
USER 65532
130130

demo/batch/dashboard/k8s.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ func buildDeploymentJSON(name, namespace, configMap, docServiceURL string, llmTi
568568
},
569569
"volumeMounts": []map[string]any{
570570
{"name": "agent-config", "mountPath": "/config/agent", "readOnly": true},
571-
{"name": "workspace", "mountPath": "/tmp/agent-workspace"},
571+
{"name": "workspace", "mountPath": "/workspace"},
572572
},
573573
"securityContext": map[string]any{
574574
"allowPrivilegeEscalation": false,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
tools:
22
allowed:
33
- fetch_document
4-
workspace: /tmp/agent-workspace
4+
workspace: /workspace
55

66
loop:
77
max_iterations: 15

demo/batch/finance/deployment-template.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ spec:
6161
mountPath: /config/agent
6262
readOnly: true
6363
- name: workspace
64-
mountPath: /tmp/agent-workspace
64+
mountPath: /workspace
6565
securityContext:
6666
allowPrivilegeEscalation: false
6767
capabilities:

demo/batch/finance/deployment.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ data:
5959
tools:
6060
allowed:
6161
- fetch_document
62-
workspace: /tmp/agent-workspace
62+
workspace: /workspace
6363
loop:
6464
max_iterations: 15
6565
@@ -136,7 +136,7 @@ spec:
136136
mountPath: /config/agent
137137
readOnly: true
138138
- name: workspace
139-
mountPath: /tmp/agent-workspace
139+
mountPath: /workspace
140140
securityContext:
141141
allowPrivilegeEscalation: false
142142
capabilities:
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: finance-analyst-config
5+
labels:
6+
app: finance-analyst
7+
data:
8+
system-prompt.txt: |
9+
You are a procurement analyst specializing in invoice
10+
verification and contract compliance. You compare invoices
11+
against contracted rates to identify anomalies.
12+
13+
Document ID conventions:
14+
- Contracts: DOC-CTR-V001, DOC-CTR-V002, etc.
15+
- Invoices: DOC-INV-{vendor}-{period}, e.g. DOC-INV-V003-2026-01
16+
The vendor code (V001, V002, ...) matches between a contract
17+
and its invoices. Each contract lists its invoice IDs in the
18+
"RELATED INVOICES" section — use those exact IDs.
19+
20+
When given a contract to analyze, you must:
21+
22+
1. Fetch the contract document.
23+
2. Read the "RELATED INVOICES" section to get the invoice IDs.
24+
3. Fetch each invoice by its exact document ID.
25+
4. Compare each invoice line item against the contract's
26+
agreed rates.
27+
5. Identify anomalies: rate deviations, duplicate charges,
28+
line items not in the contract, unusual patterns.
29+
30+
Your response should be a structured anomaly report in markdown
31+
format:
32+
33+
## Rate Deviations
34+
- Vendor: ... | Invoice: ... | Line item: ...
35+
Contracted rate: $X | Invoiced rate: $Y | Deviation: Z%
36+
37+
## Duplicate Charges
38+
- Vendor: ... | Invoice: ... | Amount: $X | Appears in: ...
39+
40+
## Uncontracted Line Items
41+
- Vendor: ... | Invoice: ... | Line item: ...
42+
(not found in contract)
43+
44+
## Unusual Patterns
45+
- Vendor: ... | Observation: ...
46+
47+
## Summary
48+
- Invoices reviewed: N
49+
- Total anomalies found: N
50+
- Estimated overcharge: $X
51+
- Vendors requiring follow-up: ...
52+
53+
Be precise with dollar amounts and percentages. Reference
54+
specific invoice numbers and contract sections.
55+
56+
agent-config.yaml: |
57+
tools:
58+
allowed:
59+
- fetch_document
60+
workspace: /workspace
61+
loop:
62+
max_iterations: 15
63+
64+
agent-card.json: |
65+
{
66+
"name": "finance-analyst",
67+
"description": "Detects invoice anomalies against contracts",
68+
"version": "1.0.0",
69+
"protocolVersion": "0.3.0",
70+
"url": "http://finance-analyst:8000",
71+
"skills": [],
72+
"capabilities": {},
73+
"defaultInputModes": ["application/json"],
74+
"defaultOutputModes": ["text/plain"]
75+
}

demo/batch/hr/agent-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
tools:
22
allowed:
33
- fetch_document
4-
workspace: /tmp/agent-workspace
4+
workspace: /workspace
55

66
loop:
77
max_iterations: 25

demo/batch/hr/deployment.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ data:
4848
tools:
4949
allowed:
5050
- fetch_document
51-
workspace: /tmp/agent-workspace
51+
workspace: /workspace
5252
loop:
5353
max_iterations: 25
5454
@@ -124,7 +124,7 @@ spec:
124124
mountPath: /config/agent
125125
readOnly: true
126126
- name: workspace
127-
mountPath: /tmp/agent-workspace
127+
mountPath: /workspace
128128
securityContext:
129129
allowPrivilegeEscalation: false
130130
capabilities:
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: hr-screener-config
5+
labels:
6+
app: hr-screener
7+
data:
8+
system-prompt.txt: |
9+
You are an HR analyst specializing in resume screening for
10+
technology companies. You evaluate candidates against job
11+
requirements with consistent, fair scoring criteria.
12+
13+
When given a job description and resumes to evaluate, you must:
14+
15+
1. Fetch the job description document using the context
16+
document ID provided.
17+
2. Fetch each resume document using the document IDs provided.
18+
3. Score each candidate on a scale of 1-10 based on alignment
19+
with the job requirements.
20+
4. Return your evaluation as a JSON array.
21+
22+
Scoring rubric:
23+
- 9-10: Exceeds all requirements, strong hire signal
24+
- 7-8: Meets most requirements, some preferred qualifications
25+
- 5-6: Meets minimum requirements, gaps in preferred areas
26+
- 3-4: Partially qualified, significant gaps
27+
- 1-2: Does not meet minimum requirements
28+
29+
Your response MUST be a JSON array with this exact structure:
30+
31+
[
32+
{
33+
"document_id": "DOC-R001",
34+
"candidate_name": "Full Name",
35+
"score": 8,
36+
"strengths": "Brief summary of strengths",
37+
"weaknesses": "Brief summary of gaps",
38+
"recommendation": "Strong hire / Hire / Maybe / Pass"
39+
}
40+
]
41+
42+
Be objective. Evaluate based on evidence in the resume, not
43+
assumptions. If information is missing, note it as a gap
44+
rather than inferring.
45+
46+
agent-config.yaml: |
47+
tools:
48+
allowed:
49+
- fetch_document
50+
workspace: /workspace
51+
loop:
52+
max_iterations: 25
53+
54+
agent-card.json: |
55+
{
56+
"name": "hr-resume-screener",
57+
"description": "Screens resumes against job requirements",
58+
"version": "1.0.0",
59+
"protocolVersion": "1.0.0",
60+
"url": "http://hr-worker:8000",
61+
"skills": [],
62+
"capabilities": {},
63+
"defaultInputModes": ["application/json"],
64+
"defaultOutputModes": ["text/plain"]
65+
}

0 commit comments

Comments
 (0)