@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.
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ /**
3
+ * @medicine-wheel/consent-lifecycle — Community Module
4
+ *
5
+ * Community-level consent operations: collective consent,
6
+ * consensus mechanisms, and Elder endorsement.
7
+ * Community consent transcends individual consent — it represents
8
+ * the collective voice of the community.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.communityConsent = communityConsent;
12
+ exports.collectiveDecision = collectiveDecision;
13
+ exports.elderApproval = elderApproval;
14
+ /**
15
+ * Create a community-level consent record.
16
+ * Community consent represents collective agreement, not just
17
+ * individual grantor/grantee relations.
18
+ */
19
+ function communityConsent(community, scope) {
20
+ const now = new Date().toISOString();
21
+ return {
22
+ id: `community-consent-${Date.now()}`,
23
+ grantor: community.name,
24
+ grantee: community.grantee,
25
+ scope,
26
+ state: 'pending',
27
+ ceremonies: [],
28
+ history: [{
29
+ from: 'pending',
30
+ to: 'pending',
31
+ reason: 'Community consent record created — awaiting collective decision.',
32
+ timestamp: now,
33
+ initiatedBy: community.initiatedBy,
34
+ }],
35
+ communityLevel: true,
36
+ dependentRelations: [],
37
+ ocapFlags: {
38
+ ownership: community.name,
39
+ control: community.name,
40
+ access: 'community',
41
+ possession: 'community-server',
42
+ compliant: false,
43
+ },
44
+ };
45
+ }
46
+ /**
47
+ * Consensus mechanism for collective decision-making.
48
+ * Collects voices and determines whether consensus is reached.
49
+ */
50
+ function collectiveDecision(voices) {
51
+ if (voices.length === 0) {
52
+ return {
53
+ consensusReached: false,
54
+ approvalCount: 0,
55
+ objectionCount: 0,
56
+ abstainCount: 0,
57
+ totalVoices: 0,
58
+ summary: 'No voices recorded. Consensus requires community participation.',
59
+ };
60
+ }
61
+ const approvals = voices.filter((v) => v.position === 'approve');
62
+ const objections = voices.filter((v) => v.position === 'object');
63
+ const abstentions = voices.filter((v) => v.position === 'abstain');
64
+ // Consensus requires no objections (not just majority)
65
+ const consensusReached = objections.length === 0 && approvals.length > 0;
66
+ return {
67
+ consensusReached,
68
+ approvalCount: approvals.length,
69
+ objectionCount: objections.length,
70
+ abstainCount: abstentions.length,
71
+ totalVoices: voices.length,
72
+ objections: objections.map((v) => ({
73
+ voice: v.name,
74
+ reason: v.reason ?? 'No reason given',
75
+ })),
76
+ summary: consensusReached
77
+ ? `Consensus reached with ${approvals.length} approval(s) and ${abstentions.length} abstention(s).`
78
+ : `Consensus not reached: ${objections.length} objection(s). All concerns must be addressed.`,
79
+ };
80
+ }
81
+ /**
82
+ * Record Elder approval for a consent record.
83
+ * Elder endorsement carries special weight in Indigenous governance.
84
+ */
85
+ function elderApproval(elderId, record, options) {
86
+ const now = new Date().toISOString();
87
+ const change = {
88
+ from: record.state,
89
+ to: record.state, // Elder approval doesn't change state directly
90
+ reason: `Elder endorsement by ${elderId}${options?.blessing ? `: ${options.blessing}` : ''}`,
91
+ timestamp: now,
92
+ initiatedBy: elderId,
93
+ };
94
+ return {
95
+ ...record,
96
+ history: [...record.history, change],
97
+ };
98
+ }
99
+ //# sourceMappingURL=community.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"community.js","sourceRoot":"","sources":["../src/community.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @medicine-wheel/consent-lifecycle
3
+ *
4
+ * Ongoing relational consent lifecycle for the Medicine Wheel Developer Suite.
5
+ * Consent as a living relational obligation, not a boolean checkbox.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export type { ConsentState, ConsentRecord, ConsentScope, ConsentCeremony, ConsentStateChange, ConsentCascade, } from './types.js';
10
+ export { ConsentStateSchema, ConsentScopeSchema, ConsentCeremonySchema, ConsentStateChangeSchema, ConsentCascadeSchema, ConsentRecordSchema, } from './schemas.js';
11
+ export type { ValidatedConsentRecord, ValidatedConsentScope, ValidatedConsentCeremony, ValidatedConsentStateChange, ValidatedConsentCascade, } from './schemas.js';
12
+ export { grantConsent, renewConsent, renegotiateConsent, withdrawConsent, checkConsentHealth, } from './lifecycle.js';
13
+ export type { ConsentHealthResult } from './lifecycle.js';
14
+ export { defineScope, narrowScope, widenScope, scopeIncludes, } from './scope.js';
15
+ export type { ScopeAdditions, WidenScopeResult, ScopeQuery, ScopeCheckResult, } from './scope.js';
16
+ export { consentCeremony, consentRenewalCeremony, } from './ceremony.js';
17
+ export type { ConsentCeremonyOptions } from './ceremony.js';
18
+ export { communityConsent, collectiveDecision, elderApproval, } from './community.js';
19
+ export type { CommunityInfo, CommunityVoice, ConsensusResult, ElderApprovalOptions, } from './community.js';
20
+ export { onWithdrawal, propagateScopeChange, findDependentRelations, } from './cascade.js';
21
+ export type { AffectedRelation, ScopeChangeResult, DependencyResult, } from './cascade.js';
22
+ export { consentStaleAlert, renewalDue, scopeMismatch, healthCheck, } from './alerts.js';
23
+ export type { StaleAlert, RenewalItem, RenewalDueResult, ActionDescription, ScopeMismatchResult, BatchHealthResult, } from './alerts.js';
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,OAAO,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAG5D,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,GACd,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ /**
3
+ * @medicine-wheel/consent-lifecycle
4
+ *
5
+ * Ongoing relational consent lifecycle for the Medicine Wheel Developer Suite.
6
+ * Consent as a living relational obligation, not a boolean checkbox.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.healthCheck = exports.scopeMismatch = exports.renewalDue = exports.consentStaleAlert = exports.findDependentRelations = exports.propagateScopeChange = exports.onWithdrawal = exports.elderApproval = exports.collectiveDecision = exports.communityConsent = exports.consentRenewalCeremony = exports.consentCeremony = exports.scopeIncludes = exports.widenScope = exports.narrowScope = exports.defineScope = exports.checkConsentHealth = exports.withdrawConsent = exports.renegotiateConsent = exports.renewConsent = exports.grantConsent = exports.ConsentRecordSchema = exports.ConsentCascadeSchema = exports.ConsentStateChangeSchema = exports.ConsentCeremonySchema = exports.ConsentScopeSchema = exports.ConsentStateSchema = void 0;
12
+ // ── Schemas ─────────────────────────────────────────────────────────────────
13
+ var schemas_js_1 = require("./schemas.js");
14
+ Object.defineProperty(exports, "ConsentStateSchema", { enumerable: true, get: function () { return schemas_js_1.ConsentStateSchema; } });
15
+ Object.defineProperty(exports, "ConsentScopeSchema", { enumerable: true, get: function () { return schemas_js_1.ConsentScopeSchema; } });
16
+ Object.defineProperty(exports, "ConsentCeremonySchema", { enumerable: true, get: function () { return schemas_js_1.ConsentCeremonySchema; } });
17
+ Object.defineProperty(exports, "ConsentStateChangeSchema", { enumerable: true, get: function () { return schemas_js_1.ConsentStateChangeSchema; } });
18
+ Object.defineProperty(exports, "ConsentCascadeSchema", { enumerable: true, get: function () { return schemas_js_1.ConsentCascadeSchema; } });
19
+ Object.defineProperty(exports, "ConsentRecordSchema", { enumerable: true, get: function () { return schemas_js_1.ConsentRecordSchema; } });
20
+ // ── Lifecycle ───────────────────────────────────────────────────────────────
21
+ var lifecycle_js_1 = require("./lifecycle.js");
22
+ Object.defineProperty(exports, "grantConsent", { enumerable: true, get: function () { return lifecycle_js_1.grantConsent; } });
23
+ Object.defineProperty(exports, "renewConsent", { enumerable: true, get: function () { return lifecycle_js_1.renewConsent; } });
24
+ Object.defineProperty(exports, "renegotiateConsent", { enumerable: true, get: function () { return lifecycle_js_1.renegotiateConsent; } });
25
+ Object.defineProperty(exports, "withdrawConsent", { enumerable: true, get: function () { return lifecycle_js_1.withdrawConsent; } });
26
+ Object.defineProperty(exports, "checkConsentHealth", { enumerable: true, get: function () { return lifecycle_js_1.checkConsentHealth; } });
27
+ // ── Scope ───────────────────────────────────────────────────────────────────
28
+ var scope_js_1 = require("./scope.js");
29
+ Object.defineProperty(exports, "defineScope", { enumerable: true, get: function () { return scope_js_1.defineScope; } });
30
+ Object.defineProperty(exports, "narrowScope", { enumerable: true, get: function () { return scope_js_1.narrowScope; } });
31
+ Object.defineProperty(exports, "widenScope", { enumerable: true, get: function () { return scope_js_1.widenScope; } });
32
+ Object.defineProperty(exports, "scopeIncludes", { enumerable: true, get: function () { return scope_js_1.scopeIncludes; } });
33
+ // ── Ceremony ────────────────────────────────────────────────────────────────
34
+ var ceremony_js_1 = require("./ceremony.js");
35
+ Object.defineProperty(exports, "consentCeremony", { enumerable: true, get: function () { return ceremony_js_1.consentCeremony; } });
36
+ Object.defineProperty(exports, "consentRenewalCeremony", { enumerable: true, get: function () { return ceremony_js_1.consentRenewalCeremony; } });
37
+ // ── Community ───────────────────────────────────────────────────────────────
38
+ var community_js_1 = require("./community.js");
39
+ Object.defineProperty(exports, "communityConsent", { enumerable: true, get: function () { return community_js_1.communityConsent; } });
40
+ Object.defineProperty(exports, "collectiveDecision", { enumerable: true, get: function () { return community_js_1.collectiveDecision; } });
41
+ Object.defineProperty(exports, "elderApproval", { enumerable: true, get: function () { return community_js_1.elderApproval; } });
42
+ // ── Cascade ─────────────────────────────────────────────────────────────────
43
+ var cascade_js_1 = require("./cascade.js");
44
+ Object.defineProperty(exports, "onWithdrawal", { enumerable: true, get: function () { return cascade_js_1.onWithdrawal; } });
45
+ Object.defineProperty(exports, "propagateScopeChange", { enumerable: true, get: function () { return cascade_js_1.propagateScopeChange; } });
46
+ Object.defineProperty(exports, "findDependentRelations", { enumerable: true, get: function () { return cascade_js_1.findDependentRelations; } });
47
+ // ── Alerts ──────────────────────────────────────────────────────────────────
48
+ var alerts_js_1 = require("./alerts.js");
49
+ Object.defineProperty(exports, "consentStaleAlert", { enumerable: true, get: function () { return alerts_js_1.consentStaleAlert; } });
50
+ Object.defineProperty(exports, "renewalDue", { enumerable: true, get: function () { return alerts_js_1.renewalDue; } });
51
+ Object.defineProperty(exports, "scopeMismatch", { enumerable: true, get: function () { return alerts_js_1.scopeMismatch; } });
52
+ Object.defineProperty(exports, "healthCheck", { enumerable: true, get: function () { return alerts_js_1.healthCheck; } });
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAYH,+EAA+E;AAC/E,2CAOsB;AANpB,gHAAA,kBAAkB,OAAA;AAClB,gHAAA,kBAAkB,OAAA;AAClB,mHAAA,qBAAqB,OAAA;AACrB,sHAAA,wBAAwB,OAAA;AACxB,kHAAA,oBAAoB,OAAA;AACpB,iHAAA,mBAAmB,OAAA;AAWrB,+EAA+E;AAC/E,+CAMwB;AALtB,4GAAA,YAAY,OAAA;AACZ,4GAAA,YAAY,OAAA;AACZ,kHAAA,kBAAkB,OAAA;AAClB,+GAAA,eAAe,OAAA;AACf,kHAAA,kBAAkB,OAAA;AAKpB,+EAA+E;AAC/E,uCAKoB;AAJlB,uGAAA,WAAW,OAAA;AACX,uGAAA,WAAW,OAAA;AACX,sGAAA,UAAU,OAAA;AACV,yGAAA,aAAa,OAAA;AAUf,+EAA+E;AAC/E,6CAGuB;AAFrB,8GAAA,eAAe,OAAA;AACf,qHAAA,sBAAsB,OAAA;AAKxB,+EAA+E;AAC/E,+CAIwB;AAHtB,gHAAA,gBAAgB,OAAA;AAChB,kHAAA,kBAAkB,OAAA;AAClB,6GAAA,aAAa,OAAA;AAUf,+EAA+E;AAC/E,2CAIsB;AAHpB,0GAAA,YAAY,OAAA;AACZ,kHAAA,oBAAoB,OAAA;AACpB,oHAAA,sBAAsB,OAAA;AASxB,+EAA+E;AAC/E,yCAKqB;AAJnB,8GAAA,iBAAiB,OAAA;AACjB,uGAAA,UAAU,OAAA;AACV,0GAAA,aAAa,OAAA;AACb,wGAAA,WAAW,OAAA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @medicine-wheel/consent-lifecycle — Lifecycle Module
3
+ *
4
+ * Core consent lifecycle operations: grant, renew, renegotiate,
5
+ * withdraw, and health assessment. Consent is a living relationship,
6
+ * not a one-time event.
7
+ */
8
+ import type { ConsentRecord, ConsentState, ConsentScope } from './types.js';
9
+ /**
10
+ * Grant initial consent, transitioning from 'pending' to 'granted'.
11
+ * Sets the grantedAt timestamp and computes expiration if renewalInterval is set.
12
+ */
13
+ export declare function grantConsent(record: ConsentRecord): ConsentRecord;
14
+ /**
15
+ * Renew existing consent, resetting the expiration clock.
16
+ * Consent must be in 'active', 'granted', or 'renewal-needed' state.
17
+ */
18
+ export declare function renewConsent(record: ConsentRecord): ConsentRecord;
19
+ /**
20
+ * Renegotiate consent with a new scope.
21
+ * Transitions to 'renegotiating' until the new scope is accepted.
22
+ * The new scope replaces the old scope once finalized.
23
+ */
24
+ export declare function renegotiateConsent(record: ConsentRecord, newScope: ConsentScope): ConsentRecord;
25
+ /**
26
+ * Withdraw consent with a reason. This is a terminal action that
27
+ * triggers cascading effects on all dependent relations.
28
+ */
29
+ export declare function withdrawConsent(record: ConsentRecord, reason: string): ConsentRecord;
30
+ /**
31
+ * Check the health of a consent record.
32
+ * Evaluates whether consent is current, properly renewed, and
33
+ * within scope. Returns a health assessment with recommendations.
34
+ */
35
+ export declare function checkConsentHealth(record: ConsentRecord): ConsentHealthResult;
36
+ /** Result of a consent health check */
37
+ export interface ConsentHealthResult {
38
+ healthy: boolean;
39
+ state: ConsentState;
40
+ issues: string[];
41
+ daysUntilExpiry: number | null;
42
+ needsRenewal: boolean;
43
+ recommendations: string[];
44
+ }
45
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAqBjE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CA4BjE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,YAAY,GACrB,aAAa,CAoBf;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,GACb,aAAa,CAef;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,mBAAmB,CAiE7E;AAID,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ /**
3
+ * @medicine-wheel/consent-lifecycle — Lifecycle Module
4
+ *
5
+ * Core consent lifecycle operations: grant, renew, renegotiate,
6
+ * withdraw, and health assessment. Consent is a living relationship,
7
+ * not a one-time event.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.grantConsent = grantConsent;
11
+ exports.renewConsent = renewConsent;
12
+ exports.renegotiateConsent = renegotiateConsent;
13
+ exports.withdrawConsent = withdrawConsent;
14
+ exports.checkConsentHealth = checkConsentHealth;
15
+ /**
16
+ * Grant initial consent, transitioning from 'pending' to 'granted'.
17
+ * Sets the grantedAt timestamp and computes expiration if renewalInterval is set.
18
+ */
19
+ function grantConsent(record) {
20
+ const now = new Date().toISOString();
21
+ const change = {
22
+ from: record.state,
23
+ to: 'granted',
24
+ reason: 'Initial consent granted',
25
+ timestamp: now,
26
+ initiatedBy: record.grantor,
27
+ };
28
+ const expiresAt = record.renewalInterval
29
+ ? new Date(Date.now() + record.renewalInterval * 86400000).toISOString()
30
+ : record.expiresAt;
31
+ return {
32
+ ...record,
33
+ state: 'granted',
34
+ grantedAt: now,
35
+ expiresAt,
36
+ history: [...record.history, change],
37
+ };
38
+ }
39
+ /**
40
+ * Renew existing consent, resetting the expiration clock.
41
+ * Consent must be in 'active', 'granted', or 'renewal-needed' state.
42
+ */
43
+ function renewConsent(record) {
44
+ const validStates = ['active', 'granted', 'renewal-needed'];
45
+ if (!validStates.includes(record.state)) {
46
+ throw new Error(`Cannot renew consent in state '${record.state}'. Must be one of: ${validStates.join(', ')}`);
47
+ }
48
+ const now = new Date().toISOString();
49
+ const change = {
50
+ from: record.state,
51
+ to: 'active',
52
+ reason: 'Consent renewed',
53
+ timestamp: now,
54
+ initiatedBy: record.grantor,
55
+ };
56
+ const expiresAt = record.renewalInterval
57
+ ? new Date(Date.now() + record.renewalInterval * 86400000).toISOString()
58
+ : record.expiresAt;
59
+ return {
60
+ ...record,
61
+ state: 'active',
62
+ renewedAt: now,
63
+ expiresAt,
64
+ history: [...record.history, change],
65
+ };
66
+ }
67
+ /**
68
+ * Renegotiate consent with a new scope.
69
+ * Transitions to 'renegotiating' until the new scope is accepted.
70
+ * The new scope replaces the old scope once finalized.
71
+ */
72
+ function renegotiateConsent(record, newScope) {
73
+ if (record.state === 'withdrawn') {
74
+ throw new Error('Cannot renegotiate withdrawn consent. A new consent must be created.');
75
+ }
76
+ const now = new Date().toISOString();
77
+ const change = {
78
+ from: record.state,
79
+ to: 'renegotiating',
80
+ reason: `Scope renegotiation initiated: ${newScope.description}`,
81
+ timestamp: now,
82
+ initiatedBy: record.grantor,
83
+ };
84
+ return {
85
+ ...record,
86
+ state: 'renegotiating',
87
+ scope: newScope,
88
+ history: [...record.history, change],
89
+ };
90
+ }
91
+ /**
92
+ * Withdraw consent with a reason. This is a terminal action that
93
+ * triggers cascading effects on all dependent relations.
94
+ */
95
+ function withdrawConsent(record, reason) {
96
+ const now = new Date().toISOString();
97
+ const change = {
98
+ from: record.state,
99
+ to: 'withdrawn',
100
+ reason,
101
+ timestamp: now,
102
+ initiatedBy: record.grantor,
103
+ };
104
+ return {
105
+ ...record,
106
+ state: 'withdrawn',
107
+ history: [...record.history, change],
108
+ };
109
+ }
110
+ /**
111
+ * Check the health of a consent record.
112
+ * Evaluates whether consent is current, properly renewed, and
113
+ * within scope. Returns a health assessment with recommendations.
114
+ */
115
+ function checkConsentHealth(record) {
116
+ const issues = [];
117
+ const now = Date.now();
118
+ // State checks
119
+ if (record.state === 'withdrawn') {
120
+ return {
121
+ healthy: false,
122
+ state: record.state,
123
+ issues: ['Consent has been withdrawn.'],
124
+ daysUntilExpiry: null,
125
+ needsRenewal: false,
126
+ recommendations: ['A new consent must be created if the relationship is to continue.'],
127
+ };
128
+ }
129
+ if (record.state === 'expired') {
130
+ issues.push('Consent has expired and must be renewed.');
131
+ }
132
+ if (record.state === 'pending') {
133
+ issues.push('Consent is still pending — not yet granted.');
134
+ }
135
+ // Expiry checks
136
+ let daysUntilExpiry = null;
137
+ let needsRenewal = false;
138
+ if (record.expiresAt) {
139
+ const expiryTime = new Date(record.expiresAt).getTime();
140
+ daysUntilExpiry = Math.ceil((expiryTime - now) / 86400000);
141
+ if (daysUntilExpiry <= 0) {
142
+ issues.push('Consent has expired.');
143
+ needsRenewal = true;
144
+ }
145
+ else if (daysUntilExpiry <= 30) {
146
+ issues.push(`Consent expires in ${daysUntilExpiry} day(s).`);
147
+ needsRenewal = true;
148
+ }
149
+ }
150
+ // Ceremony checks
151
+ if (record.ceremonies.length === 0) {
152
+ issues.push('No consent ceremonies recorded. Ceremony strengthens consent relations.');
153
+ }
154
+ // OCAP checks
155
+ if (!record.ocapFlags.compliant) {
156
+ issues.push('OCAP® compliance not verified.');
157
+ }
158
+ const healthy = issues.length === 0 && record.state === 'active';
159
+ const recommendations = [];
160
+ if (needsRenewal)
161
+ recommendations.push('Schedule a consent renewal ceremony.');
162
+ if (!record.ocapFlags.compliant)
163
+ recommendations.push('Verify OCAP® compliance.');
164
+ if (record.ceremonies.length === 0)
165
+ recommendations.push('Conduct a consent ceremony.');
166
+ return {
167
+ healthy,
168
+ state: record.state,
169
+ issues,
170
+ daysUntilExpiry,
171
+ needsRenewal,
172
+ recommendations,
173
+ };
174
+ }
175
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}