feat(ai): namespace per-app env vars across exporters and agent#1417
Merged
Conversation
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
Contributor
|
📦 Plugin has been packaged for this PR. You can download |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 4 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:Authorization→ the second export overwrote the first's token.{{host}}→ all apps shared one host.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.PostmanFormatter.toHttpItemandHoppscotchFormatter.buildHeadersviaConfigReader.getFirstas the resolvability oracle.Agent perception (Phase 3)
Ambient.moduleNames+Ambient.frameworkHints— cached percapture()in a single PSI scan, rendered asmodules:/frameworks active:hints in the system prompt. Privacy-preserving: module/framework labels only, no env-var material.get_module_dependency_graph— one new read-onlyPERCEPTIONtool 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)
rule-guide.md(both thesrc/main/resourcesandskills/.../docscopies) covering namespace-key resolution order, per-app env-var naming convention, multi-app bundle-split rule, and a worked two-app example.agent-preamble.md(token-budget ceiling raised).skills/easy-yapi-assistant/SKILL.md.Design decisions (NFRs)
RuleKeys— namespacing uses only existing keys' values.pm.*/session.*bindings; the only runtime change is formatter-level${}→{{}}.AmbientPerceptionTestandGetModuleDependencyGraphToolTest.get_module_dependency_graph,PERCEPTIONkind, 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 goldensAmbientPerceptionTest—moduleNames+frameworkHintscapture + privacy assertionsSystemPromptBuilderTest— ambient rendering + preamble namespacing mentions + raised token ceilingGetModuleDependencyGraphToolTest— adjacency, library/SDK exclusion, 24-node cap, failure handling, privacy, tool kindRuleGuideContentTest— section + convention assertions in both rule-guide copiesAll 7 spec-related test classes pass locally (
./gradlew test --tests ...).