@ashlr/hub 3.2.6 → 3.3.0
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/CHANGELOG.md +290 -0
- package/README.md +4 -1
- package/dist/build-identity.json +2 -2
- package/dist/cli/activation.d.ts +41 -0
- package/dist/cli/activation.js +485 -0
- package/dist/cli/activation.js.map +1 -0
- package/dist/cli/audit.js +18 -0
- package/dist/cli/audit.js.map +1 -1
- package/dist/cli/backlog.d.ts +0 -5
- package/dist/cli/backlog.js +18 -0
- package/dist/cli/backlog.js.map +1 -1
- package/dist/cli/comms.js +20 -0
- package/dist/cli/comms.js.map +1 -1
- package/dist/cli/completions.d.ts +6 -1
- package/dist/cli/completions.js +37 -11
- package/dist/cli/completions.js.map +1 -1
- package/dist/cli/conductor-permit.d.ts +1 -0
- package/dist/cli/conductor-permit.js +122 -0
- package/dist/cli/conductor-permit.js.map +1 -0
- package/dist/cli/daemon.js +10 -3
- package/dist/cli/daemon.js.map +1 -1
- package/dist/cli/demo.d.ts +0 -27
- package/dist/cli/demo.js +17 -0
- package/dist/cli/demo.js.map +1 -1
- package/dist/cli/goals.d.ts +2 -0
- package/dist/cli/goals.js +90 -5
- package/dist/cli/goals.js.map +1 -1
- package/dist/cli/help.js +21 -3
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/inbox.d.ts +14 -2
- package/dist/cli/inbox.js +137 -23
- package/dist/cli/inbox.js.map +1 -1
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +16 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/loop.js +26 -5
- package/dist/cli/loop.js.map +1 -1
- package/dist/cli/onboard.d.ts +0 -13
- package/dist/cli/onboard.js +20 -0
- package/dist/cli/onboard.js.map +1 -1
- package/dist/cli/resources.js +15 -0
- package/dist/cli/resources.js.map +1 -1
- package/dist/cli/run.js +1 -1
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/sandbox.js +43 -0
- package/dist/cli/sandbox.js.map +1 -1
- package/dist/cli/tui.d.ts +0 -6
- package/dist/cli/tui.js +14 -0
- package/dist/cli/tui.js.map +1 -1
- package/dist/core/comms/elon-dialogue.js +16 -7
- package/dist/core/comms/elon-dialogue.js.map +1 -1
- package/dist/core/config.js +70 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/daemon/activation-permit.d.ts +357 -33
- package/dist/core/daemon/activation-permit.js +1585 -183
- package/dist/core/daemon/activation-permit.js.map +1 -1
- package/dist/core/daemon/goal-conductor-permit-operator.d.ts +75 -0
- package/dist/core/daemon/goal-conductor-permit-operator.js +842 -0
- package/dist/core/daemon/goal-conductor-permit-operator.js.map +1 -0
- package/dist/core/daemon/loop.d.ts +13 -1
- package/dist/core/daemon/loop.js +294 -29
- package/dist/core/daemon/loop.js.map +1 -1
- package/dist/core/daemon/runtime-activation-resident-start-protocol.d.ts +141 -0
- package/dist/core/daemon/runtime-activation-resident-start-protocol.js +462 -0
- package/dist/core/daemon/runtime-activation-resident-start-protocol.js.map +1 -0
- package/dist/core/daemon/runtime-activation-resident-start-runtime.d.ts +27 -0
- package/dist/core/daemon/runtime-activation-resident-start-runtime.js +28 -0
- package/dist/core/daemon/runtime-activation-resident-start-runtime.js.map +1 -0
- package/dist/core/daemon/runtime-activation-stopped-consumer.d.ts +139 -0
- package/dist/core/daemon/runtime-activation-stopped-consumer.js +995 -0
- package/dist/core/daemon/runtime-activation-stopped-consumer.js.map +1 -0
- package/dist/core/daemon/runtime-activation-stopped-runtime.d.ts +36 -0
- package/dist/core/daemon/runtime-activation-stopped-runtime.js +134 -0
- package/dist/core/daemon/runtime-activation-stopped-runtime.js.map +1 -0
- package/dist/core/daemon/runtime-activation-transaction.d.ts +41 -17
- package/dist/core/daemon/runtime-activation-transaction.js +80 -11
- package/dist/core/daemon/runtime-activation-transaction.js.map +1 -1
- package/dist/core/daemon/runtime-release-dependency-inventory.js +1 -0
- package/dist/core/daemon/runtime-release-dependency-inventory.js.map +1 -1
- package/dist/core/daemon/service-install-authority.d.ts +0 -4
- package/dist/core/daemon/service-install-authority.js +18 -3
- package/dist/core/daemon/service-install-authority.js.map +1 -1
- package/dist/core/dashboard.d.ts +10 -0
- package/dist/core/dashboard.js +103 -28
- package/dist/core/dashboard.js.map +1 -1
- package/dist/core/effective-config.js +7 -0
- package/dist/core/effective-config.js.map +1 -1
- package/dist/core/fleet/automerge-pass.js +33 -0
- package/dist/core/fleet/automerge-pass.js.map +1 -1
- package/dist/core/fleet/decisions-ledger.js +35 -12
- package/dist/core/fleet/decisions-ledger.js.map +1 -1
- package/dist/core/fleet/external-skill-git-capture.js +9 -1
- package/dist/core/fleet/external-skill-git-capture.js.map +1 -1
- package/dist/core/fleet/judge-decision-metadata.d.ts +8 -1
- package/dist/core/fleet/judge-decision-metadata.js +14 -1
- package/dist/core/fleet/judge-decision-metadata.js.map +1 -1
- package/dist/core/fleet/manager.d.ts +15 -1
- package/dist/core/fleet/manager.js +108 -30
- package/dist/core/fleet/manager.js.map +1 -1
- package/dist/core/fleet/post-merge-credit.d.ts +134 -9
- package/dist/core/fleet/post-merge-credit.js +350 -10
- package/dist/core/fleet/post-merge-credit.js.map +1 -1
- package/dist/core/fleet/quota.d.ts +74 -7
- package/dist/core/fleet/quota.js +688 -34
- package/dist/core/fleet/quota.js.map +1 -1
- package/dist/core/fleet/self-improve.d.ts +34 -1
- package/dist/core/fleet/self-improve.js +106 -1
- package/dist/core/fleet/self-improve.js.map +1 -1
- package/dist/core/fleet/skill-library.d.ts +21 -2
- package/dist/core/fleet/skill-library.js +54 -12
- package/dist/core/fleet/skill-library.js.map +1 -1
- package/dist/core/fleet/status.js +7 -5
- package/dist/core/fleet/status.js.map +1 -1
- package/dist/core/fleet/worked-ledger.d.ts +22 -0
- package/dist/core/fleet/worked-ledger.js +32 -0
- package/dist/core/fleet/worked-ledger.js.map +1 -1
- package/dist/core/foundry/automerge-scope-policy.d.ts +2 -2
- package/dist/core/foundry/automerge-scope-policy.js +9 -2
- package/dist/core/foundry/automerge-scope-policy.js.map +1 -1
- package/dist/core/goals/advance.js +34 -5
- package/dist/core/goals/advance.js.map +1 -1
- package/dist/core/goals/conductor-quota.d.ts +38 -0
- package/dist/core/goals/conductor-quota.js +110 -0
- package/dist/core/goals/conductor-quota.js.map +1 -0
- package/dist/core/goals/conductor-target.d.ts +24 -0
- package/dist/core/goals/conductor-target.js +35 -0
- package/dist/core/goals/conductor-target.js.map +1 -0
- package/dist/core/goals/conductor.d.ts +15 -0
- package/dist/core/goals/conductor.js +116 -9
- package/dist/core/goals/conductor.js.map +1 -1
- package/dist/core/goals/store.d.ts +29 -5
- package/dist/core/goals/store.js +197 -30
- package/dist/core/goals/store.js.map +1 -1
- package/dist/core/goals/timestamp-repair.d.ts +50 -0
- package/dist/core/goals/timestamp-repair.js +740 -0
- package/dist/core/goals/timestamp-repair.js.map +1 -0
- package/dist/core/inbox/apply.js +5 -2
- package/dist/core/inbox/apply.js.map +1 -1
- package/dist/core/inbox/merge.d.ts +94 -1
- package/dist/core/inbox/merge.js +349 -16
- package/dist/core/inbox/merge.js.map +1 -1
- package/dist/core/integrations/github.d.ts +2 -0
- package/dist/core/integrations/github.js +2 -1
- package/dist/core/integrations/github.js.map +1 -1
- package/dist/core/integrations/pulse-sync.js +13 -4
- package/dist/core/integrations/pulse-sync.js.map +1 -1
- package/dist/core/learn/reflect.d.ts +42 -4
- package/dist/core/learn/reflect.js +56 -5
- package/dist/core/learn/reflect.js.map +1 -1
- package/dist/core/run/best-of-n.d.ts +18 -0
- package/dist/core/run/best-of-n.js +163 -18
- package/dist/core/run/best-of-n.js.map +1 -1
- package/dist/core/run/engines.d.ts +8 -0
- package/dist/core/run/engines.js +9 -1
- package/dist/core/run/engines.js.map +1 -1
- package/dist/core/run/learned-router.js +28 -3
- package/dist/core/run/learned-router.js.map +1 -1
- package/dist/core/run/orchestrator.d.ts +7 -2
- package/dist/core/run/orchestrator.js +140 -60
- package/dist/core/run/orchestrator.js.map +1 -1
- package/dist/core/strategy/goal-planner.js +7 -1
- package/dist/core/strategy/goal-planner.js.map +1 -1
- package/dist/core/swarm/planner.d.ts +2 -2
- package/dist/core/swarm/planner.js +52 -5
- package/dist/core/swarm/planner.js.map +1 -1
- package/dist/core/swarm/rollback.d.ts +11 -0
- package/dist/core/swarm/rollback.js +54 -0
- package/dist/core/swarm/rollback.js.map +1 -1
- package/dist/core/swarm/runner.js +123 -11
- package/dist/core/swarm/runner.js.map +1 -1
- package/dist/core/types.d.ts +139 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/web/api.js +105 -7
- package/dist/core/web/api.js.map +1 -1
- package/dist/core/web/control.d.ts +20 -0
- package/dist/core/web/control.js +49 -34
- package/dist/core/web/control.js.map +1 -1
- package/dist/core/web/fleet-status-cache.d.ts +68 -0
- package/dist/core/web/fleet-status-cache.js +120 -0
- package/dist/core/web/fleet-status-cache.js.map +1 -0
- package/dist/core/web/public/next/assets/index-CY0U241s.css +1 -0
- package/dist/core/web/public/next/assets/index-Ct0mf8n4.js +69 -0
- package/dist/core/web/public/next/assets/index-Ct0mf8n4.js.map +1 -0
- package/dist/core/web/public/next/index.html +15 -0
- package/dist/release-dependency-inventory.json +1 -1
- package/dist/tui/app.js +2 -2
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/render.d.ts +2 -0
- package/dist/tui/render.js +162 -4
- package/dist/tui/render.js.map +1 -1
- package/docs/RUNTIME_ACTIVATION_AUTHORITY.md +126 -21
- package/docs/contracts/CONTRACT-M521.md +102 -0
- package/package.json +20 -3
- package/schema/config.schema.json +800 -5
- package/node_modules/which/CHANGELOG.md +0 -166
|
@@ -1,15 +1,84 @@
|
|
|
1
1
|
import { type KeyObject } from 'node:crypto';
|
|
2
2
|
import { type BuildIdentity } from '../build-identity.js';
|
|
3
3
|
import type { AshlrConfig } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* M461 → M470 daemon activation authority.
|
|
6
|
+
*
|
|
7
|
+
* The default for anyone who has not explicitly run `ashlr activation init`
|
|
8
|
+
* is EXACTLY today's behavior: every guard denies, with the same reasons as
|
|
9
|
+
* before. Authority only exists once an operator:
|
|
10
|
+
*
|
|
11
|
+
* 1. Runs `ashlr activation init` — generates an Ed25519 keypair on this
|
|
12
|
+
* machine (private key never leaves it) and registers the public half
|
|
13
|
+
* as a trust root in ~/.ashlr/activation/trust-roots.json (0600, dir
|
|
14
|
+
* 0700, owned by the operator's uid — checked on every read).
|
|
15
|
+
* 2. Runs `ashlr activation grant <scope...>` — signs and mints either a
|
|
16
|
+
* single-use activation PERMIT (scopes: once, resident) consumed by
|
|
17
|
+
* `daemon start`, or a standing, expiring GRANT (scopes: residentStanding,
|
|
18
|
+
* conductor, install, automerge, repair, deploy) checked on every call to
|
|
19
|
+
* the corresponding guard.
|
|
20
|
+
*
|
|
21
|
+
* `resident` is grantable BOTH ways, and both forms remain live:
|
|
22
|
+
* - one-shot `resident` permit: fixed 2-minute window, requires a human to
|
|
23
|
+
* run `grant` immediately before `daemon start`. Unusable after a reboot
|
|
24
|
+
* with nobody present.
|
|
25
|
+
* - standing `residentStanding` grant: up to the normal 30-day cap, checked
|
|
26
|
+
* at resident-daemon startup instead of requiring a fresh permit — this is
|
|
27
|
+
* what lets a launchd/systemd/Task-Scheduler-triggered restart authorize
|
|
28
|
+
* itself with no human in the loop. `daemon start` (resident mode) tries
|
|
29
|
+
* the standing grant first and falls back to the one-shot permit path
|
|
30
|
+
* unchanged, so an operator who never grants `residentStanding` sees
|
|
31
|
+
* EXACTLY today's one-shot-only behavior.
|
|
32
|
+
*
|
|
33
|
+
* Both permits and grants are Ed25519-signed, scoped, expiring, and
|
|
34
|
+
* independently revocable (`ashlr activation revoke`). Every init / grant /
|
|
35
|
+
* revoke / consume / denial writes an audit row via ../sandbox/audit.js so
|
|
36
|
+
* an operator can answer "who activated this fleet, when, with what scope."
|
|
37
|
+
*
|
|
38
|
+
* Revocation of a standing grant is file-based: it stops the NEXT
|
|
39
|
+
* authorization check, immediately. For `residentStanding` specifically it is
|
|
40
|
+
* stronger than that — because standing grants are not single-use (unlike the
|
|
41
|
+
* one-shot capability, which a resident loop must consume exactly once, see
|
|
42
|
+
* `tick()`'s `activationScope` handling in ../loop.ts), a resident daemon that
|
|
43
|
+
* started off a standing grant re-checks it on every tick and stops at the
|
|
44
|
+
* next one if the grant is revoked, expired, or its trust root is revoked —
|
|
45
|
+
* not just at the next `daemon start`. It cannot interrupt a tick already in
|
|
46
|
+
* flight.
|
|
47
|
+
*
|
|
48
|
+
* File loading fails CLOSED on every ambiguity: missing, unreadable, wrong
|
|
49
|
+
* permissions, wrong owner, symlinked, malformed, or non-canonically
|
|
50
|
+
* encoded trust-root/grant/permit files are all treated as "no authority" —
|
|
51
|
+
* never as "trust everything." Windows is denied outright: node:fs chmod()
|
|
52
|
+
* on Windows does not restrict per-user read access on NTFS (it only
|
|
53
|
+
* toggles the read-only attribute), so the "reject world/group-readable
|
|
54
|
+
* private files" invariant this module depends on cannot be enforced there.
|
|
55
|
+
*/
|
|
4
56
|
declare const POLICY_VERSION = "m461-proposal-once-v1";
|
|
57
|
+
/** Hard cap on any standing grant's validity window (30 days). */
|
|
58
|
+
export declare const MAX_STANDING_GRANT_VALIDITY_MS: number;
|
|
59
|
+
/** Default TTL `ashlr activation grant` uses when --ttl is not given (24h). */
|
|
60
|
+
export declare const DEFAULT_STANDING_GRANT_VALIDITY_MS: number;
|
|
5
61
|
declare const capabilityBrand: unique symbol;
|
|
62
|
+
/** Every independently grantable scope key, in canonical order. Used by the CLI to validate `grant`/status output. */
|
|
63
|
+
export declare const DAEMON_ACTIVATION_SCOPE_KEYS: readonly ["once", "resident", "residentStanding", "conductor", "automerge", "repair", "deploy", "install", "proposalOnly"];
|
|
64
|
+
declare const SCOPE_KEYS: readonly ["once", "resident", "residentStanding", "conductor", "automerge", "repair", "deploy", "install", "proposalOnly"];
|
|
65
|
+
export type DaemonActivationScopeKey = typeof SCOPE_KEYS[number];
|
|
66
|
+
/** A real, independently grantable capability set. Unknown fields are rejected. */
|
|
67
|
+
export type DaemonActivationGrantScope = {
|
|
68
|
+
[K in DaemonActivationScopeKey]: boolean;
|
|
69
|
+
};
|
|
70
|
+
/** All-false scope — the base every CLI `grant` invocation flips bits on top of. */
|
|
71
|
+
export declare const EMPTY_DAEMON_ACTIVATION_SCOPE: DaemonActivationGrantScope;
|
|
6
72
|
/**
|
|
7
73
|
* Runtime authority is nominal and process-local. Objects that merely match
|
|
8
|
-
* this public shape are rejected by isDaemonActivationCapability().
|
|
74
|
+
* this public shape are rejected by isDaemonActivationCapability(). `scope`
|
|
75
|
+
* is readable without consuming the capability — only isDaemonActivationCapability()
|
|
76
|
+
* consumes the single-use claim.
|
|
9
77
|
*/
|
|
10
78
|
export interface DaemonActivationCapability {
|
|
11
79
|
readonly kind: 'proposal-once';
|
|
12
80
|
readonly permitId: string;
|
|
81
|
+
readonly scope: DaemonActivationGrantScope;
|
|
13
82
|
readonly [capabilityBrand]: true;
|
|
14
83
|
}
|
|
15
84
|
export interface DaemonActivationOptions {
|
|
@@ -27,6 +96,16 @@ export interface DaemonActivationPermitResult {
|
|
|
27
96
|
receiptPath?: string;
|
|
28
97
|
capability?: DaemonActivationCapability;
|
|
29
98
|
configSnapshot?: AshlrConfig;
|
|
99
|
+
/**
|
|
100
|
+
* Present only when authorized via a standing `residentStanding` grant
|
|
101
|
+
* rather than a one-shot permit. Standing grants are not single-use, so
|
|
102
|
+
* this scope is handed to the caller directly — there is no WeakMap
|
|
103
|
+
* capability to consume, and none of `isDaemonActivationCapability`'s
|
|
104
|
+
* one-shot semantics apply to it.
|
|
105
|
+
*/
|
|
106
|
+
scope?: DaemonActivationGrantScope;
|
|
107
|
+
/** Present only when `scope` is, so callers can re-check liveness per use. */
|
|
108
|
+
grantId?: string;
|
|
30
109
|
}
|
|
31
110
|
export interface DaemonActivationReadiness {
|
|
32
111
|
schemaVersion: 1;
|
|
@@ -35,17 +114,38 @@ export interface DaemonActivationReadiness {
|
|
|
35
114
|
sourceState: 'healthy' | 'degraded';
|
|
36
115
|
state: 'ready' | 'blocked' | 'degraded';
|
|
37
116
|
commandEligible: boolean;
|
|
38
|
-
requestedShape: 'proposal-once';
|
|
117
|
+
requestedShape: 'proposal-once' | 'resident';
|
|
39
118
|
trustRootCount: number;
|
|
40
|
-
residentAuthorized:
|
|
41
|
-
|
|
42
|
-
|
|
119
|
+
residentAuthorized: boolean;
|
|
120
|
+
/** Whether a currently valid standing `residentStanding` grant exists, independent of any pending one-shot permit. */
|
|
121
|
+
residentStandingAuthorized: boolean;
|
|
122
|
+
installAuthorized: boolean;
|
|
123
|
+
repairAuthorized: boolean;
|
|
43
124
|
reason: string;
|
|
44
125
|
}
|
|
45
126
|
export interface DaemonActivationTrustRoot {
|
|
46
127
|
keyId: string;
|
|
47
128
|
publicKeyPem: string;
|
|
48
129
|
}
|
|
130
|
+
/** Full operator-owned trust-root record, incl. mutable local revocation state. */
|
|
131
|
+
export interface DaemonActivationTrustRootRecord extends DaemonActivationTrustRoot {
|
|
132
|
+
createdAt: string;
|
|
133
|
+
/** Mutable, operator-set, NOT part of any signature. Non-null = revoked, immediately. */
|
|
134
|
+
revokedAt: string | null;
|
|
135
|
+
label: string;
|
|
136
|
+
}
|
|
137
|
+
/** A signed, expiring, independently revocable standing capability grant. */
|
|
138
|
+
export interface DaemonActivationGrantRecord {
|
|
139
|
+
schemaVersion: 1;
|
|
140
|
+
grantId: string;
|
|
141
|
+
keyId: string;
|
|
142
|
+
issuedAt: string;
|
|
143
|
+
expiresAt: string;
|
|
144
|
+
scope: DaemonActivationGrantScope;
|
|
145
|
+
signature: string;
|
|
146
|
+
/** Mutable, operator-set, NOT part of the signature. Non-null = revoked, immediately. */
|
|
147
|
+
revokedAt: string | null;
|
|
148
|
+
}
|
|
49
149
|
export interface DaemonActivationFileBinding {
|
|
50
150
|
path: string;
|
|
51
151
|
sha256: string;
|
|
@@ -69,20 +169,7 @@ export interface DaemonActivationPermitPayload {
|
|
|
69
169
|
keyId: string;
|
|
70
170
|
issuedAt: string;
|
|
71
171
|
expiresAt: string;
|
|
72
|
-
scope:
|
|
73
|
-
action: 'daemon-proposal-once';
|
|
74
|
-
once: true;
|
|
75
|
-
dryRun: false;
|
|
76
|
-
resident: false;
|
|
77
|
-
drain: false;
|
|
78
|
-
drainLimit: null;
|
|
79
|
-
proposalOnly: true;
|
|
80
|
-
automerge: false;
|
|
81
|
-
repair: false;
|
|
82
|
-
deploy: false;
|
|
83
|
-
install: false;
|
|
84
|
-
selfTarget: false;
|
|
85
|
-
};
|
|
172
|
+
scope: DaemonActivationGrantScope;
|
|
86
173
|
bindings: {
|
|
87
174
|
configDigest: string;
|
|
88
175
|
buildIdentity: BuildIdentity;
|
|
@@ -103,6 +190,14 @@ export interface DaemonActivationPermitVerification {
|
|
|
103
190
|
reason: string;
|
|
104
191
|
permitId?: string;
|
|
105
192
|
payloadDigest?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Populated only when reason === 'permit-runtime-binding-mismatch': the
|
|
195
|
+
* top-level binding field names (of DaemonActivationPermitPayload.bindings)
|
|
196
|
+
* whose signed value differs from the current runtime value. A fail-closed
|
|
197
|
+
* gate that can't say WHICH binding differed is very hard to operate — this
|
|
198
|
+
* turns the single opaque reason code into an actionable diagnostic.
|
|
199
|
+
*/
|
|
200
|
+
mismatchedBindings?: readonly string[];
|
|
106
201
|
}
|
|
107
202
|
export interface DaemonActivationPermitTestConsumerOptions {
|
|
108
203
|
trustRoots: readonly DaemonActivationTrustRoot[];
|
|
@@ -114,20 +209,8 @@ export interface DaemonActivationPermitTestInspectionOptions {
|
|
|
114
209
|
context: DaemonActivationRuntimeContext;
|
|
115
210
|
platform?: NodeJS.Platform;
|
|
116
211
|
}
|
|
117
|
-
/**
|
|
118
|
-
* Provisioning a production trust root requires a reviewed source change.
|
|
119
|
-
* No environment variable, config field, CLI argument, or writable trust file
|
|
120
|
-
* can add authority at runtime.
|
|
121
|
-
*/
|
|
122
|
-
export declare const DAEMON_ACTIVATION_TRUST_ROOTS: readonly Readonly<DaemonActivationTrustRoot>[];
|
|
123
212
|
/** Validate and consume a capability exactly once. */
|
|
124
213
|
export declare function isDaemonActivationCapability(value: unknown): value is DaemonActivationCapability;
|
|
125
|
-
/**
|
|
126
|
-
* Goal and simple conductors have broader authority than M461's one-item
|
|
127
|
-
* proposal profile. They remain dormant until a separately reviewed permit
|
|
128
|
-
* contract exists for those entry points.
|
|
129
|
-
*/
|
|
130
|
-
export declare function liveConductorActivationAuthorized(): boolean;
|
|
131
214
|
export declare function canonicalizeDaemonActivationValue(value: unknown): string;
|
|
132
215
|
export declare function daemonActivationConfigDigest(cfg: AshlrConfig): string;
|
|
133
216
|
export declare function verifyDaemonActivationPermit(value: unknown, context: DaemonActivationRuntimeContext, trustRoots: readonly DaemonActivationTrustRoot[]): DaemonActivationPermitVerification;
|
|
@@ -137,16 +220,168 @@ export declare function buildDaemonActivationPermitPayload(input: {
|
|
|
137
220
|
keyId: string;
|
|
138
221
|
issuedAt: string;
|
|
139
222
|
expiresAt: string;
|
|
223
|
+
/** Defaults to the legacy {once, proposalOnly} grant when omitted. */
|
|
224
|
+
scope?: DaemonActivationGrantScope;
|
|
140
225
|
context: DaemonActivationRuntimeContext;
|
|
141
226
|
}): DaemonActivationPermitPayload;
|
|
142
227
|
export declare function signDaemonActivationPermit(payload: DaemonActivationPermitPayload, privateKey: string | KeyObject): DaemonActivationPermitEnvelope;
|
|
143
228
|
/** Read-only helper for release packaging and substitution verification. */
|
|
144
229
|
export declare function daemonActivationReleaseTreeBinding(entrypointPath: string): DaemonActivationFileBinding;
|
|
230
|
+
/**
|
|
231
|
+
* Fingerprints "this authority store instance" — the ~/.ashlr directory a
|
|
232
|
+
* permit is bound to — so a permit can't be replayed against a different
|
|
233
|
+
* store (e.g. copied to another machine, or after a full delete+recreate).
|
|
234
|
+
*
|
|
235
|
+
* Deliberately uses dev+ino, NOT mtime. ~/.ashlr's own mtime changes every
|
|
236
|
+
* time a direct child is created or removed — and ordinary `daemon start`
|
|
237
|
+
* does exactly that before it ever reaches this check: acquireDaemonLock()
|
|
238
|
+
* (src/core/daemon/state.ts) creates ~/.ashlr/daemon.lock via
|
|
239
|
+
* `writeFileSync(..., {flag:'wx'})`, a brand-new direct child of ~/.ashlr.
|
|
240
|
+
* Binding to mtime meant every freshly minted permit was invalidated by the
|
|
241
|
+
* daemon's own startup lock-file creation, 100% reproducibly, before it
|
|
242
|
+
* could ever be consumed — a self-inflicted permit-runtime-binding-mismatch,
|
|
243
|
+
* not a real "different store" signal. dev+ino uniquely and STABLY identify
|
|
244
|
+
* the directory's inode: they survive ordinary child churn (locks, control
|
|
245
|
+
* files, receipts) and change only if ~/.ashlr is deleted and recreated (or
|
|
246
|
+
* moved to a different filesystem) — exactly the case this binding exists
|
|
247
|
+
* to catch.
|
|
248
|
+
*/
|
|
249
|
+
export declare function daemonActivationAuthorityStateDigest(): string;
|
|
145
250
|
export declare function daemonActivationPermitPath(): string;
|
|
146
251
|
export declare function daemonActivationReceiptPath(permitId: string): string;
|
|
252
|
+
export declare function daemonActivationDirPath(): string;
|
|
253
|
+
export declare function daemonActivationTrustRootsPath(): string;
|
|
254
|
+
export declare function daemonActivationGrantsPath(): string;
|
|
255
|
+
export declare function daemonActivationOperatorKeyPath(): string;
|
|
256
|
+
/**
|
|
257
|
+
* The ONLY source of production trust roots: an operator-owned, protected
|
|
258
|
+
* file the operator populates via `ashlr activation init`. Missing, unsafe,
|
|
259
|
+
* or malformed → [] — identical denial to before this file loading existed.
|
|
260
|
+
*/
|
|
261
|
+
export declare function loadDaemonActivationTrustRoots(): readonly DaemonActivationTrustRoot[];
|
|
262
|
+
/** Full trust-root status (incl. revoked history) for `ashlr activation status`. */
|
|
263
|
+
export declare function daemonActivationTrustRootStatus(): {
|
|
264
|
+
ok: true;
|
|
265
|
+
records: readonly DaemonActivationTrustRootRecord[];
|
|
266
|
+
} | {
|
|
267
|
+
ok: false;
|
|
268
|
+
reason: string;
|
|
269
|
+
};
|
|
270
|
+
/** Full standing-grant status (incl. revoked/expired history) for `ashlr activation status`. */
|
|
271
|
+
export declare function daemonActivationGrantStatus(): {
|
|
272
|
+
ok: true;
|
|
273
|
+
records: readonly DaemonActivationGrantRecord[];
|
|
274
|
+
} | {
|
|
275
|
+
ok: false;
|
|
276
|
+
reason: string;
|
|
277
|
+
};
|
|
278
|
+
export declare function signDaemonActivationGrant(input: {
|
|
279
|
+
grantId: string;
|
|
280
|
+
keyId: string;
|
|
281
|
+
issuedAt: string;
|
|
282
|
+
expiresAt: string;
|
|
283
|
+
scope: DaemonActivationGrantScope;
|
|
284
|
+
privateKey: string | KeyObject;
|
|
285
|
+
}): DaemonActivationGrantRecord;
|
|
286
|
+
export declare function daemonActivationScopeGranted(scopeKey: DaemonActivationScopeKey): {
|
|
287
|
+
granted: boolean;
|
|
288
|
+
reason: string;
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* The goal and simple conductors consult this every cycle. Real, gated,
|
|
292
|
+
* revocable authority: granted only after `ashlr activation init` +
|
|
293
|
+
* `ashlr activation grant conductor`. Default (no grant) is denied, exactly
|
|
294
|
+
* as before this mechanism existed. Every check is audited.
|
|
295
|
+
*/
|
|
296
|
+
export declare function liveConductorActivationAuthorized(): boolean;
|
|
297
|
+
export declare function generateDaemonActivationOperatorKeypair(): {
|
|
298
|
+
privateKeyPem: string;
|
|
299
|
+
publicKeyPem: string;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Generates an Ed25519 keypair on THIS machine (private key never leaves it,
|
|
303
|
+
* written 0600 under an 0700 directory) and registers the public half as a
|
|
304
|
+
* new active trust root. Refuses to silently clobber an existing active
|
|
305
|
+
* root or key file unless `force` is set (key rotation: the new root is
|
|
306
|
+
* ADDED, not swapped in place, so grants signed by an older still-active
|
|
307
|
+
* root keep working until explicitly revoked).
|
|
308
|
+
*/
|
|
309
|
+
export declare function daemonActivationInit(input: {
|
|
310
|
+
label?: string;
|
|
311
|
+
force?: boolean;
|
|
312
|
+
}): {
|
|
313
|
+
ok: true;
|
|
314
|
+
keyId: string;
|
|
315
|
+
publicKeyPem: string;
|
|
316
|
+
rotated: boolean;
|
|
317
|
+
} | {
|
|
318
|
+
ok: false;
|
|
319
|
+
reason: string;
|
|
320
|
+
};
|
|
321
|
+
export declare function daemonActivationRevokeTrustRoot(keyId: string): {
|
|
322
|
+
ok: true;
|
|
323
|
+
} | {
|
|
324
|
+
ok: false;
|
|
325
|
+
reason: string;
|
|
326
|
+
};
|
|
327
|
+
export declare function daemonActivationRevokeGrant(grantId: string): {
|
|
328
|
+
ok: true;
|
|
329
|
+
} | {
|
|
330
|
+
ok: false;
|
|
331
|
+
reason: string;
|
|
332
|
+
};
|
|
333
|
+
/** Mints a signed, expiring standing grant (conductor/automerge/repair/deploy/install/proposalOnly). */
|
|
334
|
+
export declare function daemonActivationMintStandingGrant(input: {
|
|
335
|
+
scope: DaemonActivationGrantScope;
|
|
336
|
+
ttlMs: number;
|
|
337
|
+
}): {
|
|
338
|
+
ok: true;
|
|
339
|
+
record: DaemonActivationGrantRecord;
|
|
340
|
+
} | {
|
|
341
|
+
ok: false;
|
|
342
|
+
reason: string;
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* Mints and pins a single-use activation permit (once/resident scopes) to
|
|
346
|
+
* daemonActivationPermitPath(), ready for `ashlr daemon start` to consume.
|
|
347
|
+
* Signs against THIS exact machine's current build (executable/entrypoint/
|
|
348
|
+
* release-tree hashes) — an operator runs this locally, immediately before
|
|
349
|
+
* starting the daemon it authorizes.
|
|
350
|
+
*/
|
|
351
|
+
export declare function daemonActivationMintOneShotPermit(input: {
|
|
352
|
+
cfg: AshlrConfig;
|
|
353
|
+
scope: DaemonActivationGrantScope;
|
|
354
|
+
}): {
|
|
355
|
+
ok: true;
|
|
356
|
+
permitId: string;
|
|
357
|
+
permitPath: string;
|
|
358
|
+
expiresAt: string;
|
|
359
|
+
} | {
|
|
360
|
+
ok: false;
|
|
361
|
+
reason: string;
|
|
362
|
+
};
|
|
363
|
+
export interface DaemonActivationPendingPermitBindingDiagnosis {
|
|
364
|
+
ok: boolean;
|
|
365
|
+
reason: string;
|
|
366
|
+
/** Field name -> {signed at mint time, computed right now}. Only present for mismatched fields. */
|
|
367
|
+
mismatches?: Record<string, {
|
|
368
|
+
signed: unknown;
|
|
369
|
+
current: unknown;
|
|
370
|
+
}>;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Read-only diagnostic (never authorizes, never consumes) for `ashlr
|
|
374
|
+
* activation status`: peeks the pending one-shot permit, recomputes the
|
|
375
|
+
* current runtime context, and reports exactly which binding field(s)
|
|
376
|
+
* differ and what the two values were. `permit-runtime-binding-mismatch`
|
|
377
|
+
* alone can't tell an operator what to fix — this can.
|
|
378
|
+
*/
|
|
379
|
+
export declare function daemonActivationDiagnosePendingPermitBindings(cfg: AshlrConfig): DaemonActivationPendingPermitBindingDiagnosis;
|
|
147
380
|
/**
|
|
148
|
-
* Runtime entrypoint.
|
|
149
|
-
*
|
|
381
|
+
* Runtime entrypoint. Trust roots come ONLY from the operator-owned store
|
|
382
|
+
* (see loadDaemonActivationTrustRoots); an npm consumer who never runs
|
|
383
|
+
* `ashlr activation init` sees the store as empty and gets today's exact
|
|
384
|
+
* denial. Every consume attempt — authorized or refused — is audited.
|
|
150
385
|
*/
|
|
151
386
|
export declare function consumeDaemonActivationPermit(cfg: AshlrConfig, opts: DaemonActivationOptions): DaemonActivationPermitResult;
|
|
152
387
|
/**
|
|
@@ -161,4 +396,93 @@ export declare function inspectDaemonActivationPermitForVerification(cfg: AshlrC
|
|
|
161
396
|
* durability with injected roots, but deliberately cannot mint authority.
|
|
162
397
|
*/
|
|
163
398
|
export declare function consumeDaemonActivationPermitForVerification(cfg: AshlrConfig, opts: DaemonActivationOptions, options: DaemonActivationPermitTestConsumerOptions): DaemonActivationPermitResult;
|
|
399
|
+
declare const GOAL_CONDUCTOR_POLICY_VERSION = "goal-conductor-proposal-once-v1";
|
|
400
|
+
export declare const GOAL_CONDUCTOR_ONCE_MAX_TOKENS = 50000;
|
|
401
|
+
export declare const GOAL_CONDUCTOR_ONCE_MAX_STEPS = 12;
|
|
402
|
+
declare const goalConductorCapabilityBrand: unique symbol;
|
|
403
|
+
export interface GoalConductorActivationTarget {
|
|
404
|
+
goalId: string;
|
|
405
|
+
milestoneId: string;
|
|
406
|
+
goalDigest: string;
|
|
407
|
+
projectPath: string;
|
|
408
|
+
}
|
|
409
|
+
export interface GoalConductorActivationContext extends DaemonActivationRuntimeContext {
|
|
410
|
+
target: GoalConductorActivationTarget;
|
|
411
|
+
}
|
|
412
|
+
export interface GoalConductorActivationPermitPayload {
|
|
413
|
+
schemaVersion: 1;
|
|
414
|
+
policyVersion: typeof GOAL_CONDUCTOR_POLICY_VERSION;
|
|
415
|
+
permitId: string;
|
|
416
|
+
nonce: string;
|
|
417
|
+
keyId: string;
|
|
418
|
+
issuedAt: string;
|
|
419
|
+
expiresAt: string;
|
|
420
|
+
scope: {
|
|
421
|
+
action: 'goal-conductor-proposal-once';
|
|
422
|
+
once: true;
|
|
423
|
+
dryRun: false;
|
|
424
|
+
resident: false;
|
|
425
|
+
maxGoals: 1;
|
|
426
|
+
maxMilestones: 1;
|
|
427
|
+
maxRetries: 0;
|
|
428
|
+
allowCloud: false;
|
|
429
|
+
allowAnyRepo: false;
|
|
430
|
+
daemonFallback: false;
|
|
431
|
+
proposalOnly: true;
|
|
432
|
+
automerge: false;
|
|
433
|
+
repair: false;
|
|
434
|
+
deploy: false;
|
|
435
|
+
install: false;
|
|
436
|
+
selfTarget: false;
|
|
437
|
+
maxTokens: typeof GOAL_CONDUCTOR_ONCE_MAX_TOKENS;
|
|
438
|
+
maxSteps: typeof GOAL_CONDUCTOR_ONCE_MAX_STEPS;
|
|
439
|
+
};
|
|
440
|
+
bindings: DaemonActivationPermitPayload['bindings'] & {
|
|
441
|
+
target: GoalConductorActivationTarget;
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
export interface GoalConductorActivationPermitEnvelope {
|
|
445
|
+
payload: GoalConductorActivationPermitPayload;
|
|
446
|
+
signature: string;
|
|
447
|
+
}
|
|
448
|
+
export interface GoalConductorActivationCapability {
|
|
449
|
+
readonly kind: 'goal-conductor-proposal-once';
|
|
450
|
+
readonly permitId: string;
|
|
451
|
+
readonly target: Readonly<GoalConductorActivationTarget>;
|
|
452
|
+
readonly [goalConductorCapabilityBrand]: true;
|
|
453
|
+
}
|
|
454
|
+
export interface GoalConductorActivationPermitResult {
|
|
455
|
+
authorized: boolean;
|
|
456
|
+
reason: string;
|
|
457
|
+
permitId?: string;
|
|
458
|
+
receiptPath?: string;
|
|
459
|
+
capability?: GoalConductorActivationCapability;
|
|
460
|
+
configSnapshot?: AshlrConfig;
|
|
461
|
+
}
|
|
462
|
+
export interface GoalConductorActivationTestConsumerOptions {
|
|
463
|
+
trustRoots: readonly DaemonActivationTrustRoot[];
|
|
464
|
+
context?: GoalConductorActivationContext;
|
|
465
|
+
afterReceiptPersisted?: () => void;
|
|
466
|
+
}
|
|
467
|
+
/** Immutable repository-owned roots. Intentionally empty in production. */
|
|
468
|
+
export declare const GOAL_CONDUCTOR_ACTIVATION_TRUST_ROOTS: readonly Readonly<DaemonActivationTrustRoot>[];
|
|
469
|
+
export declare function parseGoalConductorActivationPermitEnvelope(value: unknown): GoalConductorActivationPermitEnvelope | null;
|
|
470
|
+
export declare function buildGoalConductorActivationPermitPayload(input: {
|
|
471
|
+
permitId: string;
|
|
472
|
+
nonce: string;
|
|
473
|
+
keyId: string;
|
|
474
|
+
issuedAt: string;
|
|
475
|
+
expiresAt: string;
|
|
476
|
+
context: GoalConductorActivationContext;
|
|
477
|
+
}): GoalConductorActivationPermitPayload;
|
|
478
|
+
export declare function signGoalConductorActivationPermit(payload: GoalConductorActivationPermitPayload, privateKey: string | KeyObject): GoalConductorActivationPermitEnvelope;
|
|
479
|
+
export declare function verifyGoalConductorActivationPermit(value: unknown, context: GoalConductorActivationContext, roots: readonly DaemonActivationTrustRoot[]): DaemonActivationPermitVerification;
|
|
480
|
+
export declare function goalConductorActivationPermitPath(): string;
|
|
481
|
+
export declare function goalConductorActivationReceiptPath(permitId: string): string;
|
|
482
|
+
export declare function goalConductorActivationNonceReceiptPath(nonceDigest: string): string;
|
|
483
|
+
/** Collect the same read-only runtime binding used at permit consumption. */
|
|
484
|
+
export declare function collectGoalConductorActivationContext(cfg: AshlrConfig, target: GoalConductorActivationTarget): GoalConductorActivationContext;
|
|
485
|
+
export declare function isGoalConductorActivationCapability(value: unknown, target: GoalConductorActivationTarget): value is GoalConductorActivationCapability;
|
|
486
|
+
export declare function consumeGoalConductorActivationPermit(cfg: AshlrConfig, target: GoalConductorActivationTarget): GoalConductorActivationPermitResult;
|
|
487
|
+
export declare function consumeGoalConductorActivationPermitForVerification(cfg: AshlrConfig, target: GoalConductorActivationTarget, options: GoalConductorActivationTestConsumerOptions): GoalConductorActivationPermitResult;
|
|
164
488
|
export {};
|