@passioncode-ai/passioncode 0.2.40 → 0.2.42

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/family.json +1 -1
  3. package/package.json +1 -1
  4. package/payload/.claude-plugin/marketplace.json +2 -2
  5. package/payload/manifest.json +8 -8
  6. package/payload/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
  7. package/payload/plugins/fabric-agent-adapter/hooks/hooks.json +1 -1
  8. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +3 -3
  9. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/operator-channel-and-repository.md +4 -1
  10. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/adapt_project.py +2 -2
  11. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +2 -2
  12. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/board.md +3 -2
  13. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/delegation.md +22 -0
  14. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/estate-record.md +44 -6
  15. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/interop.md +46 -8
  16. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/kit-modules.md +6 -4
  17. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +7 -2
  18. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-actions.mjs +30 -15
  19. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-context.mjs +5 -0
  20. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-delegation.mjs +17 -9
  21. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-estate-rules.mjs +606 -0
  22. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-estate.mjs +48 -525
  23. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop-rules.mjs +43 -6
  24. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop.mjs +14 -4
  25. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-mandate.mjs +48 -15
  26. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-protocols.mjs +4 -3
  27. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_actions.py +39 -16
  28. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_context.py +8 -1
  29. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_delegation.py +22 -11
  30. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_estate.py +86 -642
  31. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_estate_rules.py +766 -0
  32. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop.py +70 -12
  33. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop_rules.py +59 -8
  34. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_mandate.py +56 -16
  35. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_protocols.py +4 -2
  36. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/kit.json +220 -21
  37. package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +3 -3
  38. package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/operator-channel-and-repository.md +4 -1
  39. package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/resilience-and-autonomy.md +7 -0
  40. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +69 -34
  41. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/references/project-board.md +27 -15
  42. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/references/session-hooks.md +13 -7
  43. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session.py +8 -0
  44. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_cli.py +17 -9
  45. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_env.py +60 -1
  46. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_mail.py +10 -3
  47. package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_mcp.py +39 -4
  48. package/payload/plugins/passioncode/.claude-plugin/plugin.json +1 -1
@@ -3,6 +3,11 @@
3
3
  // Part of the Node service kit (layer L3, after fabric-descriptor); the twin of fabric_context.py, answer for answer
4
4
  // (test/fixtures/kit-context-cases.json). Node built-ins only. The facade fabric-service.mjs does not re-export it.
5
5
  // A refusal exits 78 (EX_CONFIG) with nothing created; a second copy for the same context exits 75 as holdSingleInstance does.
6
+ // An organization's instance whose context the record does not pin (`organizations`, DEC-0127) still starts: the helper
7
+ // checks the placement and its share grant, not the pin (decision D5 of 0.52.0). Its tokens are refused instead:
8
+ // hubKeyCertified reads a context's hub keys only while the record pins that organization (DL-14a, DEC-0128), so the
9
+ // service passes `estateContext: context` to its delegation gate. A refusal at start would stop every organization
10
+ // instance on today's records, which pin none until every reader is pinned at or after DEC-0127.
6
11
  import crypto from 'node:crypto';
7
12
  import fs from 'node:fs';
8
13
  import path from 'node:path';
@@ -263,10 +263,11 @@ const readableClock = (now) => typeof now === 'number' && Number.isFinite(now) &
263
263
  * `kid` and the published key must be certified by that revision. `estate` is a revision the caller verified
264
264
  * (fabric-estate.mjs verifyEstateRecord) and its machine applied, or a function returning it; only an absent `estate`
265
265
  * skips the rule (null is an unreadable source). `estateApplied` is the highest revision the machine applied,
266
- * `estateRevocations` the revocation delta's entries since (an array or a function). A source that throws is
267
- * unreadable, never a pass. `[kind, detail]` or null.
266
+ * `estateRevocations` the revocation delta's entries since (an array or a function), `estateContext` the context this
267
+ * callee serves (DEC-0128: an organization's `org:<orgId>` reads that context's hub keys while the record pins it;
268
+ * absent or `personal`, the personal ones). A source that throws is unreadable, never a pass. `[kind, detail]` or null.
268
269
  */
