Skip to content

cogos-harness 0.4.0: mods skeleton (5 mods, shared lib) + retire dead hooks - #29

Open
chazmaniandinkle wants to merge 1 commit into
mainfrom
feat/harness-mods-skeleton
Open

chazmaniandinkle wants to merge 1 commit into
mainfrom
feat/harness-mods-skeleton

Conversation

@chazmaniandinkle

Copy link
Copy Markdown
Contributor

Mods program, step 2: the shared skeleton the five mod builds branch from (feat/mod-<name> off this branch). Plan: cog://mem/semantic/plans/harness-mods-program §2–§4.

What lands

  • cogos-harness 0.3.0 → 0.4.0 (plugin.json + marketplace). "types": "./types/index.d.ts".
  • hooks/index.mjs: the plugin's one hooks module. It calls register(on, options) for redact → guard → context → status → receipt.
  • mods/cog-{redact,guard,context,status,receipt}.mjs: stubs that register their briefed events and pass every event through unchanged.
  • lib/:
    • cfg.mjs: ~/.cog/conf/harness-mods.json, modes off/shadow/on. A missing or malformed file means every mod is off.
    • order.mjs: the typed order, before().
    • cache.mjs: vitals read/write with age. Anything older than 2 min shows its age. Mirrored to ~/.cog/run/vitals.json.
    • ledger.mjs: hook-health rows mod/<name>/<event>, append-only.
    • kernel.mjs: fetch with X-Cogos-Grant.
    • stub.mjs
  • types/index.d.ts: the PluginState contract, one block per mod.
  • types/vendor/: Claude Code's own 2.1.292 mod types, so tsc runs in a fresh clone.
  • Shell hooks: all of them are unchanged. hooks.json carries both "hooks" and "modules".
  • README: a "Mods (0.4.0)" section with the one build/test command for the five agents.

Behaviour

Before (0.3.0) After (0.4.0)
No harness-mods.json (default) shell hooks only shell hooks + 7 mod hooks, each next(e) after one cached config read; no ledger rows, no writes (tested)
A mod set to shadow n/a that mod logs one shadow:true, would:"none" ledger row per run; the event is unchanged
tool.call order n/a redact → guard → receipt, asserted on the real chain

Engine rules found with claude plugin validate (2.1.292)

These shaped the layout, and the README documents them for the mod agents:

  1. One plugin lists one hooks module, so the mods are composed in index.mjs.
  2. One plugin may not register the same event twice without a matcher. Every mod hook carries {}.
  3. $ is followed only into functions declared in the same file, never across an import. So lib/ takes an io adapter that each mod builds with its own same-file ioOf($). The base keys are identical in all five.
  4. Hooks nest in registration order, first outermost. This was confirmed in the kit: the first mod's input rewrite is what the second mod sees.

Verification (real output, from repo root)

claude plugin validate plugins/cogos-harness   → ✔ Validation passed
  hooks: tool.call{}, prompt.submit{}, tool.call{}, prompt.context{}, session.measure{}, tool.call{}, turn.complete{}
claude plugin test plugins/cogos-harness       → 31 pass, 0 fail (7 files)
npx -y -p typescript@5 tsc -p plugins/cogos-harness/tsconfig.json --noEmit → exit 0
python3 -m pytest plugins/cogos-harness/tests/test_threads.py → 109 passed

Negative controls:

  • Swapping redact/guard in index.mjs fails order.test.ts (2 fail).
  • A typo'd mod name in before() fails tsc (TS2345).

order.test.ts has one PENDING-CONTRACT case: the fake key plus attribution line is denied, and the deny text holds the placeholder. Over the stubs it asserts only the pass-through baseline; the redact and guard PRs make it real.

Retire-now

None of the 7 RETIRE rows (#10's file, 40, 44, 54, 56, 60, 67) is in this repo. All of them are in the cog workspace's .cog/hooks/, so this PR has no retire commit.

Do not merge until reviewed.

…d lib

One function-hooks module (hooks/index.mjs) composes five mods: cog-redact,
cog-guard, cog-context, cog-status and cog-receipt. In this release each mod
loads, registers, and passes every event through unchanged. Every mod is off
unless ~/.cog/conf/harness-mods.json enables it; a missing file means all off.
hooks.json keeps every existing shell hook alongside "modules".

Shared lib/: cfg (off/shadow/on loader), order (typed redact->guard->context->
status->receipt), cache (vitals read/write with age, stale > 2 min shown),
ledger (hook-health rows, append-only), kernel (fetch with X-Cogos-Grant),
stub (the no-op body).

Layout follows engine rules measured with claude plugin validate (2.1.292):
- one hooks module per plugin;
- a matcher on any repeated event;
- $ never crosses an import, so lib/ takes an io adapter built per mod.

Tests: one per mod (off/missing/shadow), order.test.ts on the real chain
(negative-controlled: swapping redact/guard fails it), lib.test.ts. Vendored
2.1.292 types make tsc runnable.

Actor: agent
Session-ID: 20261006_155913_669258
Instance: darkstar
Harness: hermes/cog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant