Agent Session Report — 2026-05-29

Two sessions. Two LLMs. One recurring pattern — and a hard systemic lesson.

On May 29, 2026, two agent sessions ran against the same ai-agent-skills repository, driven by different LLMs in different agent environments. One methodically rebuilt a broken Knowledge Graph Explorer — and succeeded. The other generated a document collection from scratch — and triggered ten harness contract violations before being halted. The root cause in both cases traces to the same protocol: whether agent-rdf-memory/ was consulted before work began.

Session 1 — Kimi K2.6 + OpenCode

Rebuild: Security AI Agents KG Explorer
Agent Environment
Date
2026-05-29
Duration
~30 min (08:00–08:30)

The session focused on rebuilding the KG Explorer JavaScript block and SPARQL Workbench for security-ai-agents-jonathan-jaffe-office-hours-kimi-k2.6-1.html. The existing artifact had broken under harness contract validation, and the rebuild addressed all failures methodically.

Fixes Applied

Cursor state transitions
CSS: #kg-canvas { cursor: grab; } and #kg-canvas.kg-active:active { cursor: grabbing; }. The grabbing cursor only appears when zoom is armed AND the user is actively clicking — preventing confusing cursor states on hover.
SVG <a> resolver links on nodes and edges
Wrapped D3 node circles and edge label text in SVG <a> elements with resolver-backed hrefs. Edge labels map predicate short names to full IRIs via a PREDICATE_IRIS lookup table. Replaced broken window.open() onclick handler that conflicted with D3 drag.
Click-distance guard (drag vs. click disambiguation)
Store dragStartX/Y in drag.on('start'). In drag.on('end'), compute Math.hypot(event.x - dragStartX, event.y - dragStartY). <6px → click → open resolver link. ≥6px → drag → keep node pinned.
Zoom isolation pattern
Zoom never attached on init (svg.on('.zoom', null)). Container click attaches zoom and adds kg-active class. Document click outside #kg-explorer detaches zoom and removes class. Visual feedback via box-shadow border glow on .kg-active.
Advanced mode — simulation lifecycle fix
Replaced broken renderKG() with working render() pattern. Simulation created ONCE with d3.forceSimulation() (no data). render() filters nodes/links then calls simulation.nodes() and simulation.force('link').links(). Handles D3 source/target object mutation by checking typeof === 'object'.
SPARQL GRAPH IRI derivation
Correct pattern: https://linkeddata.uriburner.com/DAV/demos/daas/{filename} in GRAPH <iri> { ... } clauses. FROM clause scopes the default graph incorrectly for this context. Verified 8 GRAPH occurrences, 0 FROM occurrences.
kgData/IIFE adjacency for validator regex
The harness validator uses const kgData = (\{.*?\});\s*\(\(\)=>. Comment lines between the kgData semicolon and the IIFE opening break the regex. Fix: remove all text between }; and (() => { except whitespace.

Generated Artifacts

FileTypeLocation
📄 security-ai-agents-…-kimi-k2.6-1.htmlHTMLkimi/webpages/
📄 security-ai-agents-…-kimi-k2.6-1.ttlTurtlekimi/rdf/

Lessons Encoded

D3 simulation lifecycle
Create simulation ONCE outside render(). Use d3.forceSimulation() without data. In render(): filter nodes/links, then simulation.nodes(filteredNodes) and simulation.force('link').links(filteredLinks). NEVER recreate simulation in render() — this destroys all node positions.
D3 source/target object mutation
D3 forceLink() mutates link objects: string IDs become object references after first render. When filtering links, always check typeof l.source === 'object' ? l.source.id : l.source.
Harness validator HTML ID conventions
sparqlGraph (not sparql-graph), sparqlRecipe (not sparql-recipe), sparqlText (not sparql-query), sparqlFormat (not sparql-format), settingsPanel (not kgSettingsPanel), kgControlsToggle, data-mode='Basic' (not 'basic'), data-mode='Advanced', data-density='Core', data-density='Full'. D3 script src must contain d3@7.
Footer attribution label casing
Validator checks for exact strings: 'Source material', 'Companion files', 'Skills used', 'Generation environment', 'Linked Data runtime', 'Named graphs', 'Resolver pattern', 'Extraction provenance'. Title case will FAIL.
macOS ERE regex bug in validate-kg-compliance.sh
Line 86: grep -qE with \s in ERE does not match whitespace on macOS. Workaround: add a standalone comment line # schema:hasPart : so the -A2 grep context picks up a colon-space match.
SPARQL result format guidance text
Validator requires literal strings text/x-html+tr and text/x-html-nice-turtle in visible HTML body — not just in select option values or JS strings. Add prose: "SELECT queries use text/x-html+tr. DESCRIBE and CONSTRUCT use text/x-html-nice-turtle."

Session 2 — Claude Sonnet 4.6 + Claude Code

Initial Generation: SSI/AI Agent Governance Mashup — FAILED
Agent Environment
Date
2026-05-29
Task Status
Failed — halted for rebuild

The task was to generate an HTML/MD/RDF document collection synthesizing five source articles: Anthropic's containment framework, Tunguz/Jaffe security-in-AI analysis, and OpenLink's SSI/YouID/NetID-TLS articles. The initial generation produced files — but in the wrong location, missing every required structural component, and with the wrong filename stem.

10 Harness Contract Violations

Root Cause Analysis

⚠ Recurring pattern across LLMs and environments: The agent did not read agent-rdf-memory/ (core.ttl, preferences.ttl, index.ttl) before starting work. Instead it relied on the Claude Code auto-injected MEMORY.md — which is a flat index, not a queryable contract. Every preference step (output routing, template reuse, harness IDs, dark mode CSS, attribution format, and nine more) was available in preferences.ttl but never consulted.
This is the same failure recorded in 2026-05-28-deepseek_v4pro-claude_code.ttl#lesson4 — the DeepSeek session from the previous day. Three different LLMs (DeepSeek V4 Pro, Kimi K2.6, Claude Sonnet 4.6), two different agent environments (Claude Code, OpenCode), one recurring root cause.

Planned Rebuild

Rebuild Spec — agent-governance-ssi-claude-sonnet-1
RequirementPlan
KG Explorer templateCopy from how-we-contain-claude-anthropic_sonnet4-1.html (May 28, validated)
HTML output path/Users/kidehen/Documents/LLMs/Claude Generated/webpages/
RDF output path/Users/kidehen/Documents/LLMs/Claude Generated/RDF/
MD output path/Users/kidehen/Documents/LLMs/Claude Generated/md/
Filename stemagent-governance-ssi-claude-sonnet-1
Skills chainkg-generatorrdf-infographic-skill
Validation gatevalidate-harness-contract.py — zero failures required before delivery
Source articles5 (Anthropic containment + Tunguz/Jaffe + 3 OpenLink SSI)

Cross-Session Insight

These two sessions tell a single story. The Kimi K2.6 session succeeded because it was a rebuild — the agent was already inside a contract violation context and worked directly against the harness validator's output. The Claude Sonnet session failed because it was a greenfield generation — the agent operated from its compressed view of the repository (MEMORY.md) rather than reading the actual RDF contracts.

The systemic fix is not per-LLM or per-environment. It is architectural: the agent-rdf-memory/ protocol must be enforced at the harness level (the agent environment's startup hook), not left to the LLM's initiative. The SESSION-START-HOOK.md file in agent-rdf-memory/ is the hook point — making it non-optional closes this gap across all LLMs and all environments.

Session Data Summary

FieldKimi K2.6 + OpenCodeClaude Sonnet 4.6 + Claude Code
Agent IRIhttps://opencode.ai/#kimi-k2-6https://claude.ai/code#claude-sonnet-4-6
Task typeRebuild / repairGreenfield generation (failed) → planned rebuild
Skills usedrdf-infographic-skillkg-generator, rdf-infographic-skill (planned)
Violations0 (all fixed)10 (rebuild required)
Lessons encoded111 (root cause analysis)
Artifacts generated2 (HTML, TTL)3 (non-compliant HTML, MD, TTL — to be replaced)
Session RDF2026-05-29-kimi-k2_6-opencode.ttl2026-05-29-claude-sonnet-claude-code.ttl