instar 1.3.490 → 1.3.491

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 (95) hide show
  1. package/dashboard/index.html +30 -0
  2. package/dist/commands/server.d.ts.map +1 -1
  3. package/dist/commands/server.js +146 -1
  4. package/dist/commands/server.js.map +1 -1
  5. package/dist/core/GuardPostureStore.d.ts +38 -0
  6. package/dist/core/GuardPostureStore.d.ts.map +1 -0
  7. package/dist/core/GuardPostureStore.js +87 -0
  8. package/dist/core/GuardPostureStore.js.map +1 -0
  9. package/dist/core/MachinePoolRegistry.d.ts +16 -0
  10. package/dist/core/MachinePoolRegistry.d.ts.map +1 -1
  11. package/dist/core/MachinePoolRegistry.js +24 -1
  12. package/dist/core/MachinePoolRegistry.js.map +1 -1
  13. package/dist/core/PeerPresencePuller.d.ts +9 -0
  14. package/dist/core/PeerPresencePuller.d.ts.map +1 -1
  15. package/dist/core/PeerPresencePuller.js +1 -1
  16. package/dist/core/PeerPresencePuller.js.map +1 -1
  17. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  18. package/dist/core/PostUpdateMigrator.js +30 -2
  19. package/dist/core/PostUpdateMigrator.js.map +1 -1
  20. package/dist/core/types.d.ts +29 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/core/types.js.map +1 -1
  23. package/dist/monitoring/ActiveWorkSilenceSentinel.d.ts +8 -0
  24. package/dist/monitoring/ActiveWorkSilenceSentinel.d.ts.map +1 -1
  25. package/dist/monitoring/ActiveWorkSilenceSentinel.js +8 -0
  26. package/dist/monitoring/ActiveWorkSilenceSentinel.js.map +1 -1
  27. package/dist/monitoring/ContextWedgeSentinel.d.ts +8 -0
  28. package/dist/monitoring/ContextWedgeSentinel.d.ts.map +1 -1
  29. package/dist/monitoring/ContextWedgeSentinel.js +8 -0
  30. package/dist/monitoring/ContextWedgeSentinel.js.map +1 -1
  31. package/dist/monitoring/GuardPostureTripwire.d.ts +3 -27
  32. package/dist/monitoring/GuardPostureTripwire.d.ts.map +1 -1
  33. package/dist/monitoring/GuardPostureTripwire.js +8 -76
  34. package/dist/monitoring/GuardPostureTripwire.js.map +1 -1
  35. package/dist/monitoring/GuardRegistry.d.ts +48 -0
  36. package/dist/monitoring/GuardRegistry.d.ts.map +1 -0
  37. package/dist/monitoring/GuardRegistry.js +49 -0
  38. package/dist/monitoring/GuardRegistry.js.map +1 -0
  39. package/dist/monitoring/SessionReaper.d.ts +7 -0
  40. package/dist/monitoring/SessionReaper.d.ts.map +1 -1
  41. package/dist/monitoring/SessionReaper.js +9 -0
  42. package/dist/monitoring/SessionReaper.js.map +1 -1
  43. package/dist/monitoring/SessionWatchdog.d.ts +8 -0
  44. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  45. package/dist/monitoring/SessionWatchdog.js +8 -0
  46. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  47. package/dist/monitoring/SocketDisconnectSentinel.d.ts +8 -0
  48. package/dist/monitoring/SocketDisconnectSentinel.d.ts.map +1 -1
  49. package/dist/monitoring/SocketDisconnectSentinel.js +8 -0
  50. package/dist/monitoring/SocketDisconnectSentinel.js.map +1 -1
  51. package/dist/monitoring/guardManifest.d.ts +67 -0
  52. package/dist/monitoring/guardManifest.d.ts.map +1 -0
  53. package/dist/monitoring/guardManifest.js +536 -0
  54. package/dist/monitoring/guardManifest.js.map +1 -0
  55. package/dist/monitoring/guardPosture.d.ts +77 -0
  56. package/dist/monitoring/guardPosture.d.ts.map +1 -0
  57. package/dist/monitoring/guardPosture.js +198 -0
  58. package/dist/monitoring/guardPosture.js.map +1 -0
  59. package/dist/monitoring/guardPostureView.d.ts +100 -0
  60. package/dist/monitoring/guardPostureView.d.ts.map +1 -0
  61. package/dist/monitoring/guardPostureView.js +294 -0
  62. package/dist/monitoring/guardPostureView.js.map +1 -0
  63. package/dist/monitoring/probes/GuardPostureProbe.d.ts +82 -0
  64. package/dist/monitoring/probes/GuardPostureProbe.d.ts.map +1 -0
  65. package/dist/monitoring/probes/GuardPostureProbe.js +384 -0
  66. package/dist/monitoring/probes/GuardPostureProbe.js.map +1 -0
  67. package/dist/scaffold/templates.d.ts.map +1 -1
  68. package/dist/scaffold/templates.js +9 -0
  69. package/dist/scaffold/templates.js.map +1 -1
  70. package/dist/scheduler/JobScheduler.d.ts +10 -0
  71. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  72. package/dist/scheduler/JobScheduler.js +12 -0
  73. package/dist/scheduler/JobScheduler.js.map +1 -1
  74. package/dist/server/AgentServer.d.ts +8 -0
  75. package/dist/server/AgentServer.d.ts.map +1 -1
  76. package/dist/server/AgentServer.js +2 -0
  77. package/dist/server/AgentServer.js.map +1 -1
  78. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  79. package/dist/server/CapabilityIndex.js +11 -0
  80. package/dist/server/CapabilityIndex.js.map +1 -1
  81. package/dist/server/peerUrlGuard.d.ts +35 -0
  82. package/dist/server/peerUrlGuard.d.ts.map +1 -0
  83. package/dist/server/peerUrlGuard.js +93 -0
  84. package/dist/server/peerUrlGuard.js.map +1 -0
  85. package/dist/server/routes.d.ts +14 -0
  86. package/dist/server/routes.d.ts.map +1 -1
  87. package/dist/server/routes.js +136 -0
  88. package/dist/server/routes.js.map +1 -1
  89. package/package.json +3 -2
  90. package/scripts/lint-guard-manifest.js +264 -0
  91. package/src/data/builtin-manifest.json +65 -65
  92. package/src/data/state-coherence-registry.json +54 -18
  93. package/src/scaffold/templates.ts +9 -0
  94. package/upgrades/1.3.491.md +37 -0
  95. package/upgrades/side-effects/guard-posture-endpoint.md +101 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * guardPosture — the SINGLE shared definition of "what is a guard and what
