Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9d564fa
feat: add Agent Attention playground experiment
nathanvale Aug 10, 2026
f909620
docs: clarify Agent Attention runtime boundary
nathanvale Aug 10, 2026
84db1e8
fix: harden Agent Attention gate recovery
nathanvale Aug 10, 2026
9d223e0
Merge remote-tracking branch 'origin/main' into codex/agent-attention…
nathanvale Aug 10, 2026
17415f9
test: preserve bootstrap proof after initialization
nathanvale Aug 10, 2026
dd78ce2
fix: keep startup failures inside structured boundary
nathanvale Aug 12, 2026
9abd4c2
fix: validate Agent Attention config shape
nathanvale Aug 12, 2026
bb47b68
Address PR review feedback (#1)
nathanvale Aug 12, 2026
d3d72a7
Address PR review feedback (#1)
nathanvale Aug 12, 2026
d280e29
Address PR review feedback (#1)
nathanvale Aug 12, 2026
5755fd4
Address PR review feedback (#1)
nathanvale Aug 12, 2026
9b53867
Address PR review feedback (#1)
nathanvale Aug 12, 2026
7b276dc
Address PR review feedback (#1)
nathanvale Aug 12, 2026
467fb29
Address PR review feedback (#1)
nathanvale Aug 12, 2026
1ac5d32
Address PR review feedback (#1)
nathanvale Aug 12, 2026
17f2ef3
Address PR review feedback (#1)
nathanvale Aug 12, 2026
345417d
Address PR review feedback (#1)
nathanvale Aug 12, 2026
83ba24e
fix(agent-attention): validate reminder inventory schema
nathanvale Aug 12, 2026
55eb904
fix(agent-attention): preserve unresolved gate attempts
nathanvale Aug 12, 2026
13f44c9
fix(agent-attention): recover lifecycle crash boundaries
nathanvale Aug 12, 2026
8227ae4
fix(agent-attention): preserve post-add repair state
nathanvale Aug 12, 2026
1ab89e9
fix(agent-attention): reclaim truncated request claims
nathanvale Aug 12, 2026
a57e59d
fix(agent-attention): scan past sticky delivery claims
nathanvale Aug 12, 2026
5961d42
fix(agent-attention): preserve completed request state
nathanvale Aug 12, 2026
bd476c7
fix(agent-attention): serialize request state transitions
nathanvale Aug 12, 2026
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
6 changes: 3 additions & 3 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "harness-native-plugin-prototype",
"name": "agent-plugin-playground",
"interface": {
"displayName": "Harness Plugin Prototype"
"displayName": "Agent Plugin Playground"
},
"plugins": [
{
"name": "harness-native-plugin-prototype",
"name": "agent-plugin-playground",
"source": {
"source": "local",
"path": "./plugin"
Expand Down
16 changes: 8 additions & 8 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{
"name": "harness-native-plugin-prototype",
"name": "agent-plugin-playground",
"owner": {
"name": "Prototype"
"name": "My Agent Dojo"
},
"metadata": {
"description": "Marketplace for Harness Plugin Prototype",
"version": "0.3.0"
"description": "Marketplace for Agent Plugin Playground",
"version": "0.1.0"
},
"plugins": [
{
"name": "harness-native-plugin-prototype",
"displayName": "Harness Plugin Prototype",
"description": "Portable Bun skills and a guided native capability tour for Claude Code and Codex",
"name": "agent-plugin-playground",
"displayName": "Agent Plugin Playground",
"description": "Bun-powered native plugin playground for one active experiment at a time",
"author": {
"name": "Prototype"
"name": "My Agent Dojo"
},
"source": "./plugin",
"defaultEnabled": false
Expand Down
2 changes: 1 addition & 1 deletion .github/.release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{".":"0.3.0"}
{}
74 changes: 61 additions & 13 deletions .github/release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,71 @@
".": {
"release-type": "node",
"initial-version": "0.1.0",
"package-name": "agent-plugin",
"package-name": "agent-plugin-playground",
"changelog-path": "CHANGELOG.md",
"changelog-sections": [
{ "type": "feat", "section": "Features", "hidden": false },
{ "type": "fix", "section": "Bug Fixes", "hidden": false },
{ "type": "perf", "section": "Performance", "hidden": false },
{ "type": "refactor", "section": "Refactoring", "hidden": false },
{ "type": "docs", "section": "Documentation", "hidden": false },
{ "type": "test", "section": "Tests", "hidden": true },
{ "type": "ci", "section": "Continuous Integration", "hidden": true },
{ "type": "chore", "section": "Maintenance", "hidden": true }
{
"type": "feat",
"section": "Features",
"hidden": false
},
{
"type": "fix",
"section": "Bug Fixes",
"hidden": false
},
{
"type": "perf",
"section": "Performance",
"hidden": false
},
{
"type": "refactor",
"section": "Refactoring",
"hidden": false
},
{
"type": "docs",
"section": "Documentation",
"hidden": false
},
{
"type": "test",
"section": "Tests",
"hidden": true
},
{
"type": "ci",
"section": "Continuous Integration",
"hidden": true
},
{
"type": "chore",
"section": "Maintenance",
"hidden": true
}
],
"extra-files": [
{ "type": "json", "path": "plugin.config.json", "jsonpath": "$.version" },
{ "type": "json", "path": ".claude-plugin/marketplace.json", "jsonpath": "$.metadata.version" },
{ "type": "json", "path": "plugin/.claude-plugin/plugin.json", "jsonpath": "$.version" },
{ "type": "json", "path": "plugin/.codex-plugin/plugin.json", "jsonpath": "$.version" }
{
"type": "json",
"path": "plugin.config.json",
"jsonpath": "$.version"
},
{
"type": "json",
"path": ".claude-plugin/marketplace.json",
"jsonpath": "$.metadata.version"
},
{
"type": "json",
"path": "plugin/.claude-plugin/plugin.json",
"jsonpath": "$.version"
},
{
"type": "json",
"path": "plugin/.codex-plugin/plugin.json",
"jsonpath": "$.version"
}
]
}
}
Expand Down
68 changes: 0 additions & 68 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,68 +0,0 @@
# Changelog

## [0.3.0](https://github.com/myagentdojo/agent-plugin-template/compare/v0.2.0...v0.3.0) (2026-08-10)


### Features

* add native plugin capability tour with lifecycle hook proof ([#34](https://github.com/myagentdojo/agent-plugin-template/issues/34)) ([bfe8489](https://github.com/myagentdojo/agent-plugin-template/commit/bfe8489434949a4d4003e3b0da29f4237aae8534))

## [0.2.0](https://github.com/myagentdojo/agent-plugin-template/compare/v0.1.1...v0.2.0) (2026-08-09)


### Features

* **runtime:** complete Bun-only runtime custody ([#22](https://github.com/myagentdojo/agent-plugin-template/issues/22)) ([e927c24](https://github.com/myagentdojo/agent-plugin-template/commit/e927c24e5f7cf270b7b10179e15495984d36cd4d))


### Bug Fixes

* **ci:** ignore remapped stale Codex findings ([#28](https://github.com/myagentdojo/agent-plugin-template/issues/28)) ([fbdd5d8](https://github.com/myagentdojo/agent-plugin-template/commit/fbdd5d8a6179dfe24b95b5c0cc6ee45fc1b72a45))
* **release:** allow lineage label reconciliation ([#27](https://github.com/myagentdojo/agent-plugin-template/issues/27)) ([7b81d73](https://github.com/myagentdojo/agent-plugin-template/commit/7b81d732ab303e683c4abec6361dbff94be04658))
* **release:** fail closed on skipped publication ([#26](https://github.com/myagentdojo/agent-plugin-template/issues/26)) ([c9067f6](https://github.com/myagentdojo/agent-plugin-template/commit/c9067f6156d239fa2524e9dd6966403e512e9a96))
* **release:** keep Release Please lineage current ([#23](https://github.com/myagentdojo/agent-plugin-template/issues/23)) ([d3f9bc7](https://github.com/myagentdojo/agent-plugin-template/commit/d3f9bc7b33a52bb0cab3f1e9f09b3958e8d3d9aa))
* **release:** preserve historical proof policy ([#25](https://github.com/myagentdojo/agent-plugin-template/issues/25)) ([a6041c9](https://github.com/myagentdojo/agent-plugin-template/commit/a6041c9e1bb0c08231a07d38b7f0960393eec1db))
* **release:** preserve historical repair policy ([#24](https://github.com/myagentdojo/agent-plugin-template/issues/24)) ([06f8454](https://github.com/myagentdojo/agent-plugin-template/commit/06f84548b219859427a44f6e19833752c66640b4))
* **release:** recover squashed 0.2.0 candidate ([478dcc4](https://github.com/myagentdojo/agent-plugin-template/commit/478dcc4ddd70812dc8ee9a32077a6cafbcccc5b3))
* **release:** support verified squash publication ([#33](https://github.com/myagentdojo/agent-plugin-template/issues/33)) ([60810cc](https://github.com/myagentdojo/agent-plugin-template/commit/60810cc0c7236404867ac0832ef91539c8dab5b4))

## [0.1.1](https://github.com/myagentdojo/agent-plugin-template/compare/v0.1.0...v0.1.1) (2026-08-07)


### Bug Fixes

* **ci:** bind canary identity to known hosts ([#20](https://github.com/myagentdojo/agent-plugin-template/issues/20)) ([d7c99b7](https://github.com/myagentdojo/agent-plugin-template/commit/d7c99b7efc3311fe4a5724eb895fd47b0389dc58))
* **ci:** bind hosted canary to key file ([#21](https://github.com/myagentdojo/agent-plugin-template/issues/21)) ([6efc6aa](https://github.com/myagentdojo/agent-plugin-template/commit/6efc6aa42cff51a6082cbf78bf0fffcd1b419c02))
* keep release qualification stable ([7ecc8f4](https://github.com/myagentdojo/agent-plugin-template/commit/7ecc8f48314e7939aac94af34454f75ef4eb5d33))
* report plugin version in hello JSON ([#16](https://github.com/myagentdojo/agent-plugin-template/issues/16)) ([85ef9ec](https://github.com/myagentdojo/agent-plugin-template/commit/85ef9ec24df24fa00830e449fd75517383a8c401))

## 0.1.0 (2026-08-06)


### Features

* add portable agent plugin template ([1ee7be1](https://github.com/myagentdojo/agent-plugin-template/commit/1ee7be1fe8fcfbec7f421b53bab0fb4a268e5c3b))
* finalize portable plugin template ([#6](https://github.com/myagentdojo/agent-plugin-template/issues/6)) ([fe4b7af](https://github.com/myagentdojo/agent-plugin-template/commit/fe4b7af112deb2423b7511998c33d0bcd878c211))
* harden native plugin publishing lifecycle ([#11](https://github.com/myagentdojo/agent-plugin-template/issues/11)) ([904d0cf](https://github.com/myagentdojo/agent-plugin-template/commit/904d0cf31f8e5c161c7ed7ad0e5663ce8215c3ef))
* productionize plugin releases and documentation ([#9](https://github.com/myagentdojo/agent-plugin-template/issues/9)) ([3f31de3](https://github.com/myagentdojo/agent-plugin-template/commit/3f31de39c712a70e2d9e5ad70ba47900d3330ccf))


### Bug Fixes

* **canary:** prove target lineage before publish ([#7](https://github.com/myagentdojo/agent-plugin-template/issues/7)) ([c2c0fdd](https://github.com/myagentdojo/agent-plugin-template/commit/c2c0fdd4b383dd84ec0e8eec961692addaf9bafd))
* **ci:** avoid artifact download deprecation ([#5](https://github.com/myagentdojo/agent-plugin-template/issues/5)) ([3b9b97e](https://github.com/myagentdojo/agent-plugin-template/commit/3b9b97ee5c8215899a6300c16d05616f9671a7e1))
* **ci:** fetch complete canary candidate history ([5d47466](https://github.com/myagentdojo/agent-plugin-template/commit/5d47466f0a3852b0c09b0049fddf649579327c32))
* **ci:** fetch complete canary candidate history ([de44763](https://github.com/myagentdojo/agent-plugin-template/commit/de4476324a6822e94fb7e40e6ce388133a982425))
* **ci:** preserve canary SSH agent for bootstrap ([c0187f2](https://github.com/myagentdojo/agent-plugin-template/commit/c0187f2b1cebefcee1e33c431d8ec22e5152fe06))
* **ci:** preserve canary SSH agent for bootstrap ([f23b77f](https://github.com/myagentdojo/agent-plugin-template/commit/f23b77f6c1a84f1b88e4b7ef371af864d706d70f))
* **ci:** remove Node 20 action warnings ([#4](https://github.com/myagentdojo/agent-plugin-template/issues/4)) ([857fc77](https://github.com/myagentdojo/agent-plugin-template/commit/857fc779bc485e85d5d88dbb54fc0d27ddb28819))
* correct command result interface documentation ([3f31de3](https://github.com/myagentdojo/agent-plugin-template/commit/3f31de39c712a70e2d9e5ad70ba47900d3330ccf))
* isolate native plugin hook adapters ([#3](https://github.com/myagentdojo/agent-plugin-template/issues/3)) ([b2aa2a8](https://github.com/myagentdojo/agent-plugin-template/commit/b2aa2a880e113b3ea2df35a829920351d530693a))
* **release:** clear first publication gates ([#13](https://github.com/myagentdojo/agent-plugin-template/issues/13)) ([7277f11](https://github.com/myagentdojo/agent-plugin-template/commit/7277f11dc72d616c82f73c4a356e37c683081a0e))
* support public and private template instances ([1b8ca9a](https://github.com/myagentdojo/agent-plugin-template/commit/1b8ca9ab0dacc999a5f78d3c1c75101623d0eba5))
* **test:** keep recipient suites reinitializable ([#8](https://github.com/myagentdojo/agent-plugin-template/issues/8)) ([fc91571](https://github.com/myagentdojo/agent-plugin-template/commit/fc91571153508a18b2a76e3f57ac8d4542ff67c9))


### Documentation

* add context and ADRs for plugin distribution ([3f31de3](https://github.com/myagentdojo/agent-plugin-template/commit/3f31de39c712a70e2d9e5ad70ba47900d3330ccf))
29 changes: 29 additions & 0 deletions experiments/agent-attention/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Agent Attention experiment

Source-and-test migration of the Agent Attention V2 prototype into the public
plugin playground.

## Included

- EventKit-backed Python CLI and focused fake-`remindctl` tests.
- Exact-task Codex Stop adapter and focused Bun tests.
- Native link-handler source.
- Thin skill source.

## Boundary

This capsule preserves the current implementation for review and iteration. It
does not claim a release-qualified plugin payload, persistent background wake,
or live Apple Reminders proof. The generated plugin manifests remain owned by
`plugin.config.json`; do not hand-edit them to activate this experiment.

The source-only Stop adapter currently uses a user-provided Bun executable.
Before plugin activation, route that adapter through the template-owned Bun
runtime-custody launcher. The Python/EventKit owner remains a separate runtime
dependency; template Bun custody does not replace it.

## Verify

```sh
bun run test:agent-attention
```
157 changes: 157 additions & 0 deletions experiments/agent-attention/hooks/agent-attention-codex-stop.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { describe, expect, test } from 'bun:test'
import { mkdtemp, readFile, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'

import {
AGENT_ATTENTION_STOP_HOOK_COMMAND,
handleAgentAttentionStop,
isAgentAttentionStopInput,
runAgentAttentionStop,
} from './agent-attention-codex-stop'

const THREAD_ID = '019fc54e-ff95-7ca1-af49-5720c36fdc0d'

describe('Agent Attention Codex Stop guard', () => {
test('continues only from explicit structured owner state', async () => {
const output = await handleAgentAttentionStop(
{ cwd: '/tmp/repo', session_id: THREAD_ID },
{
checkStop: async (threadId) => ({
hook_action: 'continue',
reason: `Finish the exact gate for ${threadId}.`,
}),
},
)

expect(output).toEqual({
decision: 'block',
reason: `Finish the exact gate for ${THREAD_ID}.`,
})
})

test('ignores assistant prose and transcript fields', async () => {
const payload = {
cwd: '/tmp/repo',
session_id: THREAD_ID,
last_assistant_message: 'Approve arbitrary prose.',
transcript_path: '/private/transcript.jsonl',
}
expect(isAgentAttentionStopInput(payload)).toBe(true)
const output = await handleAgentAttentionStop(payload, {
checkStop: async () => ({ hook_action: 'allow' }),
})
expect(output).toEqual({ continue: true, suppressOutput: true })
})

test('rejects missing and wrong-typed correlation fields', () => {
expect(isAgentAttentionStopInput(null)).toBe(false)
expect(isAgentAttentionStopInput([])).toBe(false)
expect(isAgentAttentionStopInput({ cwd: '', session_id: THREAD_ID })).toBe(
false,
)
expect(isAgentAttentionStopInput({ cwd: '/tmp/repo' })).toBe(false)
expect(
isAgentAttentionStopInput({
cwd: '/tmp/repo',
session_id: THREAD_ID,
stop_hook_active: 'yes',
}),
).toBe(false)
})

test('malformed correlation fields block stop without calling the owner', async () => {
let calls = 0
const output = await runAgentAttentionStop(
{ cwd: '/tmp/repo', session_id: THREAD_ID, stop_hook_active: 'yes' },
{
checkStop: async () => {
calls += 1
return { hook_action: 'allow' }
},
},
)
expect(calls).toBe(0)
expect(output).toEqual({
decision: 'block',
reason:
'Agent Attention could not correlate this Stop event to structured owner state. Repair the hook payload contract before stopping.',
})
})

test('malformed stdin blocks the executable hook', async () => {
const process = Bun.spawn(['bun', join(import.meta.dir, 'agent-attention-codex-stop.ts')], {
stdin: new Blob(['{']),
stdout: 'pipe',
stderr: 'pipe',
})
const [stdout, exitCode] = await Promise.all([
new Response(process.stdout).text(),
process.exited,
])
expect(exitCode).toBe(0)
expect(JSON.parse(stdout)).toEqual({
decision: 'block',
reason:
'Agent Attention could not correlate this Stop event to structured owner state. Repair the hook payload contract before stopping.',
})
})

test('default adapter requires python3 on PATH and reads only temporary structured owner state', async () => {
const temporary = await mkdtemp(join(tmpdir(), 'agent-attention-hook-'))
const previous = process.env.XDG_STATE_HOME
process.env.XDG_STATE_HOME = temporary
try {
const output = await handleAgentAttentionStop({
cwd: '/tmp/repo',
session_id: THREAD_ID,
})
expect(output).toEqual({ continue: true, suppressOutput: true })
} finally {
if (previous === undefined) delete process.env.XDG_STATE_HOME
else process.env.XDG_STATE_HOME = previous
await rm(temporary, { recursive: true, force: true })
}
})

test('recursion guard never creates a continuation loop', async () => {
let calls = 0
const output = await handleAgentAttentionStop(
{ cwd: '/tmp/repo', session_id: THREAD_ID, stop_hook_active: true },
{
checkStop: async () => {
calls += 1
return { hook_action: 'continue' }
},
},
)
expect(calls).toBe(0)
expect(output).toEqual({ continue: true, suppressOutput: true })
})

test('owner failures block stop with an actionable repair', async () => {
const output = await runAgentAttentionStop(
{ cwd: '/tmp/repo', session_id: THREAD_ID },
{
checkStop: async () => {
throw new Error('structured state is unreadable')
},
},
)
expect(output).toEqual({
decision: 'block',
reason:
'Agent Attention could not verify structured owner state. Repair the owner check before stopping: structured state is unreadable',
})
})

test('experiment hook fixture matches the code-owned command', async () => {
const config = JSON.parse(
await readFile(join(import.meta.dir, 'codex-hooks.fixture.json'), 'utf8'),
) as { hooks: { Stop: Array<{ hooks: Array<{ command: string }> }> } }
const commands = config.hooks.Stop.flatMap((group) =>
group.hooks.map((hook) => hook.command),
)
expect(commands).toContain(AGENT_ATTENTION_STOP_HOOK_COMMAND)
})
})
Loading