269
- function estateProblem({ estate, estateApplied, estateRevocations }, kid, x, now) {
270
+ function estateProblem({ estate, estateApplied, estateRevocations, estateContext }, kid, x, now) {
270
271
  if (estate === undefined) return null;
271
272
  let record;
272
273
  let extra;
@@ -276,7 +277,10 @@ function estateProblem({ estate, estateApplied, estateRevocations }, kid, x, now
276
277
  } catch {
277
278
  return ['issuer', 'estate-unreadable'];
278
279
  }
279
- const verdict = hubKeyCertified(record, kid, x, now, estateApplied, extra === undefined ? undefined : { extraRevocations: extra });
280
+ const verdict = hubKeyCertified(record, kid, x, now, estateApplied, {
281
+ ...(extra === undefined ? {} : { extraRevocations: extra }),
282
+ ...(estateContext === undefined ? {} : { context: estateContext }),
283
+ });
280
284
  // The clock was refused before row 1, so a verdict here is the token's or the trust source's.
281
285
  return verdict.certified ? null : [verdict.fault === 'token' ? 'token' : 'issuer', verdict.detail];
282
286
  }
@@ -284,16 +288,18 @@ function estateProblem({ estate, estateApplied, estateRevocations }, kid, x, now
284
288
  /**
285
289
  * DL-13, in its fixed order: nothing about a token is believed before its signature is. `now` is seconds since
286
290
  * the epoch; a clock that is not one is refused `unknown-state` `no-clock` before row 1. Answers {ok: true, claims,
287
- * principal, caller, chain, kid} or {ok: false, code, detail}.
291
+ * principal, caller, chain, kid} or {ok: false, code, detail}. `estateContext` (DL-14a, DEC-0128): the context this
292
+ * callee serves; an organization's `org:<orgId>` verifies the token under that context's hub key, and `issuer` is then
293
+ * that organization pin's context issuer (`organizations[].iss`); absent or `personal`, the personal hub key.
288
294
  */
289
- export function verifyDelegation(token, { audience, jwks, now, capability, effect, issuer, readOnly, estate, estateApplied, estateRevocations } = {}) {
295
+ export function verifyDelegation(token, { audience, jwks, now, capability, effect, issuer, readOnly, estate, estateApplied, estateRevocations, estateContext } = {}) {
290
296
  // Before row 1: every time row compares against the clock, and a comparison with NaN is always false.
291
297
  if (!readableClock(now)) return refuse('unknown-state', 'no-clock');
292
298
  if (!isNonEmptyString(issuer)) return refuse('issuer-unavailable', 'no-trusted-issuer');
293
299
  if (!hasKeys(jwks)) return refuse('issuer-unavailable', 'no-published-keys');
294
300
  const checked = authentic(token, jwks, DELEGATION_TYP);
295
301
  if ('problem' in checked) return refuse(checked.issuer ? 'issuer-unavailable' : 'unauthenticated', checked.problem);
296
- const uncertified = estateProblem({ estate, estateApplied, estateRevocations }, checked.kid, checked.x, now);
302
+ const uncertified = estateProblem({ estate, estateApplied, estateRevocations, estateContext }, checked.kid, checked.x, now);
297
303
  if (uncertified) return refuse(uncertified[0] === 'issuer' ? 'issuer-unavailable' : 'unauthenticated', uncertified[1]);
298
304
  const shaped = delegationShape(checked.compact.payload);
299
305
  if ('problem' in shaped) return refuse('unauthenticated', shaped.problem);
@@ -465,8 +471,10 @@ export const TIERS = Object.freeze(['T0', 'T1', 'T2']);
465
471
  * service's own local floor authenticated, T1 an enrolled machine of the same owner, T2 everything else (and any call
466
472
  * relayed from off the machine). A T0 or T1 caller is never required to present a token: with none, the call passes
467
473
  * with no delegation. A present token is verified at every tier. `issuer` (auth.delegation.issuer) is required.
474
+ * `estateContext` is the context the service's instance runs in (DL-14a, DEC-0128: an organization's instance passes its
475
+ * `org:<orgId>`, and `issuer` its pin's context issuer).
468
476
  */
469
- export function delegationGate({ audience, jwks, effects, issuer, readOnly = false, clock = () => Date.now() / 1000, estate, estateApplied, estateRevocations }) {
477
+ export function delegationGate({ audience, jwks, effects, issuer, readOnly = false, clock = () => Date.now() / 1000, estate, estateApplied, estateRevocations, estateContext }) {
470
478
  if (!isNonEmptyString(issuer)) throw new Error('the gate needs the issuer it trusts (auth.delegation.issuer)');
471
479
  return async (tool, headers, tier = 'T2') => {
472
480
  const effect = effects?.[tool];
@@ -477,7 +485,7 @@ export function delegationGate({ audience, jwks, effects, issuer, readOnly = fal
477
485
  return refuse('unauthenticated', 'no-token');
478
486
  }
479
487
  const keys = jwks instanceof JwksCache ? await jwks.get(kidOf(carried.token)) : jwks;
480
- const verdict = verifyDelegation(carried.token, { audience, jwks: keys, now: clock(), capability: tool, effect, readOnly, issuer, estate, estateApplied, estateRevocations });
488
+ const verdict = verifyDelegation(carried.token, { audience, jwks: keys, now: clock(), capability: tool, effect, readOnly, issuer, estate, estateApplied, estateRevocations, estateContext });
481
489
  if (verdict.ok) verdict.tier = TIERS.includes(tier) ? tier : 'T2';
482
490
  return verdict;
483
491
  };