Skip to content

feat(ai): namespace per-app env vars across exporters and agent#1417

Merged
tangcent merged 1 commit into
masterfrom
feat/per-app-env-namespace
Jul 12, 2026
Merged

feat(ai): namespace per-app env vars across exporters and agent#1417
tangcent merged 1 commit into
masterfrom
feat/per-app-env-namespace

Conversation

@tangcent

@tangcent tangcent commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the Per-Application Environment-Variable Namespace so the rule-authoring agent namespaces every per-app env var, and adds the one runtime enabler that makes those namespaced variables actually resolve in Postman/Hoppscotch.

The previous workflow-pattern agent (b39ad26) assumed a single application per workspace. In a multi-module workspace (order-service + payment-service), every app exported the same bare env-var names, so:

  • Two apps both wrote Authorization → the second export overwrote the first's token.
  • Every collection pointed at {{host}} → all apps shared one host.
  • Login params (username/password) collided across apps.

Changes

Runtime enabler (Phase 1–2)

  • PlaceholderSyntaxConverter — pure object that rewrites unresolved ${x} header placeholders into Postman {{x}} / Hoppscotch <<x>> syntax. Resolved vars and ${1} regex-capture refs are left untouched; placeholder-free values short-circuit byte-for-byte.
  • Wired into PostmanFormatter.toHttpItem and HoppscotchFormatter.buildHeaders via ConfigReader.getFirst as the resolvability oracle.

Agent perception (Phase 3)

  • Ambient.moduleNames + Ambient.frameworkHints — cached per capture() in a single PSI scan, rendered as modules: / frameworks active: hints in the system prompt. Privacy-preserving: module/framework labels only, no env-var material.
  • get_module_dependency_graph — one new read-only PERCEPTION tool returning the workspace module adjacency graph (with a 24-node summary cap). Lets the agent cluster API-bearing modules into app groups via connected components instead of over/under-splitting layered apps.

Knowledge base + preamble (Phase 4)

  • New "Multi-Application Namespace" section in rule-guide.md (both the src/main/resources and skills/.../docs copies) covering namespace-key resolution order, per-app env-var naming convention, multi-app bundle-split rule, and a worked two-app example.
  • Condensed "Multi-app namespacing" subsection in agent-preamble.md (token-budget ceiling raised).
  • Mirrored guidance in the external skills/easy-yapi-assistant/SKILL.md.

Design decisions (NFRs)

  • NFR-1: zero new RuleKeys — namespacing uses only existing keys' values.
  • NFR-2: no new pm.* / session.* bindings; the only runtime change is formatter-level ${}{{}}.
  • NFR-3: single-app placeholder-free exports are byte-identical (golden parity tests for both channels).
  • NFR-5: no env-var keys/values enter the transcript — verified by privacy assertions in AmbientPerceptionTest and GetModuleDependencyGraphToolTest.
  • NFR-6: exactly one new tool, get_module_dependency_graph, PERCEPTION kind, no args.

Known limitation

Param/body placeholder conversion (Req 5.5) is deferred per design Decision 3 — only header values convert in v1. This is recorded as a known limitation in the rule-guide so the agent does not promise body-level namespacing.

Test plan

  • PlaceholderSyntaxConverterTest — pure-utility cases (resolved/unresolved, ${1}, UTF-8, JSON-escaped, fast path)
  • PostmanHeaderVarConversionTest / HoppHeaderVarConversionTest — formatter wiring + NFR-3 byte-parity goldens
  • AmbientPerceptionTestmoduleNames + frameworkHints capture + privacy assertions
  • SystemPromptBuilderTest — ambient rendering + preamble namespacing mentions + raised token ceiling
  • GetModuleDependencyGraphToolTest — adjacency, library/SDK exclusion, 24-node cap, failure handling, privacy, tool kind
  • RuleGuideContentTest — section + convention assertions in both rule-guide copies

All 7 spec-related test classes pass locally (./gradlew test --tests ...).

The rule-authoring agent assumed a single application per workspace,
proposing the same env-var names (`Authorization`, `{{host}}`,
`username`/`password`) across every module. In a multi-app workspace
(order-service + payment-service) this caused cross-app token/host/
credential collisions in the exported Postman/Hoppscotch environments.

Solution:
- Add `PlaceholderSyntaxConverter` to rewrite unresolved `${x}` header
  placeholders into Postman `{{x}}` / Hoppscotch `<<x>>` syntax at
  export time, leaving config-resolved vars and `${1}` regex captures
  untouched. Wired into `PostmanFormatter` and `HoppscotchFormatter`.
- Extend `Ambient` with `moduleNames` + `frameworkHints` (cached per
  capture, single PSI scan) and render them in the system prompt so the
  agent detects multi-app workspaces and active frameworks from turn one.
- Add one read-only `get_module_dependency_graph` perception tool so the
  agent can cluster API-bearing modules into app groups via connected
  components instead of over/under-splitting.
- Add "Multi-Application Namespace" guidance to the rule-guide (both
  copies), the agent preamble, and the external skill so the built-in
  and external agents namespace env vars and split bundles consistently.

Impact:
- No new `RuleKeys`, no new `pm.*`/`session.*` bindings; single-app
  exports without placeholders are byte-identical (golden parity).
- Param/body placeholder conversion is deferred (noted as a known
  limitation in the rule-guide); only header values convert in v1.

Spec: .spec/per-app-env-namespace
@github-actions github-actions Bot added the type: new feature Add New Feature label Jul 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📦 Plugin has been packaged for this PR. You can download easy-yapi-3.2.0.252.0.zip from the GitHub Actions workflow run by clicking on the "Artifacts" dropdown.

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.04110% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.461%. Comparing base (187a310) to head (11c1a79).

Files with missing lines Patch % Lines
...om/itangcent/easyapi/ai/agent/AmbientPerception.kt 84.906% 1 Missing and 7 partials ⚠️
...t/easyapi/ai/tools/GetModuleDependencyGraphTool.kt 89.231% 4 Missing and 3 partials ⚠️
...syapi/exporter/channel/postman/PostmanFormatter.kt 75.000% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##            master     #1417       +/-   ##
=============================================
+ Coverage   64.328%   64.461%   +0.133%     
=============================================
  Files          403       405        +2     
  Lines        22665     22806      +141     
  Branches      5607      5643       +36     
=============================================
+ Hits         14580     14701      +121     
- Misses        6011      6017        +6     
- Partials      2074      2088       +14     
Flag Coverage Δ
unittests 64.461% <89.041%> (+0.133%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...tlin/com/itangcent/easyapi/ai/agent/AgentMemory.kt 100.000% <100.000%> (ø)
.../itangcent/easyapi/ai/agent/SystemPromptBuilder.kt 80.000% <100.000%> (+5.000%) ⬆️
...kotlin/com/itangcent/easyapi/ai/tools/RuleTools.kt 100.000% <100.000%> (ø)
...api/exporter/channel/PlaceholderSyntaxConverter.kt 100.000% <100.000%> (ø)
...exporter/channel/hoppscotch/HoppscotchFormatter.kt 42.763% <100.000%> (+1.152%) ⬆️
...syapi/exporter/channel/postman/PostmanFormatter.kt 58.117% <75.000%> (+0.412%) ⬆️
...t/easyapi/ai/tools/GetModuleDependencyGraphTool.kt 89.231% <89.231%> (ø)
...om/itangcent/easyapi/ai/agent/AmbientPerception.kt 82.609% <84.906%> (+4.831%) ⬆️

... and 4 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 187a310...11c1a79. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tangcent
tangcent merged commit 2e540cd into master Jul 12, 2026
12 checks passed
@tangcent
tangcent deleted the feat/per-app-env-namespace branch July 12, 2026 02:05
@github-actions github-actions Bot mentioned this pull request Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: new feature Add New Feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant