@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/cli/index.js CHANGED
@@ -65,7 +65,7 @@ var init_defaults = __esm({
65
65
  copilot: ".github/prompts",
66
66
  codex: ".codex/agents"
67
67
  };
68
- WAIRON_VERSION = "5.0.2-dev.8";
68
+ WAIRON_VERSION = "5.0.2-dev.9";
69
69
  GITHUB_REPO = "SYW-Apps/Waffle-AIron";
70
70
  ARCHITECT_AGENT_ID = "agent-architect";
71
71
  ARCHITECT_TEMPLATE_ID = "architect";
@@ -1095,6 +1095,14 @@ var init_specs = __esm({
1095
1095
  // Required if type is 'call', references Method name on target interface
1096
1096
  capability: import_zod6.z.string().optional(),
1097
1097
  // Required if type is 'dispatch': the capability routed through the target Portal's dispatch table
1098
+ /**
1099
+ * call/dispatch only: the credential this step presents to an authed callee
1100
+ * Portal, and WHERE it is loaded from (`from` — a secret-store component id,
1101
+ * `env:API_KEY`, a config key, a vault ref, …). A declared DESIGN NOTE — wairon
1102
+ * never fetches it — but its absence on a call into a Portal whose `auth ≠ none`
1103
+ * warns (PORTAL_AUTH_UNMET), so credential loading is never overlooked.
1104
+ */
1105
+ auth: import_zod6.z.object({ from: import_zod6.z.string(), note: import_zod6.z.string().optional() }).optional(),
1098
1106
  assertsGuarantees: import_zod6.z.array(GuaranteeSchema).optional(),
1099
1107
  /**
1100
1108
  * Declared entity invariants this step upholds, as "<type-id>.<invariant-id>"
@@ -12187,6 +12195,44 @@ var init_lint_allows = __esm({
12187
12195
  }
12188
12196
  });
12189
12197
 
12198
+ // src/core/rules/portal-call-auth.ts
12199
+ var portalCallAuthRule;
12200
+ var init_portal_call_auth = __esm({
12201
+ "src/core/rules/portal-call-auth.ts"() {
12202
+ "use strict";
12203
+ portalCallAuthRule = {
12204
+ name: "portal-call-auth",
12205
+ 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.",
12206
+ codes: [
12207
+ { code: "PORTAL_AUTH_UNMET", defaultSeverity: "warning", summary: "A narrative call into another component's authed Portal does not declare where its credential loads from" }
12208
+ ],
12209
+ check(ctx) {
12210
+ for (const impl of ctx.implementations) {
12211
+ const ownComponent = ctx.interfaceMap.get(impl.contract)?.component;
12212
+ const draft = ctx.isImplementationDraft(impl);
12213
+ for (const method2 of impl.methods ?? []) {
12214
+ for (const step of method2.narrative ?? []) {
12215
+ if (step.type !== "call") continue;
12216
+ if (!step.targetComponent || step.targetComponent === ownComponent) continue;
12217
+ const target = ctx.componentMap.get(step.targetComponent);
12218
+ if (!target || target.componentType !== "Portal") continue;
12219
+ if (!target.auth || target.auth.scheme === "none") continue;
12220
+ if (step.auth?.from) continue;
12221
+ ctx.addIssue(
12222
+ "warning",
12223
+ "PORTAL_AUTH_UNMET",
12224
+ `Narrative step ${step.stepNumber} of "${method2.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.`,
12225
+ impl.id,
12226
+ draft
12227
+ );
12228
+ }
12229
+ }
12230
+ }
12231
+ }
12232
+ };
12233
+ }
12234
+ });
12235
+
12190
12236
  // src/core/rules/index.ts
12191
12237
  function makeScopeFilter(opts) {
12192
12238
  const { components, interfaces, implementations, types, scopeSubsystem } = opts;
@@ -12432,6 +12478,7 @@ var init_rules = __esm({
12432
12478
  init_hidden_state();
12433
12479
  init_dependency_conformance();
12434
12480
  init_lint_allows();
12481
+ init_portal_call_auth();
12435
12482
  init_source_analysis();
12436
12483
  init_types();
12437
12484
  init_type_analysis();
@@ -12453,6 +12500,9 @@ var init_rules = __esm({
12453
12500
  narrativeAntipatternsRule,
12454
12501
  narrativeDetailRule,
12455
12502
  portalsRule,
12503
+ // Cross-call auth: a narrative call into an authed Portal must name its
12504
+ // credential source (rides with the portal family).
12505
+ portalCallAuthRule,
12456
12506
  stereotypeDepsRule,
12457
12507
  patternsRule,
12458
12508
  // Facade shape rides with pattern ownership: same §7 doctrine, narrative side.
@@ -12515,6 +12565,7 @@ var init_rules = __esm({
12515
12565
  // L4 expectations: implementations and their code linkage.
12516
12566
  MISSING_IMPLEMENTATION_METHOD: "implementations",
12517
12567
  MISSING_SOURCE_PATH: "implementations",
12568
+ PORTAL_AUTH_UNMET: "implementations",
12518
12569
  MISSING_SOURCE_FILE: "implementations",
12519
12570
  SOURCE_PATH_ESCAPES_ROOT: "implementations",
12520
12571
  UNREALIZED_METHOD: "implementations",
@@ -17078,6 +17129,7 @@ NOTICE:
17078
17129
  type: import_zod9.z.enum(["local", "call", "dispatch", "branch", "switch", "loop", "try", "parallel", "jump", "return", "throw"]),
17079
17130
  targetComponent: import_zod9.z.string().optional().describe("call/dispatch: L2 component id (for dispatch, the Portal routed through)"),
17080
17131
  targetMethod: import_zod9.z.string().optional().describe("call: method name on the target"),
17132
+ auth: import_zod9.z.object({ from: import_zod9.z.string(), note: import_zod9.z.string().optional() }).optional().describe("call/dispatch: the credential this step presents to an AUTHED callee Portal and WHERE it loads from (`from` = a secret-store component id, env:API_KEY, a config key, a vault ref). A design note \u2014 wairon never fetches it. Its absence on a call into a Portal whose auth \u2260 none warns (PORTAL_AUTH_UNMET), so credential loading is never overlooked."),
17081
17133
  detach: import_zod9.z.boolean().optional().describe("call/dispatch: fire-and-forget \u2014 issue the call and continue without awaiting the result (no later step consumes it)"),
17082
17134
  capability: import_zod9.z.string().optional().describe("dispatch: the capability routed through the target Portal's dispatch table (validated against it \u2014 UNSERVED_CAPABILITY)"),
17083
17135
  assertsGuarantees: import_zod9.z.array(import_zod9.z.string().min(1)).optional().describe("Semantic guarantees this step relies on \u2014 each must be declared in the called method's L3 guarantees (NARRATIVE_SEMANTIC_UNBACKED otherwise). Builtin tokens: idempotent | atomic | transactional | exactly-once; extension packs may declare more (any other token is UNKNOWN_GUARANTEE)"),