@wairon/cli 5.0.2-dev.8 → 5.0.2-dev.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -785,6 +785,14 @@ var init_specs = __esm({
785
785
  // Required if type is 'call', references Method name on target interface
786
786
  capability: import_zod6.z.string().optional(),
787
787
  // Required if type is 'dispatch': the capability routed through the target Portal's dispatch table
788
+ /**
789
+ * call/dispatch only: the credential this step presents to an authed callee
790
+ * Portal, and WHERE it is loaded from (`from` — a secret-store component id,
791
+ * `env:API_KEY`, a config key, a vault ref, …). A declared DESIGN NOTE — wairon
792
+ * never fetches it — but its absence on a call into a Portal whose `auth ≠ none`
793
+ * warns (PORTAL_AUTH_UNMET), so credential loading is never overlooked.
794
+ */
795
+ auth: import_zod6.z.object({ from: import_zod6.z.string(), note: import_zod6.z.string().optional() }).optional(),
788
796
  assertsGuarantees: import_zod6.z.array(GuaranteeSchema).optional(),
789
797
  /**
790
798
  * Declared entity invariants this step upholds, as "<type-id>.<invariant-id>"
@@ -11546,6 +11554,44 @@ var init_lint_allows = __esm({
11546
11554
  }
11547
11555
  });
11548
11556
 
11557
+ // src/core/rules/portal-call-auth.ts
11558
+ var portalCallAuthRule;
11559
+ var init_portal_call_auth = __esm({
11560
+ "src/core/rules/portal-call-auth.ts"() {
11561
+ "use strict";
11562
+ portalCallAuthRule = {
11563
+ name: "portal-call-auth",
11564
+ description: "An OUTBOUND narrative `call` into ANOTHER component's Portal whose auth is not `none` must declare the credential source it presents \u2014 the step's `auth.from`, a design note naming where the secret loads from (a secret-store component, env var, config key, vault ref). Its absence warns (PORTAL_AUTH_UNMET) so credential loading is never overlooked; the actual secret is never stored in the spec. Dispatch steps (a portal's OWN inbound routing) and self-calls are not cross-service calls and are excluded.",
11565
+ codes: [
11566
+ { code: "PORTAL_AUTH_UNMET", defaultSeverity: "warning", summary: "A narrative call into another component's authed Portal does not declare where its credential loads from" }
11567
+ ],
11568
+ check(ctx) {
11569
+ for (const impl of ctx.implementations) {
11570
+ const ownComponent = ctx.interfaceMap.get(impl.contract)?.component;
11571
+ const draft = ctx.isImplementationDraft(impl);
11572
+ for (const method of impl.methods ?? []) {
11573
+ for (const step of method.narrative ?? []) {
11574
+ if (step.type !== "call") continue;
11575
+ if (!step.targetComponent || step.targetComponent === ownComponent) continue;
11576
+ const target = ctx.componentMap.get(step.targetComponent);
11577
+ if (!target || target.componentType !== "Portal") continue;
11578
+ if (!target.auth || target.auth.scheme === "none") continue;
11579
+ if (step.auth?.from) continue;
11580
+ ctx.addIssue(
11581
+ "warning",
11582
+ "PORTAL_AUTH_UNMET",
11583
+ `Narrative step ${step.stepNumber} of "${method.name}" in "${impl.id}" calls the authenticated portal "${target.id}" (auth scheme: ${target.auth.scheme}) but does not declare where its credential is loaded from. Add the credential source (the step's auth.from \u2014 a secret-store component, env var, config key, or vault ref), or drop the portal's auth if it needs none.`,
11584
+ impl.id,
11585
+ draft
11586
+ );
11587
+ }
11588
+ }
11589
+ }
11590
+ }
11591
+ };
11592
+ }
11593
+ });
11594
+
11549
11595
  // src/core/rules/index.ts
11550
11596
  function composeRuleSequence(extraRules = []) {
11551
11597
  const base = SDD_RULES.filter((r) => r !== lintAllowsRule);
@@ -11795,6 +11841,7 @@ var init_rules = __esm({
11795
11841
  init_hidden_state();
11796
11842
  init_dependency_conformance();
11797
11843
  init_lint_allows();
11844
+ init_portal_call_auth();
11798
11845
  init_source_analysis();
11799
11846
  init_types();
11800
11847
  init_type_analysis();
@@ -11816,6 +11863,9 @@ var init_rules = __esm({
11816
11863
  narrativeAntipatternsRule,
11817
11864
  narrativeDetailRule,
11818
11865
  portalsRule,
11866
+ // Cross-call auth: a narrative call into an authed Portal must name its
11867
+ // credential source (rides with the portal family).
11868
+ portalCallAuthRule,
11819
11869
  stereotypeDepsRule,
11820
11870
  patternsRule,
11821
11871
  // Facade shape rides with pattern ownership: same §7 doctrine, narrative side.
@@ -11878,6 +11928,7 @@ var init_rules = __esm({
11878
11928
  // L4 expectations: implementations and their code linkage.
11879
11929
  MISSING_IMPLEMENTATION_METHOD: "implementations",
11880
11930
  MISSING_SOURCE_PATH: "implementations",
11931
+ PORTAL_AUTH_UNMET: "implementations",
11881
11932
  MISSING_SOURCE_FILE: "implementations",
11882
11933
  SOURCE_PATH_ESCAPES_ROOT: "implementations",
11883
11934
  UNREALIZED_METHOD: "implementations",
@@ -15574,7 +15625,7 @@ function defaultTargetConfig(type) {
15574
15625
  enabled: true
15575
15626
  };
15576
15627
  }
15577
- var WAIRON_VERSION = "5.0.2-dev.8";
15628
+ var WAIRON_VERSION = "5.0.2-dev.9";
15578
15629
  var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
15579
15630
  var ARCHITECT_AGENT_ID = "agent-architect";
15580
15631
  var ARCHITECT_TEMPLATE_ID = "architect";