@medicine-wheel/consent-lifecycle 0.2.2

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/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # @medicine-wheel/consent-lifecycle
2
+
3
+ Ongoing relational consent lifecycle for the Medicine Wheel Developer Suite.
4
+
5
+ > Consent as a living relational obligation, not a boolean checkbox.
6
+
7
+ ## Purpose
8
+
9
+ Transforms consent from a boolean checkbox into a living relational obligation with lifecycle tracking, renewal, renegotiation, and community-level consent protocols.
10
+
11
+ Wilson's relational accountability means consent is not an event — it's a *relationship*. "Once you are in relationship, you are responsible for that relationship's wellbeing." Consent must be maintained, renewed, and can be withdrawn — with cascading effects on all dependent relations.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @medicine-wheel/consent-lifecycle
17
+ ```
18
+
19
+ ## Key Concepts
20
+
21
+ ### ConsentState
22
+
23
+ Consent moves through a lifecycle of states:
24
+ - `pending` — consent requested but not yet granted
25
+ - `granted` — consent given but not yet ceremonialized
26
+ - `active` — consent is active and honored through ceremony
27
+ - `renewal-needed` — consent approaching expiration
28
+ - `expired` — consent has lapsed
29
+ - `renegotiating` — scope is being renegotiated
30
+ - `withdrawn` — consent has been withdrawn (terminal)
31
+
32
+ ### Cascading Effects
33
+
34
+ When consent is withdrawn or scope changes, all dependent relations are affected. The cascade module computes these effects and ensures nothing falls through the cracks.
35
+
36
+ ### Community Consent
37
+
38
+ Community-level consent transcends individual consent. It requires collective decision-making through consensus mechanisms and may require Elder endorsement.
39
+
40
+ ## API
41
+
42
+ ### Lifecycle Module
43
+
44
+ - `grantConsent(record)` — initial grant
45
+ - `renewConsent(record)` — renew existing consent
46
+ - `renegotiateConsent(record, newScope)` — change scope
47
+ - `withdrawConsent(record, reason)` — withdraw with cascading effects
48
+ - `checkConsentHealth(record)` — health assessment
49
+
50
+ ### Scope Module
51
+
52
+ - `defineScope(description, dataTypes, purposes)` — create scope
53
+ - `narrowScope(scope, restrictions)` — add restrictions
54
+ - `widenScope(scope, additions)` — expand scope (requires re-consent)
55
+ - `scopeIncludes(scope, query)` — check if action is within scope
56
+
57
+ ### Ceremony Module
58
+
59
+ - `consentCeremony(record, participants)` — record consent ceremony
60
+ - `consentRenewalCeremony(record, participants)` — renewal ceremony
61
+
62
+ ### Community Module
63
+
64
+ - `communityConsent(community, scope)` — community-level consent
65
+ - `collectiveDecision(voices)` — consensus mechanism
66
+ - `elderApproval(elderId, record)` — Elder endorsement
67
+
68
+ ### Cascade Module
69
+
70
+ - `onWithdrawal(record)` — compute cascading effects
71
+ - `propagateScopeChange(record, newScope)` — update dependent relations
72
+ - `findDependentRelations(record, allRecords)` — find dependencies
73
+
74
+ ### Alerts Module
75
+
76
+ - `consentStaleAlert(record)` — warn when consent needs renewal
77
+ - `renewalDue(records)` — find all records needing renewal
78
+ - `scopeMismatch(record, action)` — detect action outside scope
79
+ - `healthCheck(records)` — batch health check
80
+
81
+ ## License
82
+
83
+ MIT — IAIP Collaborative, Shawinigan, QC
84
+
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @medicine-wheel/consent-lifecycle — Alerts Module
3
+ *
4
+ * Consent health monitoring: stale consent warnings, renewal
5
+ * due dates, scope mismatches, and batch health checks.
6
+ * Consent that goes unmonitored decays — these alerts prevent that.
7
+ */
8
+ import type { ConsentRecord } from './types.js';
9
+ import type { ConsentHealthResult } from './lifecycle.js';
10
+ /**
11
+ * Check whether a consent record is stale and needs renewal.
12
+ * Returns a warning if consent is approaching or past expiration.
13
+ */
14
+ export declare function consentStaleAlert(record: ConsentRecord): StaleAlert | null;
15
+ /**
16
+ * Find all consent records that need renewal.
17
+ * Returns records sorted by urgency (most urgent first).
18
+ */
19
+ export declare function renewalDue(records: ConsentRecord[]): RenewalDueResult;
20
+ /**
21
+ * Detect whether an action falls outside the consent scope.
22
+ * Returns a mismatch report if the action is not covered.
23
+ */
24
+ export declare function scopeMismatch(record: ConsentRecord, action: ActionDescription): ScopeMismatchResult;
25
+ /**
26
+ * Batch health check across all consent records.
27
+ * Returns a comprehensive health report for the entire consent landscape.
28
+ */
29
+ export declare function healthCheck(records: ConsentRecord[]): BatchHealthResult;
30
+ /** Stale consent alert */
31
+ export interface StaleAlert {
32
+ recordId: string;
33
+ severity: 'info' | 'warning' | 'critical';
34
+ message: string;
35
+ daysUntilExpiry: number | null;
36
+ }
37
+ /** A single renewal item */
38
+ export interface RenewalItem {
39
+ recordId: string;
40
+ grantor: string;
41
+ grantee: string;
42
+ severity: 'info' | 'warning' | 'critical';
43
+ daysUntilExpiry: number | null;
44
+ message: string;
45
+ }
46
+ /** Result of renewal due check */
47
+ export interface RenewalDueResult {
48
+ totalDue: number;
49
+ items: RenewalItem[];
50
+ summary: string;
51
+ }
52
+ /** Description of an action to check against scope */
53
+ export interface ActionDescription {
54
+ dataType: string;
55
+ purpose: string;
56
+ }
57
+ /** Result of scope mismatch check */
58
+ export interface ScopeMismatchResult {
59
+ mismatch: boolean;
60
+ issues: string[];
61
+ recommendation: string;
62
+ }
63
+ /** Batch health check result */
64
+ export interface BatchHealthResult {
65
+ total: number;
66
+ healthy: number;
67
+ unhealthy: number;
68
+ results: Array<{
69
+ recordId: string;
70
+ health: ConsentHealthResult;
71
+ }>;
72
+ summary: string;
73
+ }
74
+ //# sourceMappingURL=alerts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alerts.d.ts","sourceRoot":"","sources":["../src/alerts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAgD1E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,gBAAgB,CA8BrE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,iBAAiB,GACxB,mBAAmB,CAmCrB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,iBAAiB,CAmBvE;AAID,0BAA0B;AAC1B,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,4BAA4B;AAC5B,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IAC1C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qCAAqC;AACrC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,gCAAgC;AAChC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAE,CAAC,CAAC;IAClE,OAAO,EAAE,MAAM,CAAC;CACjB"}
package/dist/alerts.js ADDED
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * @medicine-wheel/consent-lifecycle — Alerts Module
4
+ *
5
+ * Consent health monitoring: stale consent warnings, renewal
6
+ * due dates, scope mismatches, and batch health checks.
7
+ * Consent that goes unmonitored decays — these alerts prevent that.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.consentStaleAlert = consentStaleAlert;
11
+ exports.renewalDue = renewalDue;
12
+ exports.scopeMismatch = scopeMismatch;
13
+ exports.healthCheck = healthCheck;
14
+ const lifecycle_js_1 = require("./lifecycle.js");
15
+ /**
16
+ * Check whether a consent record is stale and needs renewal.
17
+ * Returns a warning if consent is approaching or past expiration.
18
+ */
19
+ function consentStaleAlert(record) {
20
+ if (record.state === 'withdrawn')
21
+ return null;
22
+ if (!record.expiresAt) {
23
+ // No expiration — check if consent has never been renewed
24
+ if (record.state === 'granted' && !record.renewedAt) {
25
+ return {
26
+ recordId: record.id,
27
+ severity: 'info',
28
+ message: `Consent '${record.id}' has been granted but never renewed or activated through ceremony.`,
29
+ daysUntilExpiry: null,
30
+ };
31
+ }
32
+ return null;
33
+ }
34
+ const now = Date.now();
35
+ const expiryTime = new Date(record.expiresAt).getTime();
36
+ const daysUntilExpiry = Math.ceil((expiryTime - now) / 86400000);
37
+ if (daysUntilExpiry <= 0) {
38
+ return {
39
+ recordId: record.id,
40
+ severity: 'critical',
41
+ message: `Consent '${record.id}' has EXPIRED. Immediate renewal required.`,
42
+ daysUntilExpiry,
43
+ };
44
+ }
45
+ if (daysUntilExpiry <= 7) {
46
+ return {
47
+ recordId: record.id,
48
+ severity: 'warning',
49
+ message: `Consent '${record.id}' expires in ${daysUntilExpiry} day(s). Schedule renewal ceremony.`,
50
+ daysUntilExpiry,
51
+ };
52
+ }
53
+ if (daysUntilExpiry <= 30) {
54
+ return {
55
+ recordId: record.id,
56
+ severity: 'info',
57
+ message: `Consent '${record.id}' expires in ${daysUntilExpiry} day(s). Plan for renewal.`,
58
+ daysUntilExpiry,
59
+ };
60
+ }
61
+ return null;
62
+ }
63
+ /**
64
+ * Find all consent records that need renewal.
65
+ * Returns records sorted by urgency (most urgent first).
66
+ */
67
+ function renewalDue(records) {
68
+ const due = [];
69
+ for (const record of records) {
70
+ if (record.state === 'withdrawn')
71
+ continue;
72
+ const alert = consentStaleAlert(record);
73
+ if (alert) {
74
+ due.push({
75
+ recordId: record.id,
76
+ grantor: record.grantor,
77
+ grantee: record.grantee,
78
+ severity: alert.severity,
79
+ daysUntilExpiry: alert.daysUntilExpiry,
80
+ message: alert.message,
81
+ });
82
+ }
83
+ }
84
+ // Sort by urgency: critical first, then warning, then info
85
+ const severityOrder = { critical: 0, warning: 1, info: 2 };
86
+ due.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
87
+ return {
88
+ totalDue: due.length,
89
+ items: due,
90
+ summary: due.length === 0
91
+ ? 'No consent records need renewal.'
92
+ : `${due.length} consent record(s) need attention: ${due.filter((d) => d.severity === 'critical').length} critical, ${due.filter((d) => d.severity === 'warning').length} warning.`,
93
+ };
94
+ }
95
+ /**
96
+ * Detect whether an action falls outside the consent scope.
97
+ * Returns a mismatch report if the action is not covered.
98
+ */
99
+ function scopeMismatch(record, action) {
100
+ const issues = [];
101
+ // Check state first
102
+ if (record.state !== 'active' && record.state !== 'granted') {
103
+ issues.push(`Consent is in '${record.state}' state — not active.`);
104
+ }
105
+ // Check data type
106
+ if (!record.scope.dataTypes.some((dt) => dt === action.dataType || dt === '*')) {
107
+ issues.push(`Data type '${action.dataType}' not in consented data types.`);
108
+ }
109
+ // Check purpose
110
+ if (!record.scope.purposes.some((p) => p === action.purpose || p === '*')) {
111
+ issues.push(`Purpose '${action.purpose}' not in consented purposes.`);
112
+ }
113
+ // Check restrictions
114
+ for (const restriction of record.scope.restrictions) {
115
+ if (restriction.toLowerCase().includes(action.dataType.toLowerCase()) ||
116
+ restriction.toLowerCase().includes(action.purpose.toLowerCase())) {
117
+ issues.push(`Action may violate restriction: '${restriction}'.`);
118
+ }
119
+ }
120
+ return {
121
+ mismatch: issues.length > 0,
122
+ issues,
123
+ recommendation: issues.length > 0
124
+ ? 'This action exceeds the current consent scope. Renegotiate consent before proceeding.'
125
+ : 'Action is within consent scope.',
126
+ };
127
+ }
128
+ /**
129
+ * Batch health check across all consent records.
130
+ * Returns a comprehensive health report for the entire consent landscape.
131
+ */
132
+ function healthCheck(records) {
133
+ const results = [];
134
+ let healthyCount = 0;
135
+ let unhealthyCount = 0;
136
+ for (const record of records) {
137
+ const health = (0, lifecycle_js_1.checkConsentHealth)(record);
138
+ results.push({ recordId: record.id, health });
139
+ if (health.healthy)
140
+ healthyCount++;
141
+ else
142
+ unhealthyCount++;
143
+ }
144
+ return {
145
+ total: records.length,
146
+ healthy: healthyCount,
147
+ unhealthy: unhealthyCount,
148
+ results,
149
+ summary: `${healthyCount}/${records.length} consent records healthy. ${unhealthyCount} need attention.`,
150
+ };
151
+ }
152
+ //# sourceMappingURL=alerts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alerts.js","sourceRoot":"","sources":["../src/alerts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @medicine-wheel/consent-lifecycle — Cascade Module
3
+ *
4
+ * Manages cascading effects of consent changes. When consent
5
+ * is withdrawn or scope changes, all dependent relations must
6
+ * be updated. This honors the interconnected nature of consent.
7
+ */
8
+ import type { ConsentRecord, ConsentScope, ConsentCascade } from './types.js';
9
+ /**
10
+ * Compute the cascading effects of consent withdrawal.
11
+ * All dependent relations must be notified and updated.
12
+ */
13
+ export declare function onWithdrawal(record: ConsentRecord): ConsentCascade;
14
+ /**
15
+ * Propagate a scope change to all dependent relations.
16
+ * Determines whether dependent relations need review or narrowing.
17
+ */
18
+ export declare function propagateScopeChange(record: ConsentRecord, newScope: ConsentScope): ScopeChangeResult;
19
+ /**
20
+ * Find all relations that depend on a given consent record.
21
+ * Returns the dependent relation IDs with their dependency nature.
22
+ */
23
+ export declare function findDependentRelations(record: ConsentRecord, allRecords: ConsentRecord[]): DependencyResult;
24
+ /** Details of how a dependent relation is affected */
25
+ export interface AffectedRelation {
26
+ relationId: string;
27
+ action: 'narrow' | 'review' | 'withdraw' | 'expire';
28
+ reason: string;
29
+ }
30
+ /** Result of scope change propagation */
31
+ export interface ScopeChangeResult {
32
+ cascade: ConsentCascade;
33
+ narrowed: boolean;
34
+ widened: boolean;
35
+ affectedRelations: AffectedRelation[];
36
+ requiresReconsent: boolean;
37
+ summary: string;
38
+ }
39
+ /** Result of dependency analysis */
40
+ export interface DependencyResult {
41
+ directCount: number;
42
+ transitiveCount: number;
43
+ directDependents: string[];
44
+ transitiveDependents: string[];
45
+ totalAffected: number;
46
+ summary: string;
47
+ }
48
+ //# sourceMappingURL=cascade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade.d.ts","sourceRoot":"","sources":["../src/cascade.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,CAMlE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,YAAY,GACrB,iBAAiB,CA8BnB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,aAAa,EAAE,GAC1B,gBAAgB,CA2BlB;AAID,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ /**
3
+ * @medicine-wheel/consent-lifecycle — Cascade Module
4
+ *
5
+ * Manages cascading effects of consent changes. When consent
6
+ * is withdrawn or scope changes, all dependent relations must
7
+ * be updated. This honors the interconnected nature of consent.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.onWithdrawal = onWithdrawal;
11
+ exports.propagateScopeChange = propagateScopeChange;
12
+ exports.findDependentRelations = findDependentRelations;
13
+ /**
14
+ * Compute the cascading effects of consent withdrawal.
15
+ * All dependent relations must be notified and updated.
16
+ */
17
+ function onWithdrawal(record) {
18
+ return {
19
+ triggerId: record.id,
20
+ affected: [...record.dependentRelations],
21
+ action: 'withdraw',
22
+ };
23
+ }
24
+ /**
25
+ * Propagate a scope change to all dependent relations.
26
+ * Determines whether dependent relations need review or narrowing.
27
+ */
28
+ function propagateScopeChange(record, newScope) {
29
+ const narrowed = isNarrower(record.scope, newScope);
30
+ const widened = isWider(record.scope, newScope);
31
+ const cascade = {
32
+ triggerId: record.id,
33
+ affected: [...record.dependentRelations],
34
+ action: narrowed ? 'narrow' : 'review',
35
+ };
36
+ const affectedDetails = record.dependentRelations.map((relId) => ({
37
+ relationId: relId,
38
+ action: narrowed ? 'narrow' : 'review',
39
+ reason: narrowed
40
+ ? 'Parent consent scope narrowed — dependent scope must be reviewed.'
41
+ : 'Parent consent scope changed — dependent relations need review.',
42
+ }));
43
+ return {
44
+ cascade,
45
+ narrowed,
46
+ widened,
47
+ affectedRelations: affectedDetails,
48
+ requiresReconsent: widened,
49
+ summary: record.dependentRelations.length === 0
50
+ ? 'No dependent relations affected by scope change.'
51
+ : `${record.dependentRelations.length} dependent relation(s) affected. Action: ${cascade.action}.`,
52
+ };
53
+ }
54
+ /**
55
+ * Find all relations that depend on a given consent record.
56
+ * Returns the dependent relation IDs with their dependency nature.
57
+ */
58
+ function findDependentRelations(record, allRecords) {
59
+ // Direct dependents
60
+ const directDependents = record.dependentRelations;
61
+ // Transitive dependents: relations that depend on our dependents
62
+ const transitiveDependents = [];
63
+ for (const depId of directDependents) {
64
+ const depRecord = allRecords.find((r) => r.id === depId);
65
+ if (depRecord) {
66
+ for (const transId of depRecord.dependentRelations) {
67
+ if (!directDependents.includes(transId) && !transitiveDependents.includes(transId)) {
68
+ transitiveDependents.push(transId);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ return {
74
+ directCount: directDependents.length,
75
+ transitiveCount: transitiveDependents.length,
76
+ directDependents,
77
+ transitiveDependents,
78
+ totalAffected: directDependents.length + transitiveDependents.length,
79
+ summary: directDependents.length === 0
80
+ ? 'No dependent relations found.'
81
+ : `${directDependents.length} direct and ${transitiveDependents.length} transitive dependent(s).`,
82
+ };
83
+ }
84
+ // ── Internal Helpers ────────────────────────────────────────────────────────
85
+ function isNarrower(oldScope, newScope) {
86
+ const fewerTypes = newScope.dataTypes.length < oldScope.dataTypes.length;
87
+ const fewerPurposes = newScope.purposes.length < oldScope.purposes.length;
88
+ const moreRestrictions = newScope.restrictions.length > oldScope.restrictions.length;
89
+ return fewerTypes || fewerPurposes || moreRestrictions;
90
+ }
91
+ function isWider(oldScope, newScope) {
92
+ const moreTypes = newScope.dataTypes.some((t) => !oldScope.dataTypes.includes(t));
93
+ const morePurposes = newScope.purposes.some((p) => !oldScope.purposes.includes(p));
94
+ const fewerRestrictions = oldScope.restrictions.some((r) => !newScope.restrictions.includes(r));
95
+ return moreTypes || morePurposes || fewerRestrictions;
96
+ }
97
+ //# sourceMappingURL=cascade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade.js","sourceRoot":"","sources":["../src/cascade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @medicine-wheel/consent-lifecycle — Ceremony Module
3
+ *
4
+ * Records consent ceremonies — the relational acts that formalize
5
+ * consent granting, renewal, and withdrawal. Ceremony honors
6
+ * the relational nature of consent.
7
+ */
8
+ import type { ConsentRecord } from './types.js';
9
+ /**
10
+ * Record a consent ceremony for initial consent granting.
11
+ * Transitions the consent record to 'active' state and logs
12
+ * the ceremony with participants and witnesses.
13
+ */
14
+ export declare function consentCeremony(record: ConsentRecord, participants: string[], options?: ConsentCeremonyOptions): ConsentRecord;
15
+ /**
16
+ * Record a consent renewal ceremony.
17
+ * Resets the consent expiration and transitions to 'active' state.
18
+ */
19
+ export declare function consentRenewalCeremony(record: ConsentRecord, participants: string[], options?: ConsentCeremonyOptions): ConsentRecord;
20
+ /** Options for consent ceremony recording */
21
+ export interface ConsentCeremonyOptions {
22
+ witnessedBy?: string[];
23
+ notes?: string;
24
+ ceremonyId?: string;
25
+ }
26
+ //# sourceMappingURL=ceremony.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ceremony.d.ts","sourceRoot":"","sources":["../src/ceremony.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,aAAa,EAId,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,aAAa,CA4Bf;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,aAAa,CAwCf;AAID,6CAA6C;AAC7C,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * @medicine-wheel/consent-lifecycle — Ceremony Module
4
+ *
5
+ * Records consent ceremonies — the relational acts that formalize
6
+ * consent granting, renewal, and withdrawal. Ceremony honors
7
+ * the relational nature of consent.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.consentCeremony = consentCeremony;
11
+ exports.consentRenewalCeremony = consentRenewalCeremony;
12
+ /**
13
+ * Record a consent ceremony for initial consent granting.
14
+ * Transitions the consent record to 'active' state and logs
15
+ * the ceremony with participants and witnesses.
16
+ */
17
+ function consentCeremony(record, participants, options) {
18
+ const now = new Date().toISOString();
19
+ const ceremony = {
20
+ type: 'initial',
21
+ timestamp: now,
22
+ participants,
23
+ witnessedBy: options?.witnessedBy ?? [],
24
+ outcome: 'active',
25
+ notes: options?.notes,
26
+ ceremonyId: options?.ceremonyId,
27
+ };
28
+ const change = {
29
+ from: record.state,
30
+ to: 'active',
31
+ reason: 'Consent ceremony conducted — consent is now active.',
32
+ timestamp: now,
33
+ initiatedBy: record.grantor,
34
+ };
35
+ return {
36
+ ...record,
37
+ state: 'active',
38
+ grantedAt: record.grantedAt ?? now,
39
+ ceremonies: [...record.ceremonies, ceremony],
40
+ history: [...record.history, change],
41
+ };
42
+ }
43
+ /**
44
+ * Record a consent renewal ceremony.
45
+ * Resets the consent expiration and transitions to 'active' state.
46
+ */
47
+ function consentRenewalCeremony(record, participants, options) {
48
+ const validStates = ['active', 'granted', 'renewal-needed'];
49
+ if (!validStates.includes(record.state)) {
50
+ throw new Error(`Cannot conduct renewal ceremony for consent in state '${record.state}'.`);
51
+ }
52
+ const now = new Date().toISOString();
53
+ const ceremony = {
54
+ type: 'renewal',
55
+ timestamp: now,
56
+ participants,
57
+ witnessedBy: options?.witnessedBy ?? [],
58
+ outcome: 'active',
59
+ notes: options?.notes,
60
+ ceremonyId: options?.ceremonyId,
61
+ };
62
+ const change = {
63
+ from: record.state,
64
+ to: 'active',
65
+ reason: 'Consent renewal ceremony conducted.',
66
+ timestamp: now,
67
+ initiatedBy: record.grantor,
68
+ };
69
+ const expiresAt = record.renewalInterval
70
+ ? new Date(Date.now() + record.renewalInterval * 86400000).toISOString()
71
+ : record.expiresAt;
72
+ return {
73
+ ...record,
74
+ state: 'active',
75
+ renewedAt: now,
76
+ expiresAt,
77
+ ceremonies: [...record.ceremonies, ceremony],
78
+ history: [...record.history, change],
79
+ };
80
+ }
81
+ //# sourceMappingURL=ceremony.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ceremony.js","sourceRoot":"","sources":["../src/ceremony.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAcH,0CAgCC;AAMD,wDA4CC;AAvFD;;;;GAIG;AACH,SAAgB,eAAe,CAC7B,MAAqB,EACrB,YAAsB,EACtB,OAAgC;IAEhC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAoB;QAChC,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,GAAG;QACd,YAAY;QACZ,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,EAAE;QACvC,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,OAAO,EAAE,KAAK;QACrB,UAAU,EAAE,OAAO,EAAE,UAAU;KAChC,CAAC;IAEF,MAAM,MAAM,GAAuB;QACjC,IAAI,EAAE,MAAM,CAAC,KAAK;QAClB,EAAE,EAAE,QAAQ;QACZ,MAAM,EAAE,qDAAqD;QAC7D,SAAS,EAAE,GAAG;QACd,WAAW,EAAE,MAAM,CAAC,OAAO;KAC5B,CAAC;IAEF,OAAO;QACL,GAAG,MAAM;QACT,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,GAAG;QAClC,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC;QAC5C,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;KACrC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CACpC,MAAqB,EACrB,YAAsB,EACtB,OAAgC;IAEhC,MAAM,WAAW,GAAmB,CAAC,QAAQ,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAC5E,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,yDAAyD,MAAM,CAAC,KAAK,IAAI,CAC1E,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAoB;QAChC,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,GAAG;QACd,YAAY;QACZ,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,EAAE;QACvC,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,OAAO,EAAE,KAAK;QACrB,UAAU,EAAE,OAAO,EAAE,UAAU;KAChC,CAAC;IAEF,MAAM,MAAM,GAAuB;QACjC,IAAI,EAAE,MAAM,CAAC,KAAK;QAClB,EAAE,EAAE,QAAQ;QACZ,MAAM,EAAE,qCAAqC;QAC7C,SAAS,EAAE,GAAG;QACd,WAAW,EAAE,MAAM,CAAC,OAAO;KAC5B,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,CAAC,eAAe;QACtC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,eAAe,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE;QACxE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;IAErB,OAAO;QACL,GAAG,MAAM;QACT,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,GAAG;QACd,SAAS;QACT,UAAU,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC;QAC5C,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC;KACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @medicine-wheel/consent-lifecycle — Community Module
3
+ *
4
+ * Community-level consent operations: collective consent,
5
+ * consensus mechanisms, and Elder endorsement.
6
+ * Community consent transcends individual consent — it represents
7
+ * the collective voice of the community.
8
+ */
9
+ import type { ConsentRecord, ConsentScope } from './types.js';
10
+ /**
11
+ * Create a community-level consent record.
12
+ * Community consent represents collective agreement, not just
13
+ * individual grantor/grantee relations.
14
+ */
15
+ export declare function communityConsent(community: CommunityInfo, scope: ConsentScope): ConsentRecord;
16
+ /**
17
+ * Consensus mechanism for collective decision-making.
18
+ * Collects voices and determines whether consensus is reached.
19
+ */
20
+ export declare function collectiveDecision(voices: CommunityVoice[]): ConsensusResult;
21
+ /**
22
+ * Record Elder approval for a consent record.
23
+ * Elder endorsement carries special weight in Indigenous governance.
24
+ */
25
+ export declare function elderApproval(elderId: string, record: ConsentRecord, options?: ElderApprovalOptions): ConsentRecord;
26
+ /** Information about the community granting consent */
27
+ export interface CommunityInfo {
28
+ name: string;
29
+ grantee: string;
30
+ initiatedBy: string;
31
+ }
32
+ /** A community member's voice in collective decision-making */
33
+ export interface CommunityVoice {
34
+ name: string;
35
+ role: string;
36
+ position: 'approve' | 'object' | 'abstain';
37
+ reason?: string;
38
+ }
39
+ /** Result of a collective consensus process */
40
+ export interface ConsensusResult {
41
+ consensusReached: boolean;
42
+ approvalCount: number;
43
+ objectionCount: number;
44
+ abstainCount: number;
45
+ totalVoices: number;
46
+ objections?: Array<{
47
+ voice: string;
48
+ reason: string;
49
+ }>;
50
+ summary: string;
51
+ }
52
+ /** Options for Elder approval */
53
+ export interface ElderApprovalOptions {
54
+ blessing?: string;
55
+ conditions?: string[];
56
+ }
57
+ //# sourceMappingURL=community.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"community.d.ts","sourceRoot":"","sources":["../src/community.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,YAAY,GAClB,aAAa,CA2Bf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,eAAe,CAiC5E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,aAAa,CAef;AAID,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,iCAAiC;AACjC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB"}