Skip to content

feat(tools): recorder hooks for skill-memory replay (4 action tools — follow-up to #925) #988

@shaun0927

Description

@shaun0927

Motivation

PR #925 ships the skill-memory replay primitives:

  • replay-artifact.ts types + JSON-Schema validator
  • recorder-buffer.ts per-CDP-target FIFO (cap 100)
  • oc_skill_record extended to accept replay_artifact
  • New oc_skill_replay tool (returns structured {ok} or {ok:false, failure} envelope)
  • Skill-memory store migration v1 → v2 (v1 records remain read-compatible)

But no action tool feeds the recorder buffer. The pipeline is open at the source: oc_skill_replay exists but it has nothing to replay unless oc_skill_record is called manually with a hand-crafted replay_artifact. The original #875 spec called for the buffer to be populated automatically by action tools.

This issue tracks the recorder hooks that close the pipeline.

Scope

Add an optional capture_artifact: boolean argument (default false) to each of these action tools:

Tool Hook point
src/tools/interact.ts After Ralph successfully resolves the target selector and the action succeeds
src/tools/fill-form.ts Per-field winning selector at the same point in each field's success path
src/tools/form-input.ts After successful input
src/tools/navigate.ts When the navigation was triggered by a discovered link/anchor (not a direct URL arg)

For each hook, push to the per-CDP-target buffer:

recorderBuffer.push(targetId, {
  winningSelector: result.selector,
  siblings: result.robustnessAlternatives.slice(0, 2),  // up to 2 sibling selectors
  step: { tool: '<toolName>', args: normalizedArgs },
});

When capture_artifact: false (default) or omitted: zero behavior change — the hook is a pure no-op. This keeps the Portability-Harness Contract P2 byte-parity invariant intact for existing automations.

Acceptance criteria

  1. Each of the 4 tools accepts capture_artifact: boolean (default false) in inputSchema.
  2. capture_artifact: true populates the per-CDP-target recorder buffer with the winning selector + ≤2 robustness siblings + the calling tool/args.
  3. capture_artifact: false (default) is a strict no-op — verified by a P2 byte-parity test: same fixture automation run with capture_artifact omitted vs. explicitly false returns byte-identical responses to the v1.11 baseline.
  4. The buffer's existing cap (100 entries per target, destructive flush on oc_skill_record) is honored.
  5. Recording a new artifact via capture_artifact: true followed by oc_skill_record produces a v2 record that oc_skill_replay can successfully consume — end-to-end test that closes the pipeline.

Post-merge verification (using openchrome)

./dist/cli/index.js serve --http 3100 --auth-token test &

# 1. Run an automation that exercises interact + fill_form with capture_artifact:true
node tests/manual/recorder-pipeline-smoke.ts --capture
# Expected: oc_skill_record produces a v2 record containing the captured artifact.

# 2. Recall + replay
node tests/manual/recorder-pipeline-smoke.ts --replay
# Expected: replay completes with ok:true, zero read_page/find calls between recall and replay.

# 3. P2 byte-parity — without capture_artifact, response shape unchanged
node tests/manual/recorder-pipeline-smoke.ts --no-capture --compare-baseline
# Expected: byte-identical to v1.11 fixture.

Out of scope

Portability-Harness Contract compliance

  • P1 (tool server identity): hook fires inline within an existing tools/call. No orchestration.
  • P2 (zero-impact when off): capture_artifact: false default → byte-identical to v1.11. Enforced by parity test.
  • P3 (anywhere-compatible MCP): no new dependencies, no outbound traffic.

References

OpenChrome 실검증 체크리스트

2026-05-14 최신 merged 버전 적용 후 재검증. OpenChrome 응답, 로컬 fixture, 빌드/테스트 산출물로 직접 증명 가능한 항목만 합격 조건으로 남겼다. 사람 리뷰, 외부 사이트 안정성, 미확인 PR 상태 같은 조건은 합격 조건에서 제외한다.

검증 대상

최신 버전/공통 런타임 검증

  • 최신 develop 소스를 적용하고 npm run build 통과를 확인했다.
  • npm run lint:tier 통과를 확인했다.
  • npm test -- --runInBand 결과 504/507 suites 통과, 3 skipped, 6429/6525 tests 통과, 96 skipped를 확인했다. 단, Jest open-handle 경고는 별도 런타임 리스크로 기록했다.
  • oc_connection_health가 connected 상태를 반환했다.
  • 로컬 fixture에서 OpenChrome navigate/read_page/interact/javascript_tool 경로로 DOM 상태 변화를 관찰했다.
  • 동일 fixture/동일 설정에서 핵심 결과가 재현 가능함을 확인했다.

이슈별 해결 증거

  • 최신 develop에 연결된 구현 PR: 1239, 1229, 1228, 1227, 1222
  • 관련 테스트/소스 증거가 최신 트리에 존재한다:
    • src/tools/_shared/replay-recorder.ts
    • src/core/skill-memory/recorder-buffer.ts
    • src/core/skill-memory/replay-artifact.ts
    • tests/tools/form-input.test.ts
    • docs/releases/v1.11.0.md
    • docs/roadmap/history/openchrome-1.11-cleanup.md
  • 체크리스트에는 OpenChrome 응답/fixture/로컬 산출물로 재현할 수 없는 합격 조건을 남기지 않았다.

실패/보류 기준

  • 체크가 하나라도 미충족이면 이슈를 닫지 않는다.
  • 실패가 최신 코드 결함으로 재현되면 실패한 OpenChrome 호출, 응답 excerpt, fixture 상태를 증거로 남기고 별도 수정 PR을 올린다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1P1 highenhancementNew feature or requesthost-integrationWires module cores into host (CDP, MCP, tools, transports, OS APIs)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions