Skip to content

T-0AF7-hook-editor-and-harness-gap-table

State: planning/proposed · Impact: medium · Complexity: medium

Once hook is a vault kind it needs a form: SkillFieldsForm.vue is built around a skill’s fields and a hook’s are different in shape — an event, a matcher over tool names, and then whichever fields its type carries. The same work answers a second question for every kind: which of this note’s fields does each of its targets actually honour. One table, rows the features the note uses and columns its effective targets, turns the capability matrix into something an author reads while editing rather than a document they go and find.

LocationRole today
solutions/determined/experiences/agent-pants/app/components/SkillFieldsForm.vueThe one fields form. Sections are hard-coded and fieldAppliesToKind gates each row
solutions/determined/experiences/agent-pants/app/utils/fieldSpec.ts#FIELD_SPECSThe field roster: id, key, label, and the kinds each field applies to
solutions/determined/experiences/agent-pants/app/utils/fieldSpec.ts#fieldAppliesToKindThe per-kind gate every row in the form calls
solutions/determined/experiences/agent-pants/app/components/ApPropertiesPanel.vueThe aux panel that shows a note’s resolved placement and its declared keys — the closest thing to a gap view today, and it says nothing about targets
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/notes/[...path].vueMounts the form, the body editor and the aux region
packages/rust/agent-adapt/src/tools.rs#ToolRegistryThe 11 canonical tool names, with each runtime’s spelling — the matcher builder’s vocabulary
packages/rust/agent-adapt/src/render/hooks_json.rs#render_hooks_jsonTranslates a matcher’s pipe-delimited halves per runtime
solutions/agent-pants/docs/vault/reference/harness-comparison.mdThe per-harness survey in prose; nothing in the app reads it

ApHookFieldsForm.vue renders a hook note on the shared section renderer, with an event picker whose options come from the capability matrix for the note’s effective targets, a matcher builder over the canonical tool names from tools.rs, and type-specific fields — command, url, prompt or the agent reference — shown for the selected type and hidden otherwise.

ApHarnessGapTable.vue is a view over any note, not just a hook. Rows are the features that note actually uses — the fields it sets, its event, its matcher. Columns are its effective targets. Each cell reads the matrix and says one of: honoured, translated (with what it becomes), or dropped. A translated or dropped cell offers “override for this harness”, which opens that target’s block in the edit form’s Overrides section with the key pre-filled.

The table is reachable from the preview pane for every kind, so an author checking what a harness receives can move from the rendered file to the reason a key is missing from it.

  1. Add the hook fields to FIELD_SPECS with kinds: ['hook'] and the section and order keys the shared renderer reads, so the hook form is data-driven like the rest.
  2. Build ApHookFieldsForm.vue on the section renderer from T-GHE3-edit-form-in-center-pane: event picker, matcher builder, type-specific field group.
  3. Expose the canonical tool names to the client. Decision inside this step: read them from the capability matrix rather than adding a second op over tools.rs, so the matcher builder and the gap table share one source.
  4. Build ApHarnessGapTable.vue: derive the used-features row set from the note’s own fields, take the columns from the effective targets, and render each cell from the matrix with its verdict.
  5. Wire the cell action: a dropped or translated cell opens the Overrides section for that target with the harness’s own key name pre-filled, from T-IIZO-per-target-overrides.
  6. Mount the table as a view reachable from the preview pane for every kind, and cover the hook form and the table with component tests beside the existing ApComponentTree.test.ts.
AreaNote
solutions/determined/experiences/agent-pants/app/components/ApHookFieldsForm.vueThe hook edit form on the shared section renderer
solutions/determined/experiences/agent-pants/app/components/ApHarnessGapTable.vueUsed features by effective target, cells from the matrix
solutions/determined/experiences/agent-pants/app/components/ApHarnessGapTable.test.tsCell verdicts and the override handoff
solutions/determined/experiences/agent-pants/app/utils/fieldSpec.tsHook field entries with their section and order
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/notes/[...path].vueMount the hook form for a hook note; reach the gap table from the secondary pane
solutions/determined/experiences/agent-pants/stories/screens/A story for the hook form and one for the gap table
solutions/determined/experiences/agent-pants/docs/authoring.mdHow to author a hook and how to read the gap table
  • AC-1: Opening a note whose kind is hook renders ApHookFieldsForm.vue, not SkillFieldsForm.vue.
  • AC-2: The event picker offers only events the note’s effective targets carry, and says which target drops an event that is selected.
  • AC-3: The matcher builder offers the canonical tool names from tools.rs and writes them pipe-delimited.
  • AC-4: Changing type shows that type’s own fields and hides the others; the note never carries two of command, url and prompt at once.
  • AC-5: The gap table renders for a skill, a command, an agent and a hook, with one column per effective target.
  • AC-6: A cell whose verdict is dropped or translated offers “override for this harness”, and taking it opens that target’s Overrides block with the harness’s key name pre-filled.
  • AC-7: A field an override already supplies for a target renders as honoured, not dropped.
  • AC-8: The gap table component test asserts one honoured, one translated and one dropped cell against a fixed matrix fixture.

Member of milestone M-BMFD, from the user’s planning request of 2026-09-07: the editor should warn where a harness does not honour a field, and hooks should be authored in the app. The divergence the table renders is surveyed in solutions/agent-pants/docs/vault/reference/harness-comparison.md, and the assessment solutions/agent-pants/docs/vault/design/workflow-and-ux-assessment.md records that nothing in the app tells an author what a target drops. Hook and permission vocabularies come from Claude Code hooks, Gemini CLI and OpenCode, fetched 2026-09-07.

T-H56N-hooks-as-vault-entities, T-GHE3-edit-form-in-center-pane, T-IIZO-per-target-overrides


← Back to Tasks