[PR #4954] [MERGED] feat(analysis-view): project an environment manifest from web network captures #6690

Closed
opened 2026-11-01 21:42:20 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4954
Author: @earakely-scale
Created: 10/18/2026
Status: ✅ Merged
Merged: 10/18/2026
Merged by: @morluto

Base: main ← Head: feat/environment-manifest-view


📝 Commits (10+)

  • 61d3536 feat(analysis-view): project an environment manifest from web network captures
  • 2d95597 test(web-network): check the manifest refusal text like the api-surface refusal
  • 6cb38b5 docs(specs): record the hosted web-network lane run for the manifest view
  • b6d18d2 docs(specs): reconcile the manifest view verification scope note with the hosted run
  • 44203ec fix(analysis-view): bound body, route and name work in the environment manifest
  • bfe5a36 fix(analysis-view): keep manifest folding, naming and media-type reads linear
  • 71d7513 fix(analysis-view): charge the manifest group key before building it
  • 2679323 fix(analysis-view): accept a +json suffix only on application media types
  • 692453b chore: merge main into environment manifest review
  • f73af11 fix(analysis-view): require the capture parent's exact subject for a manifest

📊 Changes

33 files changed (+4096 additions, -361 deletions)

View changed files

📝 .agents/skills/reverse-engineer-anything/references/evidence-workflows.md (+8 -0)
📝 docs/mcp-contracts.md (+8 -0)
➕ docs/specs/agent-environments/manifest-view/plan.md (+28 -0)
➕ docs/specs/agent-environments/manifest-view/spec.md (+63 -0)
➕ docs/specs/agent-environments/manifest-view/tasks.md (+12 -0)
➕ docs/specs/agent-environments/manifest-view/verification.md (+186 -0)
📝 docs/web-network-captures.md (+88 -0)
📝 scripts/verify-web-network-captures.mjs (+26 -0)
📝 src/application/analysisView/AnalysisViewService.test.ts (+116 -31)
📝 src/application/analysisView/AnalysisViewService.ts (+17 -4)
📝 src/contracts/analysisDetail.test.ts (+6 -5)
➕ src/contracts/analysisViewEnvironmentManifestExample.ts (+132 -0)
📝 src/contracts/analysisViewToolContracts.ts (+6 -1)
➕ src/domain/analysisView/EnvironmentManifestAccumulator.test.ts (+122 -0)
➕ src/domain/analysisView/EnvironmentManifestAccumulator.ts (+543 -0)
📝 src/domain/analysisView/WebNetworkApiSurfaceAccumulator.ts (+44 -241)
➕ src/domain/analysisView/WebNetworkProjectionAccumulator.ts (+158 -0)
📝 src/domain/analysisView/analysisView.ts (+27 -0)
📝 src/domain/analysisView/binaryLayoutView.ts (+4 -1)
➕ src/domain/analysisView/environmentManifestRules.test.ts (+45 -0)

...and 13 more files

📄 Description

Summary

Adds the environment-manifest view kind to inspect_analysis_view for retained HAR Evidence: the primary origin's recorded request lines become a deterministic, replayable tool surface (names, path templates, parameters, observed query names, value-free body shapes, record pointers), with excluded groups, three fixed unknowns and the shared projection budget. Literal fold-in under the opt-in rules never touches format-rule parameters.

Refs morluto/rea#4933 (design discussion; scope decision requested there).

Opened as a draft until the scope decision in the design discussion lands and the human owner has reviewed the final diff; the body is complete so the review can start now.

Problem and expected behavior

An agent environment needs a manifest of what a captured application exposes, without serving or replaying anything yet. Existing api-surface groups are not named tools and cannot carry opt-in identifier rules. Expected: view: {kind: "environment-manifest", template_rules?, include_query_parameter_names?} on inspect_web_network_capture HAR Evidence returns tools whose templates equal the api-surface grouping without rules and apply after-uid-literal, opaque-token, sibling-variance only when listed; a parameter produced by one of the four format rules must keep its exact-format meaning (a literal sibling such as /api/teams/search or /api/teams/mine stays its own tool instead of becoming an observed value of /api/teams/{numeric}).

Change and scope

New: environmentManifestRules.ts (opt-in rules, re-bucketing, sibling merge with fold-in restricted to opt-in parameters, naming), EnvironmentManifestAccumulator.ts, environmentManifestView.ts, WebNetworkProjectionAccumulator.ts and webNetworkRouteTemplates.ts (helpers lifted from the api-surface accumulator), a generated contract example, domain tests, and docs/specs/agent-environments/manifest-view/. Pre-existing files, one line each: WebNetworkApiSurfaceAccumulator.ts - behaviour-preserving refactor onto the shared route/media-type/budget helpers so both views share one interpretation and stay under jscpd; webNetworkApiSurfaceView.ts - parent guards replaced by shared admitHarCaptureParent, rule enum from ROUTE_RULES; analysisView.ts - registers request/result schemas, UnsignedAnalysisView member and projector dispatch for the new kind; AnalysisViewService.ts - builds the manifest accumulator for the kind and extends the inferred-confidence rule to it; binaryLayoutView.ts / javascriptApplicationView.ts - type-level Exclude widened so the kind never reaches those projectors; webNetworkCaptureView.ts - unsupported-view message names the kind; analysisViewToolContracts.ts - tool description and example; analysisDetail.test.ts - asserts the kind appears only in inspect_analysis_view's output schema; AnalysisViewService.test.ts, analysisViewCli.test.ts, analysisViewMcp.test.ts, qlogCapture.test.ts - mirror api-surface coverage for the kind (qlog parent refused by both); tests/fixtures/historicalHar.ts + analysisView.ts - Grafana-shaped 28-entry HAR as a TS builder and its capture fixture; scripts/verify-web-network-captures.mjs - real-capture verifier also projects the manifest and asserts refusal/pointer-only records; docs/web-network-captures.md - new 'Environment manifest' section; docs/mcp-contracts.md and the skill evidence-workflows.md - pointer paragraphs. No file outside the slice is modified; CHANGELOG.md, server.json, README.md, docs/readme/* and package.json dependencies are untouched.

Follow the contribution scope.

Contract and boundary impact

  • Semantic owner and earliest changed stage: Domain analysis-view projection (src/domain/analysisView/); the earliest changed stage is the view request schema in analysisView.ts, dispatched kind-first like api-surface. AnalysisViewService.ts only extends the inferred-confidence rule to the new kind.
  • Contribution scope fit and linked maintainer decision: Analysis capability over retained captured data, within existing boundaries: no side effects, no network, no execution. Part 1 of the decision requested in morluto/rea#4933.
  • CLI and MCP/tool-catalog contract: No new tool or command. inspect_analysis_view accepts view.kind = "environment-manifest" with template_rules? (each rule at most once) and include_query_parameter_names?; its description and examples grow by one example, so the catalog digest changes at build and running servers report the usual restart-required status after upgrade.
  • Provider, bridge, target-format, or platform compatibility: HAR parents only; native mitmproxy, SAZ and qlog parents return the same typed unsupported error as api-surface. No provider, bridge or platform dependency.
  • Evidence, artifact, provenance, or reconstruction contract: Wrapped as rea.analysis-view Evidence linked to the parent; confidence inferred whenever any tool or excluded group is templated, derived otherwise; authority stays the parent's historical-reference; view_digest present. Records are pointers only and no header, cookie, query or body value is copied into the result.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): Not applicable: no target is selected, launched or contacted; the view performs no network activity and replays nothing.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact (CI generates and validates ignored catalogs and skills/; edit authored instructions in .agents/skills/reverse-engineer-anything/ and never commit build outputs): No tracked generated file changes (npm run docs:check passes with an empty diff); docs/public/product-catalog.json and skills/ regenerate in CI. .agents/skills/reverse-engineer-anything/references/evidence-workflows.md gains a pointer paragraph. No package or installation change.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Domain test: GET /api/teams/1, /api/teams/2, /api/teams/search, /api/teams/mine with all rules -> tools get_teams_mine, get_teams_search, get_teams_by_id (/api/teams/{numeric}, observed ["1","2"]), templated_groups 1.
  • Built CLI on the 28-record Grafana-shaped fixture: no rules -> 22 tools + 3 primary-origin exclusions == 25 api-surface groups, every path_template == api_surface_template; all rules -> 19 tools, templated_groups 13, /api/dashboards/uid/{uid}, /api/folders/{uid} (fg1jo91e57e2ob + general), /api/plugins/{plugin_id}/settings, /api/datasources/uid/{uid}/health; byte-identical across repeated runs; records pointer-only; no recorded value leaked.
  • Built CLI on the fixture + /api/teams/search + /api/teams/mine: /api/teams/{numeric} keeps observed ["1"]; both literals are their own tools.
  • Byte-exact reproduction of the published contract example through the real HAR decoder and view service (mcp-boundary/cli-boundary tests).

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.
Representative output
{"evidence_id":"ev_6553a8e59258bd72034b3e2096dad15c127dd91920f9577aac63e9ebe8fc7b8f","confidence":"inferred","authority":"historical-reference","normalized_result":{"kind":"environment-manifest","origin":"http://grafana.example","name":"grafana-example","view":{"kind":"environment-manifest","template_rules":["after-uid-literal","opaque-token","sibling-variance"],"include_query_parameter_names":true},"tools":[{"name":"get_folders_by_uid","method":"GET","path_template":"/api/folders/{uid}","api_surface_template":"/api/folders/fg1jo91e57e2ob","params":[{"index":2,"name":"uid","rule":"opaque-token","basis":"inferred","observed_values":["fg1jo91e57e2ob","general"]}],"query_parameter_names":["accesscontrol"],"body_shape":null,"statuses":[200],"content_types":["application/json"],"record_ordinals":[12,13]},{"name":"get_plugins_settings_by_plugin_id","method":"GET","path_template":"/api/plugins/{plugin_id}/settings","api_surface_template":"/api/plugins/grafana-testdata-datasource/settings","params":[{"index":2,"name":"plugin_id","rule":"sibling-variance","basis":"inferred","observed_values":["grafana-lokiexplore-app","grafana-pyroscope-app","grafana-testdata-datasource"]}],"query_parameter_names":[],"body_shape":null,"statuses":[200],"content_types":["application/json"],"record_ordinals":[15,16,17]}],"unknowns":[{"kind":"authorization-model","statement":"Authorization headers and cookies are structurally excluded from captures; the manifest states no authorization model."},{"kind":"response-semantics","statement":"Recorded statuses and bodies are retained only as pointers to parent records; the manifest states no response semantics."},{"kind":"state-transition","statement":"Recorded exchanges are independent observations; the manifest states no ordering, side effects or state transitions between tools."}],"templated_groups":13,"tool_count":19}}

Validation performed

  • npm run check:fast - pass
  • npm run format; npm run format:check - pass (4028 files)
  • npx knip - pass
  • npm run check:ci:tasks - pass (jscpd 3.35% < 3.5%, lint:built 0 errors)
  • npm run docs:check - pass, no generated file changed
  • vitest domain+services (full) - 312 files, 5412 passed, 3 skipped
  • vitest mcp-boundary (full) - 153 files passed, 2 skipped; 901 tests passed, 7 skipped
  • vitest acceptance (full) - 123 files passed, 1 skipped; 608 tests passed, 13 skipped
  • vitest cli-boundary (full) - 659 passed, 2 skipped, 8 failed in closedStdout/commandFinalizationCancellation/javascriptApplicationJsonOutput; 7 pass in isolation, the closedStdout exit-status case reproduces on a clean 18aa9af2 export (pre-existing, unrelated)
  • Details and /usr/bin/time -l figures in docs/specs/agent-environments/manifest-view/verification.md (Verified base 18aa9af2b2)
  • Automated review round 1 (Codex and Greptile, seven findings at b6d18d23) addressed in 44203ecd: top-level-only body shapes, every route part admitted before allocation, a 32-segment bound on sibling-variance stated as a limitation, stop words kept literal after a uid literal, per-base collision suffixes, templated exclusions preserved on a row collision; each thread has a reply.
  • Later automated rounds (Codex): bfe5a364 keeps sibling folding, name suffixes and request media-type reads linear; 71d7513c charges the group key before building it; 2679323e accepts a +json suffix only on application media types; f73af11c requires the capture parent's exact subject at admission; dd87f54e merges only identifier-like siblings under sibling-variance. Each has a regression test and a reply in its thread.
  • Maintainer-side work on this branch: a collaborator merged main into the branch (692453bf), replaced the suffix counter with one keyed by the truncated prefix and suffix width with its own tests (d6cb57e3), re-applied the subject check on top (99be275e) and posted independent verification on every finding thread, including a run over the five published showcase corpora. The fork CI run on 99be275e is green (https://github.com/earakely-scale/rea/actions/runs/39146579873); dd87f54e is appended on top of it.
  • Hosted lane run on the fork: https://github.com/earakely-scale/rea/actions/runs/39146579873

Compatibility, safety, and release

  • Additive: new discriminated-union member in analysisViewRequestSchema / analysisViewResultSchema; existing view kinds and their outputs are unchanged.
  • api-surface accumulator refactored onto shared helpers without behavioural change; its contract example and tests are unchanged.
  • The unsupported-view error message for historical captures now also names environment-manifest (message text only; codes unchanged).
  • No dependency, CHANGELOG, server.json, README or docs/readme changes; serving/exporting an environment from the manifest is deferred to later increments of the same issue.

Author readiness

Human owner: @earakely-scale

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4954 **Author:** [@earakely-scale](https://github.com/earakely-scale) **Created:** 10/18/2026 **Status:** ✅ Merged **Merged:** 10/18/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `feat/environment-manifest-view` --- ### 📝 Commits (10+) - [`61d3536`](https://github.com/morluto/rea/commit/61d35369c560caf595dac38faeec96d5df4f68e6) feat(analysis-view): project an environment manifest from web network captures - [`2d95597`](https://github.com/morluto/rea/commit/2d95597f648e3c1d9ee8cf0831ab55d75fa0d750) test(web-network): check the manifest refusal text like the api-surface refusal - [`6cb38b5`](https://github.com/morluto/rea/commit/6cb38b5cbac4b8f20e9c7476c9de747c992c5489) docs(specs): record the hosted web-network lane run for the manifest view - [`b6d18d2`](https://github.com/morluto/rea/commit/b6d18d2392489e139fdc8816e645bb6a8275cc10) docs(specs): reconcile the manifest view verification scope note with the hosted run - [`44203ec`](https://github.com/morluto/rea/commit/44203ecd73d93ff1076f4bcd471824565f58abaf) fix(analysis-view): bound body, route and name work in the environment manifest - [`bfe5a36`](https://github.com/morluto/rea/commit/bfe5a36422eb5e7e04bcf8459e98b8a6ab3b87ef) fix(analysis-view): keep manifest folding, naming and media-type reads linear - [`71d7513`](https://github.com/morluto/rea/commit/71d7513c478c722fbb2026d7ff7d9a5025dbd190) fix(analysis-view): charge the manifest group key before building it - [`2679323`](https://github.com/morluto/rea/commit/2679323e78b6c5577bbb773010b0192c8e648b71) fix(analysis-view): accept a +json suffix only on application media types - [`692453b`](https://github.com/morluto/rea/commit/692453bf5593df3e0bba689db448b5152fd5a598) chore: merge main into environment manifest review - [`f73af11`](https://github.com/morluto/rea/commit/f73af11cc3246bac1dd07de777af7b6fced7d326) fix(analysis-view): require the capture parent's exact subject for a manifest ### 📊 Changes **33 files changed** (+4096 additions, -361 deletions) <details> <summary>View changed files</summary> 📝 `.agents/skills/reverse-engineer-anything/references/evidence-workflows.md` (+8 -0) 📝 `docs/mcp-contracts.md` (+8 -0) ➕ `docs/specs/agent-environments/manifest-view/plan.md` (+28 -0) ➕ `docs/specs/agent-environments/manifest-view/spec.md` (+63 -0) ➕ `docs/specs/agent-environments/manifest-view/tasks.md` (+12 -0) ➕ `docs/specs/agent-environments/manifest-view/verification.md` (+186 -0) 📝 `docs/web-network-captures.md` (+88 -0) 📝 `scripts/verify-web-network-captures.mjs` (+26 -0) 📝 `src/application/analysisView/AnalysisViewService.test.ts` (+116 -31) 📝 `src/application/analysisView/AnalysisViewService.ts` (+17 -4) 📝 `src/contracts/analysisDetail.test.ts` (+6 -5) ➕ `src/contracts/analysisViewEnvironmentManifestExample.ts` (+132 -0) 📝 `src/contracts/analysisViewToolContracts.ts` (+6 -1) ➕ `src/domain/analysisView/EnvironmentManifestAccumulator.test.ts` (+122 -0) ➕ `src/domain/analysisView/EnvironmentManifestAccumulator.ts` (+543 -0) 📝 `src/domain/analysisView/WebNetworkApiSurfaceAccumulator.ts` (+44 -241) ➕ `src/domain/analysisView/WebNetworkProjectionAccumulator.ts` (+158 -0) 📝 `src/domain/analysisView/analysisView.ts` (+27 -0) 📝 `src/domain/analysisView/binaryLayoutView.ts` (+4 -1) ➕ `src/domain/analysisView/environmentManifestRules.test.ts` (+45 -0) _...and 13 more files_ </details> ### 📄 Description ## Summary Adds the `environment-manifest` view kind to `inspect_analysis_view` for retained HAR Evidence: the primary origin's recorded request lines become a deterministic, replayable tool surface (names, path templates, parameters, observed query names, value-free body shapes, record pointers), with excluded groups, three fixed unknowns and the shared projection budget. Literal fold-in under the opt-in rules never touches format-rule parameters. Refs morluto/rea#4933 (design discussion; scope decision requested there). Opened as a draft until the scope decision in the design discussion lands and the human owner has reviewed the final diff; the body is complete so the review can start now. ## Problem and expected behavior An agent environment needs a manifest of what a captured application exposes, without serving or replaying anything yet. Existing api-surface groups are not named tools and cannot carry opt-in identifier rules. Expected: `view: {kind: "environment-manifest", template_rules?, include_query_parameter_names?}` on `inspect_web_network_capture` HAR Evidence returns tools whose templates equal the api-surface grouping without rules and apply `after-uid-literal`, `opaque-token`, `sibling-variance` only when listed; a parameter produced by one of the four format rules must keep its exact-format meaning (a literal sibling such as `/api/teams/search` or `/api/teams/mine` stays its own tool instead of becoming an observed value of `/api/teams/{numeric}`). ## Change and scope New: environmentManifestRules.ts (opt-in rules, re-bucketing, sibling merge with fold-in restricted to opt-in parameters, naming), EnvironmentManifestAccumulator.ts, environmentManifestView.ts, WebNetworkProjectionAccumulator.ts and webNetworkRouteTemplates.ts (helpers lifted from the api-surface accumulator), a generated contract example, domain tests, and docs/specs/agent-environments/manifest-view/. Pre-existing files, one line each: WebNetworkApiSurfaceAccumulator.ts - behaviour-preserving refactor onto the shared route/media-type/budget helpers so both views share one interpretation and stay under jscpd; webNetworkApiSurfaceView.ts - parent guards replaced by shared admitHarCaptureParent, rule enum from ROUTE_RULES; analysisView.ts - registers request/result schemas, UnsignedAnalysisView member and projector dispatch for the new kind; AnalysisViewService.ts - builds the manifest accumulator for the kind and extends the inferred-confidence rule to it; binaryLayoutView.ts / javascriptApplicationView.ts - type-level Exclude widened so the kind never reaches those projectors; webNetworkCaptureView.ts - unsupported-view message names the kind; analysisViewToolContracts.ts - tool description and example; analysisDetail.test.ts - asserts the kind appears only in inspect_analysis_view's output schema; AnalysisViewService.test.ts, analysisViewCli.test.ts, analysisViewMcp.test.ts, qlogCapture.test.ts - mirror api-surface coverage for the kind (qlog parent refused by both); tests/fixtures/historicalHar.ts + analysisView.ts - Grafana-shaped 28-entry HAR as a TS builder and its capture fixture; scripts/verify-web-network-captures.mjs - real-capture verifier also projects the manifest and asserts refusal/pointer-only records; docs/web-network-captures.md - new 'Environment manifest' section; docs/mcp-contracts.md and the skill evidence-workflows.md - pointer paragraphs. No file outside the slice is modified; CHANGELOG.md, server.json, README.md, docs/readme/* and package.json dependencies are untouched. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). ## Contract and boundary impact - Semantic owner and earliest changed stage: Domain analysis-view projection (`src/domain/analysisView/`); the earliest changed stage is the view request schema in `analysisView.ts`, dispatched kind-first like api-surface. `AnalysisViewService.ts` only extends the inferred-confidence rule to the new kind. - Contribution scope fit and linked maintainer decision: Analysis capability over retained captured data, within existing boundaries: no side effects, no network, no execution. Part 1 of the decision requested in morluto/rea#4933. - CLI and MCP/tool-catalog contract: No new tool or command. `inspect_analysis_view` accepts `view.kind = "environment-manifest"` with `template_rules?` (each rule at most once) and `include_query_parameter_names?`; its description and examples grow by one example, so the catalog digest changes at build and running servers report the usual restart-required status after upgrade. - Provider, bridge, target-format, or platform compatibility: HAR parents only; native mitmproxy, SAZ and qlog parents return the same typed unsupported error as api-surface. No provider, bridge or platform dependency. - Evidence, artifact, provenance, or reconstruction contract: Wrapped as `rea.analysis-view` Evidence linked to the parent; confidence `inferred` whenever any tool or excluded group is templated, `derived` otherwise; authority stays the parent's `historical-reference`; `view_digest` present. Records are pointers only and no header, cookie, query or body value is copied into the result. - Target selection, authority, upstream behavior, and cleanup details (if applicable): Not applicable: no target is selected, launched or contacted; the view performs no network activity and replays nothing. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs): No tracked generated file changes (`npm run docs:check` passes with an empty diff); `docs/public/product-catalog.json` and `skills/` regenerate in CI. `.agents/skills/reverse-engineer-anything/references/evidence-workflows.md` gains a pointer paragraph. No package or installation change. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Domain test: GET /api/teams/1, /api/teams/2, /api/teams/search, /api/teams/mine with all rules -> tools get_teams_mine, get_teams_search, get_teams_by_id (/api/teams/{numeric}, observed ["1","2"]), templated_groups 1. - Built CLI on the 28-record Grafana-shaped fixture: no rules -> 22 tools + 3 primary-origin exclusions == 25 api-surface groups, every path_template == api_surface_template; all rules -> 19 tools, templated_groups 13, /api/dashboards/uid/{uid}, /api/folders/{uid} (fg1jo91e57e2ob + general), /api/plugins/{plugin_id}/settings, /api/datasources/uid/{uid}/health; byte-identical across repeated runs; records pointer-only; no recorded value leaked. - Built CLI on the fixture + /api/teams/search + /api/teams/mine: /api/teams/{numeric} keeps observed ["1"]; both literals are their own tools. - Byte-exact reproduction of the published contract example through the real HAR decoder and view service (mcp-boundary/cli-boundary tests). For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. <details><summary>Representative output</summary> ``` {"evidence_id":"ev_6553a8e59258bd72034b3e2096dad15c127dd91920f9577aac63e9ebe8fc7b8f","confidence":"inferred","authority":"historical-reference","normalized_result":{"kind":"environment-manifest","origin":"http://grafana.example","name":"grafana-example","view":{"kind":"environment-manifest","template_rules":["after-uid-literal","opaque-token","sibling-variance"],"include_query_parameter_names":true},"tools":[{"name":"get_folders_by_uid","method":"GET","path_template":"/api/folders/{uid}","api_surface_template":"/api/folders/fg1jo91e57e2ob","params":[{"index":2,"name":"uid","rule":"opaque-token","basis":"inferred","observed_values":["fg1jo91e57e2ob","general"]}],"query_parameter_names":["accesscontrol"],"body_shape":null,"statuses":[200],"content_types":["application/json"],"record_ordinals":[12,13]},{"name":"get_plugins_settings_by_plugin_id","method":"GET","path_template":"/api/plugins/{plugin_id}/settings","api_surface_template":"/api/plugins/grafana-testdata-datasource/settings","params":[{"index":2,"name":"plugin_id","rule":"sibling-variance","basis":"inferred","observed_values":["grafana-lokiexplore-app","grafana-pyroscope-app","grafana-testdata-datasource"]}],"query_parameter_names":[],"body_shape":null,"statuses":[200],"content_types":["application/json"],"record_ordinals":[15,16,17]}],"unknowns":[{"kind":"authorization-model","statement":"Authorization headers and cookies are structurally excluded from captures; the manifest states no authorization model."},{"kind":"response-semantics","statement":"Recorded statuses and bodies are retained only as pointers to parent records; the manifest states no response semantics."},{"kind":"state-transition","statement":"Recorded exchanges are independent observations; the manifest states no ordering, side effects or state transitions between tools."}],"templated_groups":13,"tool_count":19}} ``` </details> ## Validation performed - npm run check:fast - pass - npm run format; npm run format:check - pass (4028 files) - npx knip - pass - npm run check:ci:tasks - pass (jscpd 3.35% < 3.5%, lint:built 0 errors) - npm run docs:check - pass, no generated file changed - vitest domain+services (full) - 312 files, 5412 passed, 3 skipped - vitest mcp-boundary (full) - 153 files passed, 2 skipped; 901 tests passed, 7 skipped - vitest acceptance (full) - 123 files passed, 1 skipped; 608 tests passed, 13 skipped - vitest cli-boundary (full) - 659 passed, 2 skipped, 8 failed in closedStdout/commandFinalizationCancellation/javascriptApplicationJsonOutput; 7 pass in isolation, the closedStdout exit-status case reproduces on a clean 18aa9af2 export (pre-existing, unrelated) - Details and /usr/bin/time -l figures in docs/specs/agent-environments/manifest-view/verification.md (Verified base 18aa9af2b2c26fd114113dd39528a91224801840) - Automated review round 1 (Codex and Greptile, seven findings at b6d18d23) addressed in 44203ecd: top-level-only body shapes, every route part admitted before allocation, a 32-segment bound on sibling-variance stated as a limitation, stop words kept literal after a uid literal, per-base collision suffixes, templated exclusions preserved on a row collision; each thread has a reply. - Later automated rounds (Codex): bfe5a364 keeps sibling folding, name suffixes and request media-type reads linear; 71d7513c charges the group key before building it; 2679323e accepts a `+json` suffix only on application media types; f73af11c requires the capture parent's exact subject at admission; dd87f54e merges only identifier-like siblings under sibling-variance. Each has a regression test and a reply in its thread. - Maintainer-side work on this branch: a collaborator merged main into the branch (692453bf), replaced the suffix counter with one keyed by the truncated prefix and suffix width with its own tests (d6cb57e3), re-applied the subject check on top (99be275e) and posted independent verification on every finding thread, including a run over the five published showcase corpora. The fork CI run on 99be275e is green (https://github.com/earakely-scale/rea/actions/runs/39146579873); dd87f54e is appended on top of it. - Hosted lane run on the fork: https://github.com/earakely-scale/rea/actions/runs/39146579873 ## Compatibility, safety, and release - Additive: new discriminated-union member in `analysisViewRequestSchema` / `analysisViewResultSchema`; existing view kinds and their outputs are unchanged. - api-surface accumulator refactored onto shared helpers without behavioural change; its contract example and tests are unchanged. - The unsupported-view error message for historical captures now also names `environment-manifest` (message text only; codes unchanged). - No dependency, CHANGELOG, server.json, README or docs/readme changes; serving/exporting an environment from the manifest is deferred to later increments of the same issue. ## Author readiness Human owner: @earakely-scale - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:42:20 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#6690
No description provided.