3
+ * does the config say about it" (GUARD-POSTURE-ENDPOINT-SPEC §2.1).
4
+ *
5
+ * Consumed by BOTH the boot-time GuardPostureTripwire (transition alarms) and
6
+ * the GET /guards endpoint (steady-state readability). Never re-derive this
7
+ * extraction elsewhere — the SafeGitExecutor single-funnel lesson: two copies
8
+ * of "what counts as a guard" WILL drift, and the drifted one is always the
9
+ * one watching when the next Mini incident happens.
10
+ *
11
+ * Also home of resolveGuardConfigSnapshot(): the one-disk-read resolved-config
12
+ * snapshot the endpoint derives everything from. Disk, not the in-memory
13
+ * config object, because the original incident (2026-06-05) was an emergency
14
+ * DIRECT DISK EDIT invisible to in-memory config until restart.
15
+ */
16
+ import fs from 'node:fs';
17
+ import path from 'node:path';
18
+ import { getInitDefaults } from '../config/ConfigDefaults.js';
19
+ import { resolveDevAgentGate } from '../core/devAgentGate.js';
20
+ import { DEV_GATED_FEATURES, getConfigByPath } from '../core/devGatedFeatures.js';
21
+ /** Posture keys whose false→true transition is COST-INCREASING and must be
22
+ * surfaced as loudly as a guard-disable (FABLE-MODEL-ESCALATION-SPEC §10). */
23
+ export const COST_INCREASING_ENABLE_KEYS = new Set([
24
+ 'models.tierEscalation.enabled',
25
+ ]);
26
+ /**
27
+ * Extract the guard posture from a resolved config object.
28
+ *
29
+ * Covered surface (generic by design — a future guard is covered the moment
30
+ * it follows the `monitoring.<key>.enabled` convention, with no change here):
31
+ * - `monitoring.<key>.enabled` (boolean) → `monitoring.<key>.enabled`
32
+ * - `monitoring.<key>` (plain boolean) → `monitoring.<key>`
33
+ * - `scheduler.enabled` (boolean) → `scheduler.enabled`
34
+ * - `models.tierEscalation.{enabled,dryRun}`
35
+ */
36
+ export function extractGuardPosture(config) {
37
+ const posture = {};
38
+ if (!config || typeof config !== 'object')
39
+ return posture;
40
+ const cfg = config;
41
+ const monitoring = cfg.monitoring;
42
+ if (monitoring && typeof monitoring === 'object' && !Array.isArray(monitoring)) {
43
+ for (const [key, value] of Object.entries(monitoring)) {
44
+ if (typeof value === 'boolean') {
45
+ posture[`monitoring.${key}`] = value;
46
+ }
47
+ else if (value && typeof value === 'object' && !Array.isArray(value)) {
48
+ const enabled = value.enabled;
49
+ if (typeof enabled === 'boolean')
50
+ posture[`monitoring.${key}.enabled`] = enabled;
51
+ }
52
+ }
53
+ }
54
+ const scheduler = cfg.scheduler;
55
+ if (scheduler && typeof scheduler === 'object' && !Array.isArray(scheduler)) {
56
+ const enabled = scheduler.enabled;
57
+ if (typeof enabled === 'boolean')
58
+ posture['scheduler.enabled'] = enabled;
59
+ }
60
+ // Model-tier escalation (FABLE-MODEL-ESCALATION-SPEC §10): a COST-INCREASING
61
+ // enable gets the same visibility as a guard-disable, and a dryRun-off flip
62
+ // is the moment real swaps start — both are posture.
63
+ const models = cfg.models;
64
+ if (models && typeof models === 'object' && !Array.isArray(models)) {
65
+ const tierEscalation = models.tierEscalation;
66
+ if (tierEscalation && typeof tierEscalation === 'object' && !Array.isArray(tierEscalation)) {
67
+ const te = tierEscalation;
68
+ if (typeof te.enabled === 'boolean')
69
+ posture['models.tierEscalation.enabled'] = te.enabled;
70
+ if (typeof te.dryRun === 'boolean')
71
+ posture['models.tierEscalation.dryRun'] = te.dryRun;
72
+ }
73
+ }
74
+ return posture;
75
+ }
76
+ /**
77
+ * Diff two postures. Only keys present in BOTH snapshots can transition —
78
+ * a key appearing for the first time (new feature) or vanishing (config
79
+ * cleanup) is a shape change, not a guard flip, and raises nothing.
80
+ */
81
+ export function diffGuardPosture(prev, cur) {
82
+ const disabled = [];
83
+ const enabled = [];
84
+ for (const key of Object.keys(cur).sort()) {
85
+ if (!(key in prev))
86
+ continue;
87
+ if (prev[key] === true && cur[key] === false)
88
+ disabled.push(key);
89
+ else if (prev[key] === false && cur[key] === true)
90
+ enabled.push(key);
91
+ }
92
+ return { disabled, enabled };
93
+ }
94
+ export function guardPostureSnapshotPath(stateDir) {
95
+ return path.join(stateDir, 'state', 'guard-posture.json');
96
+ }
97
+ /** Read the tripwire's boot-time posture snapshot. null = absent/corrupt —
98
+ * callers degrade to `divergence: "snapshot-unavailable"`, never invent. */
99
+ export function readGuardPostureBootSnapshot(stateDir) {
100
+ try {
101
+ const parsed = JSON.parse(fs.readFileSync(guardPostureSnapshotPath(stateDir), 'utf-8'));
102
+ if (parsed && typeof parsed === 'object' && parsed.posture && typeof parsed.posture === 'object') {
103
+ return parsed;
104
+ }
105
+ return null;
106
+ }
107
+ catch {
108
+ // @silent-fallback-ok — absent or corrupt snapshot degrades to
109
+ // snapshot-unavailable honesty downstream; the tripwire repairs the file
110
+ // at next boot.
111
+ return null;
112
+ }
113
+ }
114
+ function deepMergeInto(target, source, depth = 0) {
115
+ for (const key of Object.keys(source)) {
116
+ if (depth < 64 &&
117
+ typeof target[key] === 'object' && target[key] !== null && !Array.isArray(target[key]) &&
118
+ typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
119
+ deepMergeInto(target[key], source[key], depth + 1);
120
+ }
121
+ else {
122
+ // Past the sanity depth a subtree is replaced wholesale — a config
123
+ // nested >64 levels is not a real agent config, and unbounded
124
+ // recursion on hostile input is a stack-overflow vector.
125
+ target[key] = structuredClone(source[key]);
126
+ }
127
+ }
128
+ }
129
+ function setConfigByPath(config, dottedPath, value) {
130
+ const keys = dottedPath.split('.');
131
+ let cur = config;
132
+ for (const key of keys.slice(0, -1)) {
133
+ const next = cur[key];
134
+ if (!next || typeof next !== 'object' || Array.isArray(next)) {
135
+ cur[key] = {};
136
+ }
137
+ cur = cur[key];
138
+ }
139
+ cur[keys[keys.length - 1]] = value;
140
+ }
141
+ /**
142
+ * Read the on-disk agent config ONCE and resolve it the way the server would:
143
+ * shared defaults (by agent type) + file deep-merged on top + every
144
+ * DEV_GATED_FEATURES `enabled` resolved via resolveDevAgentGate (their
145
+ * convention is to OMIT `enabled` and let the gate decide).
146
+ *
147
+ * EXACTLY ONE fs read of config.json per call — the endpoint calls this once
148
+ * per request (Tier-1 pinned), never per guard.
149
+ */
150
+ export function resolveGuardConfigSnapshot(projectDir, opts) {
151
+ const configPath = path.join(projectDir, '.instar', 'config.json');
152
+ let fileRaw = null;
153
+ let fileAbsent = true;
154
+ let readError;
155
+ try {
156
+ const text = fs.readFileSync(configPath, 'utf-8');
157
+ fileAbsent = false;
158
+ const parsed = JSON.parse(text);
159
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
160
+ fileRaw = parsed;
161
+ }
162
+ else {
163
+ readError = `config.json parsed to a non-object (${Array.isArray(parsed) ? 'array' : typeof parsed})`;
164
+ }
165
+ }
166
+ catch (err) {
167
+ const code = err?.code;
168
+ if (code === 'ENOENT') {
169
+ fileAbsent = true; // defaults-only snapshot — valid, not an error
170
+ }
171
+ else {
172
+ fileAbsent = false;
173
+ readError = err instanceof Error ? err.message : String(err);
174
+ }
175
+ }
176
+ const agentType = opts?.agentType ??
177
+ (fileRaw?.agentType === 'standalone' ? 'standalone' : 'managed-project');
178
+ const defaults = getInitDefaults(agentType);
179
+ const resolved = structuredClone(defaults);
180
+ if (fileRaw)
181
+ deepMergeInto(resolved, fileRaw);
182
+ // Dev-gated features deliberately omit `enabled` from defaults; the runtime
183
+ // resolves them via the dev-agent gate. Mirror that here so a dev-gated
184
+ // guard appears with its gate-resolved value (spec §2.1) — in BOTH the
185
+ // resolved view and the defaults baseline (the gate IS the default).
186
+ const gateSource = { developmentAgent: resolved.developmentAgent };
187
+ for (const feature of DEV_GATED_FEATURES) {
188
+ const explicit = getConfigByPath(resolved, feature.configPath);
189
+ const effective = resolveDevAgentGate(typeof explicit === 'boolean' ? explicit : undefined, gateSource);
190
+ setConfigByPath(resolved, feature.configPath, effective);
191
+ const explicitDefault = getConfigByPath(defaults, feature.configPath);
192
+ if (typeof explicitDefault !== 'boolean') {
193
+ setConfigByPath(defaults, feature.configPath, resolveDevAgentGate(undefined, gateSource));
194
+ }
195
+ }
196
+ return { resolved, defaults, fileAbsent, readError };
197
+ }
198
+ //# sourceMappingURL=guardPosture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardPosture.js","sourceRoot":"","sources":["../../src/monitoring/guardPosture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * guardPostureView — honest effective-state derivation + strict output
3
+ * projection for GET /guards (GUARD-POSTURE-ENDPOINT-SPEC §2.2).
4
+ *
5
+ * Pure logic, no I/O: callers hand in the one-read resolved-config snapshot,
6
+ * the tripwire's boot posture snapshot, and a GuardRegistry; this module
7
+ * derives one closed-vocabulary state per guard via the spec's NORMATIVE
8
+ * PRECEDENCE TABLE (first match wins) and emits ONLY the closed field set —
9
+ * the route never spreads source config/runtime objects (several guard
10
+ * config blocks carry operationally sensitive values; getters are untrusted
11
+ * producers, this projection is the authority).
12
+ */
13
+ import { type GuardManifestEntry } from './guardManifest.js';
14
+ import { type GuardPostureBootSnapshot, type ResolvedGuardConfigSnapshot } from './guardPosture.js';
15
+ import type { GuardRegistry, GuardRuntimeRead } from './GuardRegistry.js';
16
+ export type GuardEffectiveState = 'on-confirmed' | 'on-unverified' | 'on-stale' | 'on-dry-run' | 'off' | 'diverged-pending-restart' | 'errored' | 'missing' | 'off-runtime-divergent';
17
+ export type GuardOffClass = 'dark-default' | 'diverged-from-default' | null;
18
+ export type GuardDivergence = 'none' | 'diverged' | 'not-applicable' | 'snapshot-unavailable';
19
+ /** Staleness multiplier over a guard's self-declared cadence (spec §2.2, N=5). */
20
+ export declare const STALE_TICK_MULTIPLIER = 5;
21
+ /** The CLOSED projection — every field a /guards row may carry. Anything not
22
+ * named here never leaves the server (Tier-1 allowlist test). */
23
+ export interface GuardRuntimeProjection {
24
+ enabled: boolean;
25
+ dryRun?: boolean;
26
+ lastTickAt?: number;
27
+ tickAgeMs?: number;
28
+ stale?: boolean;
29
+ jobCount?: number;
30
+ pausedJobCount?: number;
31
+ }
32
+ export interface GuardRow {
33
+ key: string;
34
+ configEnabled: boolean | null;
35
+ defaultEnabled: boolean | null;
36
+ effective: GuardEffectiveState;
37
+ offClass: GuardOffClass;
38
+ divergence: GuardDivergence;
39
+ runtime: GuardRuntimeProjection | null;
40
+ runtimeReason?: 'not-instrumented' | 'status-error' | 'out-of-process' | 'not-registered';
41
+ /** Normalized getter-error message (errored state only). */
42
+ error?: string;
43
+ process: 'server' | 'lifeline';
44
+ }
45
+ export interface GuardsSummary {
46
+ onConfirmed: number;
47
+ onUnverified: number;
48
+ onStale: number;
49
+ onDryRun: number;
50
+ off: number;
51
+ offDeviant: number;
52
+ offDarkDefault: number;
53
+ divergedPendingRestart: number;
54
+ errored: number;
55
+ missing: number;
56
+ offRuntimeDivergent: number;
57
+ runtimeEnriched: string;
58
+ }
59
+ export interface GuardInventoryResult {
60
+ guards: GuardRow[];
61
+ summary: GuardsSummary;
62
+ }
63
+ declare const ROW_FIELD_ALLOWLIST: ReadonlySet<string>;
64
+ declare const RUNTIME_FIELD_ALLOWLIST: ReadonlySet<string>;
65
+ export { ROW_FIELD_ALLOWLIST, RUNTIME_FIELD_ALLOWLIST };
66
+ interface DeriveInput {
67
+ key: string;
68
+ manifest: GuardManifestEntry | undefined;
69
+ configEnabled: boolean | undefined;
70
+ defaultEnabled: boolean | undefined;
71
+ configDryRun: boolean | undefined;
72
+ bootValue: boolean | undefined;
73
+ bootSnapshotAvailable: boolean;
74
+ runtime: GuardRuntimeRead;
75
+ now: number;
76
+ }
77
+ /**
78
+ * The normative precedence table (spec §2.2) — ONE state per guard, first
79
+ * match wins:
80
+ * errored → missing → off-runtime-divergent → diverged-pending-restart →
81
+ * off → on-dry-run → on-stale → on-confirmed → on-unverified
82
+ */
83
+ export declare function deriveGuardRow(input: DeriveInput): GuardRow;
84
+ /**
85
+ * Assemble the full inventory: shared extractor (config-derived) ∪ declared
86
+ * manifest, deduped by key, each row derived through the precedence table.
87
+ */
88
+ export declare function buildGuardInventory(opts: {
89
+ snapshot: ResolvedGuardConfigSnapshot;
90
+ bootSnapshot: GuardPostureBootSnapshot | null;
91
+ registry: GuardRegistry;
92
+ now?: number;
93
+ }): GuardInventoryResult;
94
+ /** Compact posture block that rides the capacity heartbeat (spec §2.3).
95
+ * The wire shape lives in core/types.ts (GuardPostureSummary) so the
96
+ * heartbeat/pool layers don't import from monitoring; this alias keeps the
97
+ * spec's name for monitoring-side consumers. */
98
+ export type HeartbeatGuardPosture = import('../core/types.js').GuardPostureSummary;
99
+ export declare function buildHeartbeatPostureBlock(inventory: GuardInventoryResult, generatedAt: string): HeartbeatGuardPosture;
100
+ //# sourceMappingURL=guardPostureView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardPostureView.d.ts","sourceRoot":"","sources":["../../src/monitoring/guardPostureView.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,294 @@
1
+ /**
2
+ * guardPostureView — honest effective-state derivation + strict output
3
+ * projection for GET /guards (GUARD-POSTURE-ENDPOINT-SPEC §2.2).
4
+ *
5
+ * Pure logic, no I/O: callers hand in the one-read resolved-config snapshot,
6
+ * the tripwire's boot posture snapshot, and a GuardRegistry; this module
7
+ * derives one closed-vocabulary state per guard via the spec's NORMATIVE
8
+ * PRECEDENCE TABLE (first match wins) and emits ONLY the closed field set —
9
+ * the route never spreads source config/runtime objects (several guard
10
+ * config blocks carry operationally sensitive values; getters are untrusted
11
+ * producers, this projection is the authority).
12
+ */
13
+ import { GUARD_MANIFEST, } from './guardManifest.js';
14
+ import { getConfigByPath } from '../core/devGatedFeatures.js';
15
+ import { extractGuardPosture, } from './guardPosture.js';
16
+ /** Staleness multiplier over a guard's self-declared cadence (spec §2.2, N=5). */
17
+ export const STALE_TICK_MULTIPLIER = 5;
18
+ const ROW_FIELD_ALLOWLIST = new Set([
19
+ 'key', 'configEnabled', 'defaultEnabled', 'effective', 'offClass',
20
+ 'divergence', 'runtime', 'runtimeReason', 'error', 'process',
21
+ ]);
22
+ const RUNTIME_FIELD_ALLOWLIST = new Set([
23
+ 'enabled', 'dryRun', 'lastTickAt', 'tickAgeMs', 'stale', 'jobCount', 'pausedJobCount',
24
+ ]);
25
+ export { ROW_FIELD_ALLOWLIST, RUNTIME_FIELD_ALLOWLIST };
26
+ function asBool(v) {
27
+ return typeof v === 'boolean' ? v : undefined;
28
+ }
29
+ /**
30
+ * The normative precedence table (spec §2.2) — ONE state per guard, first
31
+ * match wins:
32
+ * errored → missing → off-runtime-divergent → diverged-pending-restart →
33
+ * off → on-dry-run → on-stale → on-confirmed → on-unverified
34
+ */
35
+ export function deriveGuardRow(input) {
36
+ const { key, manifest, runtime, now } = input;
37
+ const isCodeDefault = manifest?.kind === 'code-default';
38
+ const configEnabled = input.configEnabled ?? (isCodeDefault ? manifest.defaultEnabled : undefined);
39
+ const defaultEnabled = input.defaultEnabled ?? manifest?.defaultEnabled;
40
+ const process = manifest?.process ?? 'server';
41
+ // ── Disk-vs-boot divergence classification (input to two states below) ──
42
+ let divergence;
43
+ if (isCodeDefault) {
44
+ divergence = 'not-applicable';
45
+ }
46
+ else if (manifest?.liveConfig) {
47
+ // Component re-reads config per use — a disk change is already live, the
48
+ // diverged-pending-restart state would lie in the false-positive direction.
49
+ divergence = 'none';
50
+ }
51
+ else if (!input.bootSnapshotAvailable || input.bootValue === undefined) {
52
+ // Absent snapshot or older-inventory snapshot (key missing): suppressed
53
+ // AND flagged — degraded honestly, never silently clean.
54
+ divergence = 'snapshot-unavailable';
55
+ }
56
+ else if (configEnabled !== undefined && input.bootValue !== configEnabled) {
57
+ divergence = 'diverged';
58
+ }
59
+ else {
60
+ divergence = 'none';
61
+ }
62
+ // Runtime projection (closed fields only).
63
+ let runtimeProjection = null;
64
+ let runtimeReason;
65
+ let error;
66
+ if (process === 'lifeline') {
67
+ // Out-of-process guards are config-derived ONLY (spec §2.1): the sync
68
+ // in-memory getter contract cannot cross processes.
69
+ runtimeReason = 'out-of-process';
70
+ }
71
+ else if (runtime.kind === 'ok') {
72
+ const s = runtime.status;
73
+ runtimeProjection = { enabled: s.enabled };
74
+ if (typeof s.dryRun === 'boolean')
75
+ runtimeProjection.dryRun = s.dryRun;
76
+ if (typeof s.lastTickAt === 'number') {
77
+ runtimeProjection.lastTickAt = s.lastTickAt;
78
+ if (s.lastTickAt > 0)
79
+ runtimeProjection.tickAgeMs = Math.max(0, now - s.lastTickAt);
80
+ }
81
+ if (typeof s.jobCount === 'number')
82
+ runtimeProjection.jobCount = s.jobCount;
83
+ if (typeof s.pausedJobCount === 'number')
84
+ runtimeProjection.pausedJobCount = s.pausedJobCount;
85
+ }
86
+ else if (runtime.kind === 'error') {
87
+ runtimeReason = 'status-error';
88
+ error = runtime.message;
89
+ }
90
+ else {
91
+ runtimeReason = manifest?.expectRuntime ? 'not-registered' : 'not-instrumented';
92
+ }
93
+ // Staleness only applies where the guard self-declares a cadence.
94
+ let stale = false;
95
+ if (runtime.kind === 'ok' &&
96
+ runtime.status.enabled &&
97
+ manifest?.expectedTickMs !== undefined) {
98
+ const lastTickAt = runtime.status.lastTickAt;
99
+ if (!lastTickAt || lastTickAt <= 0) {
100
+ stale = true; // constructed-but-never-ticking reports stale, never "on"
101
+ }
102
+ else if (now - lastTickAt > STALE_TICK_MULTIPLIER * manifest.expectedTickMs) {
103
+ stale = true;
104
+ }
105
+ }
106
+ if (runtimeProjection && manifest?.expectedTickMs !== undefined && runtime.kind === 'ok' && runtime.status.enabled) {
107
+ runtimeProjection.stale = stale;
108
+ }
109
+ const dryRun = (runtime.kind === 'ok' ? asBool(runtime.status.dryRun) : undefined) ?? input.configDryRun ?? false;
110
+ // ── Precedence table — first match wins ──
111
+ let effective;
112
+ let offClass = null;
113
+ const diskDivergenceDetected = divergence === 'diverged';
114
+ const noDetectedDiskDivergence = !diskDivergenceDetected; // snapshot-unavailable counts as none
115
+ if (runtime.kind === 'error') {
116
+ effective = 'errored';
117
+ }
118
+ else if (manifest?.expectRuntime === true &&
119
+ process === 'server' &&
120
+ configEnabled === true &&
121
+ runtime.kind === 'unregistered' &&
122
+ input.bootValue !== false) {
123
+ // Declared for this host, config says on, but no runtime registered at
124
+ // boot (crash-before-register / unconfigured adapter): a STATE, never a
125
+ // silent omission. The `bootValue !== false` clause keeps this honest: a
126
+ // guard that was OFF at boot and flipped on-disk since was never expected
127
+ // to construct — that case falls through to diverged-pending-restart,
128
+ // which describes it truthfully (missing would be a false crash alarm).
129
+ effective = 'missing';
130
+ }
131
+ else if (configEnabled === true &&
132
+ runtime.kind === 'ok' &&
133
+ runtime.status.enabled === false &&
134
+ noDetectedDiskDivergence) {
135
+ // The in-memory load-shed class: config says ON, disk matches boot, but
136
+ // the live runtime self-reports off — the strongest "the config is lying
137
+ // to you" signal; never folds into on-unverified.
138
+ effective = 'off-runtime-divergent';
139
+ }
140
+ else if (diskDivergenceDetected) {
141
+ effective = 'diverged-pending-restart';
142
+ }
143
+ else if (configEnabled === false) {
144
+ effective = 'off';
145
+ offClass = defaultEnabled === false ? 'dark-default' : 'diverged-from-default';
146
+ }
147
+ else if (dryRun && configEnabled === true) {
148
+ effective = 'on-dry-run'; // watching but toothless; stale stays visible in the runtime block
149
+ }
150
+ else if (stale) {
151
+ effective = 'on-stale';
152
+ }
153
+ else if (runtime.kind === 'ok' && runtime.status.enabled) {
154
+ effective = 'on-confirmed';
155
+ }
156
+ else {
157
+ // Config on, no live runtime surface. NEVER counted or rendered as
158
+ // confirmed-on — a guard that crashed mid-init lands here, and painting
159
+ // it green is the Mini bug with extra steps.
160
+ effective = 'on-unverified';
161
+ }
162
+ const row = {
163
+ key,
164
+ configEnabled: configEnabled ?? null,
165
+ defaultEnabled: defaultEnabled ?? null,
166
+ effective,
167
+ offClass,
168
+ divergence,
169
+ runtime: runtimeProjection,
170
+ process,
171
+ };
172
+ if (runtimeReason)
173
+ row.runtimeReason = runtimeReason;
174
+ if (error)
175
+ row.error = error;
176
+ return row;
177
+ }
178
+ /**
179
+ * Assemble the full inventory: shared extractor (config-derived) ∪ declared
180
+ * manifest, deduped by key, each row derived through the precedence table.
181
+ */
182
+ export function buildGuardInventory(opts) {
183
+ const now = opts.now ?? Date.now();
184
+ const extractedCurrent = extractGuardPosture(opts.snapshot.resolved);
185
+ const extractedDefaults = extractGuardPosture(opts.snapshot.defaults);
186
+ const manifestMap = new Map();
187
+ for (const entry of GUARD_MANIFEST)
188
+ manifestMap.set(entry.key, entry);
189
+ const keys = [...new Set([...Object.keys(extractedCurrent), ...manifestMap.keys()])].sort();
190
+ const guards = [];
191
+ for (const key of keys) {
192
+ const manifest = manifestMap.get(key);
193
+ let configEnabled = asBool(extractedCurrent[key]);
194
+ let defaultEnabled = asBool(extractedDefaults[key]);
195
+ if (configEnabled === undefined && manifest?.configPath) {
196
+ configEnabled = asBool(getConfigByPath(opts.snapshot.resolved, manifest.configPath));
197
+ }
198
+ if (defaultEnabled === undefined && manifest?.configPath) {
199
+ defaultEnabled = asBool(getConfigByPath(opts.snapshot.defaults, manifest.configPath));
200
+ }
201
+ if (defaultEnabled === undefined && manifest)
202
+ defaultEnabled = manifest.defaultEnabled;
203
+ // The resolved snapshot normally contains every default key (defaults are
204
+ // merged in), but a degraded/partial snapshot must still yield the
205
+ // default-resolved state — a guard can never drop out of the inventory.
206
+ if (configEnabled === undefined)
207
+ configEnabled = defaultEnabled;
208
+ const configDryRun = manifest?.dryRunConfigPath
209
+ ? asBool(getConfigByPath(opts.snapshot.resolved, manifest.dryRunConfigPath))
210
+ : undefined;
211
+ const bootPosture = opts.bootSnapshot?.posture;
212
+ guards.push(deriveGuardRow({
213
+ key,
214
+ manifest,
215
+ configEnabled,
216
+ defaultEnabled,
217
+ configDryRun,
218
+ bootValue: bootPosture ? asBool(bootPosture[key]) : undefined,
219
+ bootSnapshotAvailable: !!bootPosture,
220
+ runtime: opts.registry.read(key),
221
+ now,
222
+ }));
223
+ }
224
+ const summary = {
225
+ onConfirmed: 0, onUnverified: 0, onStale: 0, onDryRun: 0,
226
+ off: 0, offDeviant: 0, offDarkDefault: 0,
227
+ divergedPendingRestart: 0, errored: 0, missing: 0, offRuntimeDivergent: 0,
228
+ runtimeEnriched: '',
229
+ };
230
+ let enriched = 0;
231
+ for (const g of guards) {
232
+ if (g.runtime)
233
+ enriched++;
234
+ switch (g.effective) {
235
+ case 'on-confirmed':
236
+ summary.onConfirmed++;
237
+ break;
238
+ case 'on-unverified':
239
+ summary.onUnverified++;
240
+ break;
241
+ case 'on-stale':
242
+ summary.onStale++;
243
+ break;
244
+ case 'on-dry-run':
245
+ summary.onDryRun++;
246
+ break;
247
+ case 'off':
248
+ summary.off++;
249
+ if (g.offClass === 'diverged-from-default')
250
+ summary.offDeviant++;
251
+ else
252
+ summary.offDarkDefault++;
253
+ break;
254
+ case 'diverged-pending-restart':
255
+ summary.divergedPendingRestart++;
256
+ break;
257
+ case 'errored':
258
+ summary.errored++;
259
+ break;
260
+ case 'missing':
261
+ summary.missing++;
262
+ break;
263
+ case 'off-runtime-divergent':
264
+ summary.offRuntimeDivergent++;
265
+ break;
266
+ }
267
+ }
268
+ summary.runtimeEnriched = `${enriched}/${guards.length}`;
269
+ return { guards, summary };
270
+ }
271
+ export function buildHeartbeatPostureBlock(inventory, generatedAt) {
272
+ const offDeviantKeys = inventory.guards
273
+ .filter(g => g.effective === 'off' && g.offClass === 'diverged-from-default')
274
+ .map(g => g.key);
275
+ const offRuntimeDivergentKeys = inventory.guards
276
+ .filter(g => g.effective === 'off-runtime-divergent')
277
+ .map(g => g.key);
278
+ const s = inventory.summary;
279
+ return {
280
+ onConfirmed: s.onConfirmed,
281
+ onUnverified: s.onUnverified,
282
+ onStale: s.onStale,
283
+ onDryRun: s.onDryRun,
284
+ offDeviant: s.offDeviant,
285
+ offDeviantKeys,
286
+ offRuntimeDivergent: s.offRuntimeDivergent,
287
+ offRuntimeDivergentKeys,
288
+ divergedPendingRestart: s.divergedPendingRestart,
289
+ errored: s.errored,
290
+ missing: s.missing,
291
+ generatedAt,
292
+ };
293
+ }
294
+ //# sourceMappingURL=guardPostureView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guardPostureView.js","sourceRoot":"","sources":["../../src/monitoring/guardPostureView.ts"],"names":[],"mappings":"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"}