@haaaiawd/second-nature 0.1.1 → 0.1.3
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/index.ts +64 -21
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -2
- package/runtime/cli/action-bridge.d.ts +11 -0
- package/runtime/cli/action-bridge.js +27 -0
- package/runtime/cli/commands/credential.d.ts +2 -0
- package/runtime/cli/commands/credential.js +40 -0
- package/runtime/cli/commands/index.d.ts +12 -0
- package/runtime/cli/commands/index.js +138 -0
- package/runtime/cli/commands/policy.d.ts +12 -0
- package/runtime/cli/commands/policy.js +43 -0
- package/runtime/cli/explain/format-explanation.d.ts +10 -0
- package/runtime/cli/explain/format-explanation.js +10 -0
- package/runtime/cli/explain/resolve-subject.d.ts +2 -0
- package/runtime/cli/explain/resolve-subject.js +26 -0
- package/runtime/cli/index.d.ts +25 -0
- package/runtime/cli/index.js +36 -0
- package/runtime/cli/read-models/index.d.ts +20 -0
- package/runtime/cli/read-models/index.js +161 -0
- package/runtime/cli/read-models/types.d.ts +75 -0
- package/runtime/cli/read-models/types.js +1 -0
- package/runtime/connectors/agent-network/evomap/adapter.d.ts +23 -0
- package/runtime/connectors/agent-network/evomap/adapter.js +69 -0
- package/runtime/connectors/agent-network/evomap/index.d.ts +2 -0
- package/runtime/connectors/agent-network/evomap/index.js +2 -0
- package/runtime/connectors/agent-network/evomap/manifest.d.ts +2 -0
- package/runtime/connectors/agent-network/evomap/manifest.js +7 -0
- package/runtime/connectors/base/channel-health.d.ts +29 -0
- package/runtime/connectors/base/channel-health.js +23 -0
- package/runtime/connectors/base/contract.d.ts +81 -0
- package/runtime/connectors/base/contract.js +71 -0
- package/runtime/connectors/base/failure-taxonomy.d.ts +13 -0
- package/runtime/connectors/base/failure-taxonomy.js +105 -0
- package/runtime/connectors/base/index.d.ts +6 -0
- package/runtime/connectors/base/index.js +6 -0
- package/runtime/connectors/base/manifest.d.ts +11 -0
- package/runtime/connectors/base/manifest.js +36 -0
- package/runtime/connectors/base/policy-layer.d.ts +27 -0
- package/runtime/connectors/base/policy-layer.js +213 -0
- package/runtime/connectors/base/route-planner.d.ts +10 -0
- package/runtime/connectors/base/route-planner.js +98 -0
- package/runtime/connectors/index.d.ts +4 -0
- package/runtime/connectors/index.js +4 -0
- package/runtime/connectors/social-community/instreet/adapter.d.ts +32 -0
- package/runtime/connectors/social-community/instreet/adapter.js +79 -0
- package/runtime/connectors/social-community/instreet/index.d.ts +2 -0
- package/runtime/connectors/social-community/instreet/index.js +2 -0
- package/runtime/connectors/social-community/instreet/manifest.d.ts +2 -0
- package/runtime/connectors/social-community/instreet/manifest.js +7 -0
- package/runtime/connectors/social-community/moltbook/adapter.d.ts +15 -0
- package/runtime/connectors/social-community/moltbook/adapter.js +48 -0
- package/runtime/connectors/social-community/moltbook/index.d.ts +2 -0
- package/runtime/connectors/social-community/moltbook/index.js +2 -0
- package/runtime/connectors/social-community/moltbook/manifest.d.ts +7 -0
- package/runtime/connectors/social-community/moltbook/manifest.js +12 -0
- package/runtime/core/second-nature/guidance/apply-guidance.d.ts +10 -0
- package/runtime/core/second-nature/guidance/apply-guidance.js +10 -0
- package/runtime/core/second-nature/guidance/request-guidance.d.ts +18 -0
- package/runtime/core/second-nature/guidance/request-guidance.js +22 -0
- package/runtime/core/second-nature/index.d.ts +14 -0
- package/runtime/core/second-nature/index.js +14 -0
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.d.ts +100 -0
- package/runtime/core/second-nature/orchestrator/effect-dispatcher.js +139 -0
- package/runtime/core/second-nature/orchestrator/guard-layer.d.ts +2 -0
- package/runtime/core/second-nature/orchestrator/guard-layer.js +54 -0
- package/runtime/core/second-nature/orchestrator/intent-planner.d.ts +3 -0
- package/runtime/core/second-nature/orchestrator/intent-planner.js +92 -0
- package/runtime/core/second-nature/orchestrator/lease-manager.d.ts +14 -0
- package/runtime/core/second-nature/orchestrator/lease-manager.js +58 -0
- package/runtime/core/second-nature/orchestrator/resume-from-checkpoint.d.ts +32 -0
- package/runtime/core/second-nature/orchestrator/resume-from-checkpoint.js +23 -0
- package/runtime/core/second-nature/outreach/build-message.d.ts +16 -0
- package/runtime/core/second-nature/outreach/build-message.js +27 -0
- package/runtime/core/second-nature/outreach/evaluate-outreach.d.ts +13 -0
- package/runtime/core/second-nature/outreach/evaluate-outreach.js +41 -0
- package/runtime/core/second-nature/quiet/quiet-pipeline.d.ts +34 -0
- package/runtime/core/second-nature/quiet/quiet-pipeline.js +35 -0
- package/runtime/core/second-nature/reflection/run-narrative-reflection.d.ts +39 -0
- package/runtime/core/second-nature/reflection/run-narrative-reflection.js +29 -0
- package/runtime/core/second-nature/rhythm/rhythm-policy.d.ts +18 -0
- package/runtime/core/second-nature/rhythm/rhythm-policy.js +24 -0
- package/runtime/core/second-nature/rhythm/select-window.d.ts +3 -0
- package/runtime/core/second-nature/rhythm/select-window.js +50 -0
- package/runtime/core/second-nature/runtime/lifecycle-service.d.ts +26 -0
- package/runtime/core/second-nature/runtime/lifecycle-service.js +38 -0
- package/runtime/core/second-nature/runtime/service-entry.d.ts +36 -0
- package/runtime/core/second-nature/runtime/service-entry.js +44 -0
- package/runtime/core/second-nature/types.d.ts +37 -0
- package/runtime/core/second-nature/types.js +1 -0
- package/runtime/guidance/contracts.d.ts +48 -0
- package/runtime/guidance/contracts.js +54 -0
- package/runtime/guidance/fallback.d.ts +2 -0
- package/runtime/guidance/fallback.js +17 -0
- package/runtime/guidance/guidance-assembler.d.ts +5 -0
- package/runtime/guidance/guidance-assembler.js +62 -0
- package/runtime/guidance/index.d.ts +8 -0
- package/runtime/guidance/index.js +8 -0
- package/runtime/guidance/output-guard.d.ts +10 -0
- package/runtime/guidance/output-guard.js +29 -0
- package/runtime/guidance/persona-selection.d.ts +11 -0
- package/runtime/guidance/persona-selection.js +90 -0
- package/runtime/guidance/review-workflow.d.ts +15 -0
- package/runtime/guidance/review-workflow.js +60 -0
- package/runtime/guidance/template-registry.d.ts +3 -0
- package/runtime/guidance/template-registry.js +45 -0
- package/runtime/guidance/types.d.ts +72 -0
- package/runtime/guidance/types.js +1 -0
- package/runtime/observability/db/index.d.ts +10 -0
- package/runtime/observability/db/index.js +17 -0
- package/runtime/observability/db/schema/index.d.ts +946 -0
- package/runtime/observability/db/schema/index.js +70 -0
- package/runtime/observability/index.d.ts +12 -0
- package/runtime/observability/index.js +11 -0
- package/runtime/observability/projections/guidance-audit.d.ts +16 -0
- package/runtime/observability/projections/guidance-audit.js +35 -0
- package/runtime/observability/projections/outreach-quality-audit.d.ts +15 -0
- package/runtime/observability/projections/outreach-quality-audit.js +9 -0
- package/runtime/observability/projections/reflection-audit.d.ts +17 -0
- package/runtime/observability/projections/reflection-audit.js +9 -0
- package/runtime/observability/query/compose-evidence.d.ts +56 -0
- package/runtime/observability/query/compose-evidence.js +43 -0
- package/runtime/observability/query/evidence-query-engine.d.ts +17 -0
- package/runtime/observability/query/evidence-query-engine.js +166 -0
- package/runtime/observability/redaction/manifest.d.ts +18 -0
- package/runtime/observability/redaction/manifest.js +109 -0
- package/runtime/observability/redaction/policy.d.ts +19 -0
- package/runtime/observability/redaction/policy.js +71 -0
- package/runtime/observability/services/decision-ledger.d.ts +33 -0
- package/runtime/observability/services/decision-ledger.js +115 -0
- package/runtime/observability/services/execution-telemetry.d.ts +32 -0
- package/runtime/observability/services/execution-telemetry.js +126 -0
- package/runtime/observability/services/governance-audit.d.ts +27 -0
- package/runtime/observability/services/governance-audit.js +139 -0
- package/runtime/observability/services/redaction-store.d.ts +3 -0
- package/runtime/observability/services/redaction-store.js +20 -0
- package/runtime/setup/HOST_SETUP.md +112 -0
- package/runtime/shared/types/continuity.d.ts +69 -0
- package/runtime/shared/types/continuity.js +1 -0
- package/runtime/shared/types/credential.d.ts +22 -0
- package/runtime/shared/types/credential.js +1 -0
- package/runtime/shared/types/index.d.ts +3 -0
- package/runtime/shared/types/index.js +3 -0
- package/runtime/shared/types/outreach.d.ts +19 -0
- package/runtime/shared/types/outreach.js +1 -0
- package/runtime/storage/bootstrap/repair.d.ts +3 -0
- package/runtime/storage/bootstrap/repair.js +5 -0
- package/runtime/storage/db/index.d.ts +10 -0
- package/runtime/storage/db/index.js +17 -0
- package/runtime/storage/db/schema/assets.d.ts +140 -0
- package/runtime/storage/db/schema/assets.js +10 -0
- package/runtime/storage/db/schema/credentials.d.ts +178 -0
- package/runtime/storage/db/schema/credentials.js +12 -0
- package/runtime/storage/db/schema/index.d.ts +6 -0
- package/runtime/storage/db/schema/index.js +6 -0
- package/runtime/storage/db/schema/intent-commits.d.ts +161 -0
- package/runtime/storage/db/schema/intent-commits.js +11 -0
- package/runtime/storage/db/schema/policies.d.ts +81 -0
- package/runtime/storage/db/schema/policies.js +7 -0
- package/runtime/storage/db/schema/proposals.d.ts +216 -0
- package/runtime/storage/db/schema/proposals.js +14 -0
- package/runtime/storage/db/schema/provenance.d.ts +104 -0
- package/runtime/storage/db/schema/provenance.js +8 -0
- package/runtime/storage/index.d.ts +16 -0
- package/runtime/storage/index.js +16 -0
- package/runtime/storage/memory/workspace/paths.d.ts +62 -0
- package/runtime/storage/memory/workspace/paths.js +160 -0
- package/runtime/storage/memory/workspace/store.d.ts +26 -0
- package/runtime/storage/memory/workspace/store.js +153 -0
- package/runtime/storage/memory/workspace/types.d.ts +45 -0
- package/runtime/storage/memory/workspace/types.js +1 -0
- package/runtime/storage/repositories/asset-repository.d.ts +8 -0
- package/runtime/storage/repositories/asset-repository.js +19 -0
- package/runtime/storage/repositories/credential-repository.d.ts +8 -0
- package/runtime/storage/repositories/credential-repository.js +19 -0
- package/runtime/storage/repositories/index.d.ts +6 -0
- package/runtime/storage/repositories/index.js +6 -0
- package/runtime/storage/repositories/intent-commit-repository.d.ts +10 -0
- package/runtime/storage/repositories/intent-commit-repository.js +35 -0
- package/runtime/storage/repositories/policy-repository.d.ts +8 -0
- package/runtime/storage/repositories/policy-repository.js +19 -0
- package/runtime/storage/repositories/proposal-repository.d.ts +9 -0
- package/runtime/storage/repositories/proposal-repository.js +26 -0
- package/runtime/storage/repositories/provenance-repository.d.ts +20 -0
- package/runtime/storage/repositories/provenance-repository.js +41 -0
- package/runtime/storage/services/credential-vault.d.ts +8 -0
- package/runtime/storage/services/credential-vault.js +78 -0
- package/runtime/storage/services/daily-log-pipeline.d.ts +47 -0
- package/runtime/storage/services/daily-log-pipeline.js +86 -0
- package/runtime/storage/services/effect-commit-store.d.ts +11 -0
- package/runtime/storage/services/effect-commit-store.js +93 -0
- package/runtime/storage/services/governance-layer.d.ts +40 -0
- package/runtime/storage/services/governance-layer.js +103 -0
- package/runtime/storage/services/persona-candidate-loader.d.ts +5 -0
- package/runtime/storage/services/persona-candidate-loader.js +41 -0
- package/runtime/storage/services/provenance-service.d.ts +40 -0
- package/runtime/storage/services/provenance-service.js +43 -0
- package/runtime/storage/services/quiet-input-loader.d.ts +40 -0
- package/runtime/storage/services/quiet-input-loader.js +131 -0
- package/runtime/storage/services/repair-and-backup.d.ts +22 -0
- package/runtime/storage/services/repair-and-backup.js +73 -0
- package/runtime/storage/state-api.d.ts +46 -0
- package/runtime/storage/state-api.js +73 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export const REDACTION_CONFIG = {
|
|
2
|
+
maskedFieldNames: [
|
|
3
|
+
"token",
|
|
4
|
+
"access_token",
|
|
5
|
+
"refresh_token",
|
|
6
|
+
"api_key",
|
|
7
|
+
"apiSecret",
|
|
8
|
+
"secret",
|
|
9
|
+
"password",
|
|
10
|
+
"bearer_token",
|
|
11
|
+
"authorization",
|
|
12
|
+
"node_secret",
|
|
13
|
+
],
|
|
14
|
+
eraseFieldNames: [
|
|
15
|
+
"full_message",
|
|
16
|
+
"full_post",
|
|
17
|
+
"private_message",
|
|
18
|
+
"prompt",
|
|
19
|
+
"system_prompt",
|
|
20
|
+
"completion",
|
|
21
|
+
"response_content",
|
|
22
|
+
],
|
|
23
|
+
hashFieldNames: [
|
|
24
|
+
"user_id",
|
|
25
|
+
"session_id",
|
|
26
|
+
"trace_id",
|
|
27
|
+
"content_hash",
|
|
28
|
+
],
|
|
29
|
+
sensitivityLevels: ["public", "internal", "confidential", "restricted"],
|
|
30
|
+
};
|
|
31
|
+
export const DEFAULT_REDACTION_POLICY = {
|
|
32
|
+
defaultPolicy: [
|
|
33
|
+
{ fieldName: "token", action: "mask" },
|
|
34
|
+
{ fieldName: "access_token", action: "mask" },
|
|
35
|
+
{ fieldName: "refresh_token", action: "mask" },
|
|
36
|
+
{ fieldName: "api_key", action: "mask" },
|
|
37
|
+
{ fieldName: "apiSecret", action: "mask" },
|
|
38
|
+
{ fieldName: "secret", action: "mask" },
|
|
39
|
+
{ fieldName: "password", action: "mask" },
|
|
40
|
+
{ fieldName: "bearer_token", action: "mask" },
|
|
41
|
+
{ fieldName: "authorization", action: "mask" },
|
|
42
|
+
{ fieldName: "node_secret", action: "mask" },
|
|
43
|
+
{ fieldName: "full_message", action: "erase" },
|
|
44
|
+
{ fieldName: "full_post", action: "erase" },
|
|
45
|
+
{ fieldName: "private_message", action: "erase" },
|
|
46
|
+
{ fieldName: "prompt", action: "erase" },
|
|
47
|
+
{ fieldName: "system_prompt", action: "erase" },
|
|
48
|
+
{ fieldName: "completion", action: "erase" },
|
|
49
|
+
{ fieldName: "response_content", action: "erase" },
|
|
50
|
+
{ fieldName: "content_hash", action: "hash" },
|
|
51
|
+
],
|
|
52
|
+
fieldOverrides: {},
|
|
53
|
+
maxFieldLength: 500,
|
|
54
|
+
};
|
|
55
|
+
export function getFieldRedactionRule(fieldName, policy = DEFAULT_REDACTION_POLICY) {
|
|
56
|
+
for (const rule of policy.defaultPolicy) {
|
|
57
|
+
if (rule.fieldName === fieldName) {
|
|
58
|
+
return rule;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const [prefix, rules] of Object.entries(policy.fieldOverrides)) {
|
|
62
|
+
if (fieldName.startsWith(prefix)) {
|
|
63
|
+
for (const rule of rules) {
|
|
64
|
+
if (rule.fieldName === fieldName || rule.fieldName === "*") {
|
|
65
|
+
return rule;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { fieldName, action: "keep" };
|
|
71
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ObservabilityDatabase } from "../db/index.js";
|
|
2
|
+
import type { DecisionRecord } from "../../shared/types/continuity.js";
|
|
3
|
+
export interface QuietLifecycleEvent {
|
|
4
|
+
id: string;
|
|
5
|
+
tickId: string;
|
|
6
|
+
eventType: "quiet.entered" | "quiet.skipped" | "quiet.interrupted" | "quiet.resumed" | "quiet.suppressed";
|
|
7
|
+
reason?: string;
|
|
8
|
+
suppressedBy?: string;
|
|
9
|
+
reflectionCandidates?: string[];
|
|
10
|
+
createdAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface OutreachDecision {
|
|
13
|
+
id: string;
|
|
14
|
+
tickId: string;
|
|
15
|
+
eventType: "outreach.considered" | "outreach.denied" | "outreach.deferred" | "outreach.sent";
|
|
16
|
+
platformId?: string;
|
|
17
|
+
targetUserId?: string;
|
|
18
|
+
valueScore?: number;
|
|
19
|
+
suppressionReason?: string;
|
|
20
|
+
messagePreview?: string;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class DecisionLedger {
|
|
24
|
+
private db;
|
|
25
|
+
constructor(db: ObservabilityDatabase);
|
|
26
|
+
recordDecision(record: DecisionRecord): Promise<void>;
|
|
27
|
+
recordQuietLifecycle(event: QuietLifecycleEvent): Promise<void>;
|
|
28
|
+
recordOutreachDecision(event: OutreachDecision): Promise<void>;
|
|
29
|
+
queryByTickId(tickId: string): Promise<DecisionRecord[]>;
|
|
30
|
+
queryByTraceId(traceId: string): Promise<DecisionRecord | null>;
|
|
31
|
+
queryByIntentId(intentId: string): Promise<DecisionRecord[]>;
|
|
32
|
+
private mapToDecisionRecord;
|
|
33
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { eq } from "drizzle-orm";
|
|
2
|
+
import { decisionLedger } from "../db/schema/index.js";
|
|
3
|
+
import { redactEvent } from "../redaction/manifest.js";
|
|
4
|
+
import { persistRedactionManifest } from "./redaction-store.js";
|
|
5
|
+
export class DecisionLedger {
|
|
6
|
+
db;
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
async recordDecision(record) {
|
|
11
|
+
const { redacted, manifest } = redactEvent(record);
|
|
12
|
+
await this.db.db.insert(decisionLedger).values({
|
|
13
|
+
id: redacted.id,
|
|
14
|
+
tickId: redacted.tickId,
|
|
15
|
+
traceId: redacted.traceId,
|
|
16
|
+
intentId: redacted.intentId ?? null,
|
|
17
|
+
platformId: redacted.platformId ?? null,
|
|
18
|
+
verdict: redacted.verdict,
|
|
19
|
+
mode: redacted.mode,
|
|
20
|
+
reasons: JSON.stringify(redacted.reasons),
|
|
21
|
+
reasonCodes: JSON.stringify(redacted.reasonCodes),
|
|
22
|
+
decisionBasis: redacted.decisionBasis,
|
|
23
|
+
evidenceRefs: JSON.stringify(redacted.evidenceRefs),
|
|
24
|
+
modelEvalRef: redacted.modelEvalRef ?? null,
|
|
25
|
+
createdAt: redacted.createdAt,
|
|
26
|
+
});
|
|
27
|
+
await persistRedactionManifest(this.db, redacted.id, "decision.recorded", manifest);
|
|
28
|
+
}
|
|
29
|
+
async recordQuietLifecycle(event) {
|
|
30
|
+
const { redacted, manifest } = redactEvent(event);
|
|
31
|
+
await this.db.db.insert(decisionLedger).values({
|
|
32
|
+
id: redacted.id,
|
|
33
|
+
tickId: redacted.tickId,
|
|
34
|
+
traceId: `quiet-${redacted.eventType}-${redacted.id}`,
|
|
35
|
+
intentId: null,
|
|
36
|
+
platformId: null,
|
|
37
|
+
verdict: "allow",
|
|
38
|
+
mode: "quiet",
|
|
39
|
+
reasons: JSON.stringify([redacted.eventType, redacted.reason ?? ""].filter(Boolean)),
|
|
40
|
+
reasonCodes: JSON.stringify(["quiet_lifecycle"]),
|
|
41
|
+
decisionBasis: "rule_only",
|
|
42
|
+
evidenceRefs: JSON.stringify(redacted.reflectionCandidates ?? []),
|
|
43
|
+
modelEvalRef: null,
|
|
44
|
+
createdAt: redacted.createdAt,
|
|
45
|
+
});
|
|
46
|
+
await persistRedactionManifest(this.db, redacted.id, redacted.eventType, manifest);
|
|
47
|
+
}
|
|
48
|
+
async recordOutreachDecision(event) {
|
|
49
|
+
const { redacted, manifest } = redactEvent(event);
|
|
50
|
+
const verdict = redacted.eventType === "outreach.sent"
|
|
51
|
+
? "allow"
|
|
52
|
+
: redacted.eventType === "outreach.deferred" || redacted.eventType === "outreach.considered"
|
|
53
|
+
? "defer"
|
|
54
|
+
: "deny";
|
|
55
|
+
await this.db.db.insert(decisionLedger).values({
|
|
56
|
+
id: redacted.id,
|
|
57
|
+
tickId: redacted.tickId,
|
|
58
|
+
traceId: `outreach-${redacted.eventType}-${redacted.id}`,
|
|
59
|
+
intentId: null,
|
|
60
|
+
platformId: redacted.platformId ?? null,
|
|
61
|
+
verdict,
|
|
62
|
+
mode: "active",
|
|
63
|
+
reasons: JSON.stringify([
|
|
64
|
+
redacted.eventType,
|
|
65
|
+
redacted.valueScore?.toString() ?? "",
|
|
66
|
+
redacted.suppressionReason ?? "",
|
|
67
|
+
].filter(Boolean)),
|
|
68
|
+
reasonCodes: JSON.stringify(["outreach_decision"]),
|
|
69
|
+
decisionBasis: "score_based",
|
|
70
|
+
evidenceRefs: JSON.stringify([redacted.targetUserId ?? ""].filter(Boolean)),
|
|
71
|
+
modelEvalRef: null,
|
|
72
|
+
createdAt: redacted.createdAt,
|
|
73
|
+
});
|
|
74
|
+
await persistRedactionManifest(this.db, redacted.id, redacted.eventType, manifest);
|
|
75
|
+
}
|
|
76
|
+
async queryByTickId(tickId) {
|
|
77
|
+
const results = await this.db.db
|
|
78
|
+
.select()
|
|
79
|
+
.from(decisionLedger)
|
|
80
|
+
.where(eq(decisionLedger.tickId, tickId));
|
|
81
|
+
return results.map(this.mapToDecisionRecord);
|
|
82
|
+
}
|
|
83
|
+
async queryByTraceId(traceId) {
|
|
84
|
+
const results = await this.db.db
|
|
85
|
+
.select()
|
|
86
|
+
.from(decisionLedger)
|
|
87
|
+
.where(eq(decisionLedger.traceId, traceId))
|
|
88
|
+
.limit(1);
|
|
89
|
+
return results[0] ? this.mapToDecisionRecord(results[0]) : null;
|
|
90
|
+
}
|
|
91
|
+
async queryByIntentId(intentId) {
|
|
92
|
+
const results = await this.db.db
|
|
93
|
+
.select()
|
|
94
|
+
.from(decisionLedger)
|
|
95
|
+
.where(eq(decisionLedger.intentId, intentId));
|
|
96
|
+
return results.map(this.mapToDecisionRecord);
|
|
97
|
+
}
|
|
98
|
+
mapToDecisionRecord(row) {
|
|
99
|
+
return {
|
|
100
|
+
id: row.id,
|
|
101
|
+
tickId: row.tickId,
|
|
102
|
+
traceId: row.traceId,
|
|
103
|
+
intentId: row.intentId ?? undefined,
|
|
104
|
+
platformId: row.platformId ?? undefined,
|
|
105
|
+
verdict: row.verdict,
|
|
106
|
+
mode: row.mode,
|
|
107
|
+
reasons: JSON.parse(row.reasons),
|
|
108
|
+
reasonCodes: JSON.parse(row.reasonCodes),
|
|
109
|
+
decisionBasis: row.decisionBasis,
|
|
110
|
+
evidenceRefs: JSON.parse(row.evidenceRefs),
|
|
111
|
+
modelEvalRef: row.modelEvalRef ?? undefined,
|
|
112
|
+
createdAt: row.createdAt,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ObservabilityDatabase } from "../db/index.js";
|
|
2
|
+
import type { ExecutionAttempt, IntentCommitState } from "../../shared/types/continuity.js";
|
|
3
|
+
export interface ExecutionAttemptInput {
|
|
4
|
+
traceId: string;
|
|
5
|
+
decisionId: string;
|
|
6
|
+
intentId: string;
|
|
7
|
+
platformId: string;
|
|
8
|
+
capability: string;
|
|
9
|
+
channel: string;
|
|
10
|
+
status: ExecutionAttempt["status"];
|
|
11
|
+
commitState?: IntentCommitState;
|
|
12
|
+
failureClass?: string;
|
|
13
|
+
retryPolicy?: string;
|
|
14
|
+
idempotencyKey?: string;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
16
|
+
startedAt?: string;
|
|
17
|
+
finishedAt?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class ExecutionTelemetry {
|
|
20
|
+
private db;
|
|
21
|
+
constructor(db: ObservabilityDatabase);
|
|
22
|
+
recordExecutionAttempt(attempt: ExecutionAttempt): Promise<void>;
|
|
23
|
+
startAttempt(input: ExecutionAttemptInput): Promise<string>;
|
|
24
|
+
completeAttempt(traceId: string, status: "succeeded" | "failed", commitState?: IntentCommitState, failureClass?: string): Promise<void>;
|
|
25
|
+
updateCommitState(traceId: string, commitState: IntentCommitState): Promise<void>;
|
|
26
|
+
queryByTraceId(traceId: string): Promise<ExecutionAttempt | null>;
|
|
27
|
+
queryByDecisionId(decisionId: string): Promise<ExecutionAttempt[]>;
|
|
28
|
+
queryByPlatform(platformId: string): Promise<ExecutionAttempt[]>;
|
|
29
|
+
queryFailedAttempts(since: string): Promise<ExecutionAttempt[]>;
|
|
30
|
+
queryByCommitState(commitState: IntentCommitState): Promise<ExecutionAttempt[]>;
|
|
31
|
+
private mapToExecutionAttempt;
|
|
32
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { eq, and, gte } from "drizzle-orm";
|
|
2
|
+
import { executionAttempts } from "../db/schema/index.js";
|
|
3
|
+
import { redactEvent } from "../redaction/manifest.js";
|
|
4
|
+
import { persistRedactionManifest } from "./redaction-store.js";
|
|
5
|
+
export class ExecutionTelemetry {
|
|
6
|
+
db;
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
async recordExecutionAttempt(attempt) {
|
|
11
|
+
const { redacted, manifest } = redactEvent(attempt);
|
|
12
|
+
await this.db.db.insert(executionAttempts).values({
|
|
13
|
+
id: redacted.id,
|
|
14
|
+
traceId: redacted.traceId,
|
|
15
|
+
decisionId: redacted.decisionId,
|
|
16
|
+
intentId: redacted.intentId,
|
|
17
|
+
platformId: redacted.platformId,
|
|
18
|
+
capability: redacted.capability,
|
|
19
|
+
channel: redacted.channel,
|
|
20
|
+
status: redacted.status,
|
|
21
|
+
commitState: redacted.commitState ?? null,
|
|
22
|
+
failureClass: redacted.failureClass ?? null,
|
|
23
|
+
retryPolicy: redacted.retryPolicy ?? null,
|
|
24
|
+
idempotencyKey: redacted.idempotencyKey ?? null,
|
|
25
|
+
startedAt: redacted.startedAt ?? null,
|
|
26
|
+
finishedAt: redacted.finishedAt ?? null,
|
|
27
|
+
});
|
|
28
|
+
await persistRedactionManifest(this.db, redacted.id, "connector.attempt.recorded", manifest);
|
|
29
|
+
}
|
|
30
|
+
async startAttempt(input) {
|
|
31
|
+
const id = `attempt-${input.traceId}-${Date.now()}`;
|
|
32
|
+
const now = new Date().toISOString();
|
|
33
|
+
const attempt = {
|
|
34
|
+
id,
|
|
35
|
+
traceId: input.traceId,
|
|
36
|
+
decisionId: input.decisionId,
|
|
37
|
+
intentId: input.intentId,
|
|
38
|
+
platformId: input.platformId,
|
|
39
|
+
capability: input.capability,
|
|
40
|
+
channel: input.channel,
|
|
41
|
+
status: "started",
|
|
42
|
+
commitState: input.commitState,
|
|
43
|
+
failureClass: input.failureClass,
|
|
44
|
+
retryPolicy: input.retryPolicy,
|
|
45
|
+
idempotencyKey: input.idempotencyKey,
|
|
46
|
+
metadata: input.metadata,
|
|
47
|
+
startedAt: now,
|
|
48
|
+
finishedAt: undefined,
|
|
49
|
+
};
|
|
50
|
+
await this.recordExecutionAttempt(attempt);
|
|
51
|
+
return id;
|
|
52
|
+
}
|
|
53
|
+
async completeAttempt(traceId, status, commitState, failureClass) {
|
|
54
|
+
const now = new Date().toISOString();
|
|
55
|
+
await this.db.db
|
|
56
|
+
.update(executionAttempts)
|
|
57
|
+
.set({
|
|
58
|
+
status,
|
|
59
|
+
commitState: commitState ?? null,
|
|
60
|
+
failureClass: failureClass ?? null,
|
|
61
|
+
finishedAt: now,
|
|
62
|
+
})
|
|
63
|
+
.where(eq(executionAttempts.traceId, traceId));
|
|
64
|
+
}
|
|
65
|
+
async updateCommitState(traceId, commitState) {
|
|
66
|
+
await this.db.db
|
|
67
|
+
.update(executionAttempts)
|
|
68
|
+
.set({ commitState })
|
|
69
|
+
.where(eq(executionAttempts.traceId, traceId));
|
|
70
|
+
}
|
|
71
|
+
async queryByTraceId(traceId) {
|
|
72
|
+
const results = await this.db.db
|
|
73
|
+
.select()
|
|
74
|
+
.from(executionAttempts)
|
|
75
|
+
.where(eq(executionAttempts.traceId, traceId))
|
|
76
|
+
.limit(1);
|
|
77
|
+
return results[0] ? this.mapToExecutionAttempt(results[0]) : null;
|
|
78
|
+
}
|
|
79
|
+
async queryByDecisionId(decisionId) {
|
|
80
|
+
const results = await this.db.db
|
|
81
|
+
.select()
|
|
82
|
+
.from(executionAttempts)
|
|
83
|
+
.where(eq(executionAttempts.decisionId, decisionId));
|
|
84
|
+
return results.map(this.mapToExecutionAttempt);
|
|
85
|
+
}
|
|
86
|
+
async queryByPlatform(platformId) {
|
|
87
|
+
const results = await this.db.db
|
|
88
|
+
.select()
|
|
89
|
+
.from(executionAttempts)
|
|
90
|
+
.where(eq(executionAttempts.platformId, platformId));
|
|
91
|
+
return results.map(this.mapToExecutionAttempt);
|
|
92
|
+
}
|
|
93
|
+
async queryFailedAttempts(since) {
|
|
94
|
+
const results = await this.db.db
|
|
95
|
+
.select()
|
|
96
|
+
.from(executionAttempts)
|
|
97
|
+
.where(and(eq(executionAttempts.status, "failed"), gte(executionAttempts.startedAt, since)));
|
|
98
|
+
return results.map(this.mapToExecutionAttempt);
|
|
99
|
+
}
|
|
100
|
+
async queryByCommitState(commitState) {
|
|
101
|
+
const results = await this.db.db
|
|
102
|
+
.select()
|
|
103
|
+
.from(executionAttempts)
|
|
104
|
+
.where(eq(executionAttempts.commitState, commitState));
|
|
105
|
+
return results.map(this.mapToExecutionAttempt);
|
|
106
|
+
}
|
|
107
|
+
mapToExecutionAttempt(row) {
|
|
108
|
+
return {
|
|
109
|
+
id: row.id,
|
|
110
|
+
traceId: row.traceId,
|
|
111
|
+
decisionId: row.decisionId,
|
|
112
|
+
intentId: row.intentId,
|
|
113
|
+
platformId: row.platformId,
|
|
114
|
+
capability: row.capability,
|
|
115
|
+
channel: row.channel,
|
|
116
|
+
status: row.status,
|
|
117
|
+
commitState: row.commitState,
|
|
118
|
+
failureClass: row.failureClass ?? undefined,
|
|
119
|
+
retryPolicy: row.retryPolicy ?? undefined,
|
|
120
|
+
idempotencyKey: row.idempotencyKey ?? undefined,
|
|
121
|
+
metadata: undefined,
|
|
122
|
+
startedAt: row.startedAt ?? undefined,
|
|
123
|
+
finishedAt: row.finishedAt ?? undefined,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ObservabilityDatabase } from "../db/index.js";
|
|
2
|
+
import type { AnchorChangeAudit } from "../../shared/types/continuity.js";
|
|
3
|
+
export interface CredentialLifecycleAudit {
|
|
4
|
+
id: string;
|
|
5
|
+
platformId: string;
|
|
6
|
+
credentialId: string;
|
|
7
|
+
statusFrom?: string;
|
|
8
|
+
statusTo: string;
|
|
9
|
+
verificationDeadline?: string;
|
|
10
|
+
attemptsRemaining?: number;
|
|
11
|
+
explanationCapsule: string;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class GovernanceAudit {
|
|
15
|
+
private db;
|
|
16
|
+
constructor(db: ObservabilityDatabase);
|
|
17
|
+
recordAnchorChangeAudit(event: AnchorChangeAudit): Promise<void>;
|
|
18
|
+
recordCredentialLifecycle(event: CredentialLifecycleAudit): Promise<void>;
|
|
19
|
+
recordProposalApply(proposalId: string, targetAssetId: string, assetPath: string, beforeHash: string | undefined, afterHash: string | undefined, supportingSources: string[], reason: string): Promise<void>;
|
|
20
|
+
recordProposalReject(proposalId: string, targetAssetId: string, assetPath: string, reason: string): Promise<void>;
|
|
21
|
+
queryByProposalId(proposalId: string): Promise<AnchorChangeAudit[]>;
|
|
22
|
+
queryByAssetId(assetId: string): Promise<AnchorChangeAudit[]>;
|
|
23
|
+
queryByEventType(eventType: string): Promise<AnchorChangeAudit[]>;
|
|
24
|
+
queryCredentialByPlatform(platformId: string): Promise<CredentialLifecycleAudit[]>;
|
|
25
|
+
private mapToAnchorAudit;
|
|
26
|
+
private mapToCredentialAudit;
|
|
27
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { eq } from "drizzle-orm";
|
|
2
|
+
import { governanceAudit } from "../db/schema/index.js";
|
|
3
|
+
import { redactEvent } from "../redaction/manifest.js";
|
|
4
|
+
import { persistRedactionManifest } from "./redaction-store.js";
|
|
5
|
+
export class GovernanceAudit {
|
|
6
|
+
db;
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
async recordAnchorChangeAudit(event) {
|
|
11
|
+
const { redacted, manifest } = redactEvent(event);
|
|
12
|
+
await this.db.db.insert(governanceAudit).values({
|
|
13
|
+
id: redacted.id,
|
|
14
|
+
eventType: "anchor_change",
|
|
15
|
+
proposalId: redacted.proposalId,
|
|
16
|
+
targetAssetId: redacted.targetAssetId,
|
|
17
|
+
assetPath: redacted.assetPath,
|
|
18
|
+
statusFrom: null,
|
|
19
|
+
statusTo: redacted.status,
|
|
20
|
+
beforeHash: redacted.beforeHash ?? null,
|
|
21
|
+
afterHash: redacted.afterHash ?? null,
|
|
22
|
+
supportingSources: JSON.stringify(redacted.supportingSources),
|
|
23
|
+
reason: redacted.reason,
|
|
24
|
+
verificationDeadline: null,
|
|
25
|
+
attemptsRemaining: null,
|
|
26
|
+
createdAt: redacted.createdAt,
|
|
27
|
+
});
|
|
28
|
+
await persistRedactionManifest(this.db, redacted.id, "anchor.change", manifest);
|
|
29
|
+
}
|
|
30
|
+
async recordCredentialLifecycle(event) {
|
|
31
|
+
const { redacted, manifest } = redactEvent(event);
|
|
32
|
+
await this.db.db.insert(governanceAudit).values({
|
|
33
|
+
id: redacted.id,
|
|
34
|
+
eventType: "credential_lifecycle",
|
|
35
|
+
proposalId: null,
|
|
36
|
+
targetAssetId: redacted.platformId,
|
|
37
|
+
assetPath: redacted.credentialId,
|
|
38
|
+
statusFrom: redacted.statusFrom ?? null,
|
|
39
|
+
statusTo: redacted.statusTo,
|
|
40
|
+
beforeHash: null,
|
|
41
|
+
afterHash: null,
|
|
42
|
+
supportingSources: "[]",
|
|
43
|
+
reason: redacted.explanationCapsule,
|
|
44
|
+
verificationDeadline: redacted.verificationDeadline ?? null,
|
|
45
|
+
attemptsRemaining: redacted.attemptsRemaining ?? null,
|
|
46
|
+
createdAt: redacted.createdAt,
|
|
47
|
+
});
|
|
48
|
+
await persistRedactionManifest(this.db, redacted.id, "credential.lifecycle", manifest);
|
|
49
|
+
}
|
|
50
|
+
async recordProposalApply(proposalId, targetAssetId, assetPath, beforeHash, afterHash, supportingSources, reason) {
|
|
51
|
+
const id = `anchor-${proposalId}-${Date.now()}`;
|
|
52
|
+
const event = {
|
|
53
|
+
id,
|
|
54
|
+
proposalId,
|
|
55
|
+
targetAssetId,
|
|
56
|
+
assetPath,
|
|
57
|
+
status: "applied",
|
|
58
|
+
beforeHash,
|
|
59
|
+
afterHash,
|
|
60
|
+
supportingSources,
|
|
61
|
+
reason,
|
|
62
|
+
appliedAt: new Date().toISOString(),
|
|
63
|
+
createdAt: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
await this.recordAnchorChangeAudit(event);
|
|
66
|
+
}
|
|
67
|
+
async recordProposalReject(proposalId, targetAssetId, assetPath, reason) {
|
|
68
|
+
const id = `anchor-reject-${proposalId}-${Date.now()}`;
|
|
69
|
+
const event = {
|
|
70
|
+
id,
|
|
71
|
+
proposalId,
|
|
72
|
+
targetAssetId,
|
|
73
|
+
assetPath,
|
|
74
|
+
status: "rejected",
|
|
75
|
+
supportingSources: [],
|
|
76
|
+
reason,
|
|
77
|
+
createdAt: new Date().toISOString(),
|
|
78
|
+
};
|
|
79
|
+
await this.recordAnchorChangeAudit(event);
|
|
80
|
+
}
|
|
81
|
+
async queryByProposalId(proposalId) {
|
|
82
|
+
const results = await this.db.db
|
|
83
|
+
.select()
|
|
84
|
+
.from(governanceAudit)
|
|
85
|
+
.where(eq(governanceAudit.proposalId, proposalId));
|
|
86
|
+
return results.map(this.mapToAnchorAudit);
|
|
87
|
+
}
|
|
88
|
+
async queryByAssetId(assetId) {
|
|
89
|
+
const results = await this.db.db
|
|
90
|
+
.select()
|
|
91
|
+
.from(governanceAudit)
|
|
92
|
+
.where(eq(governanceAudit.targetAssetId, assetId));
|
|
93
|
+
return results.map(this.mapToAnchorAudit);
|
|
94
|
+
}
|
|
95
|
+
async queryByEventType(eventType) {
|
|
96
|
+
const results = await this.db.db
|
|
97
|
+
.select()
|
|
98
|
+
.from(governanceAudit)
|
|
99
|
+
.where(eq(governanceAudit.eventType, eventType));
|
|
100
|
+
return results.map(this.mapToAnchorAudit);
|
|
101
|
+
}
|
|
102
|
+
async queryCredentialByPlatform(platformId) {
|
|
103
|
+
const results = await this.db.db
|
|
104
|
+
.select()
|
|
105
|
+
.from(governanceAudit)
|
|
106
|
+
.where(eq(governanceAudit.targetAssetId, platformId));
|
|
107
|
+
return results
|
|
108
|
+
.filter(r => r.eventType === "credential_lifecycle")
|
|
109
|
+
.map(this.mapToCredentialAudit);
|
|
110
|
+
}
|
|
111
|
+
mapToAnchorAudit(row) {
|
|
112
|
+
return {
|
|
113
|
+
id: row.id,
|
|
114
|
+
proposalId: row.proposalId ?? "",
|
|
115
|
+
targetAssetId: row.targetAssetId ?? "",
|
|
116
|
+
assetPath: row.assetPath ?? "",
|
|
117
|
+
status: row.statusTo,
|
|
118
|
+
beforeHash: row.beforeHash ?? undefined,
|
|
119
|
+
afterHash: row.afterHash ?? undefined,
|
|
120
|
+
supportingSources: JSON.parse(row.supportingSources ?? "[]"),
|
|
121
|
+
reason: row.reason ?? "",
|
|
122
|
+
appliedAt: row.statusTo === "applied" ? row.createdAt : undefined,
|
|
123
|
+
createdAt: row.createdAt,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
mapToCredentialAudit(row) {
|
|
127
|
+
return {
|
|
128
|
+
id: row.id,
|
|
129
|
+
platformId: row.targetAssetId ?? "",
|
|
130
|
+
credentialId: row.assetPath ?? "",
|
|
131
|
+
statusFrom: row.statusFrom ?? undefined,
|
|
132
|
+
statusTo: row.statusTo,
|
|
133
|
+
verificationDeadline: row.verificationDeadline ?? undefined,
|
|
134
|
+
attemptsRemaining: row.attemptsRemaining ?? undefined,
|
|
135
|
+
explanationCapsule: row.reason ?? "",
|
|
136
|
+
createdAt: row.createdAt,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ObservabilityDatabase } from "../db/index.js";
|
|
2
|
+
import type { RedactionManifest } from "../redaction/manifest.js";
|
|
3
|
+
export declare function persistRedactionManifest(db: ObservabilityDatabase, eventId: string, eventType: string, manifest: RedactionManifest): Promise<void>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { redactionManifest as redactionManifestTable } from "../db/schema/index.js";
|
|
2
|
+
export async function persistRedactionManifest(db, eventId, eventType, manifest) {
|
|
3
|
+
const rows = [
|
|
4
|
+
...manifest.maskedFields.map((fieldName) => ({ fieldName, action: "mask" })),
|
|
5
|
+
...manifest.erasedFields.map((fieldName) => ({ fieldName, action: "erase" })),
|
|
6
|
+
...manifest.hashedFields.map((fieldName) => ({ fieldName, action: "hash" })),
|
|
7
|
+
];
|
|
8
|
+
if (rows.length === 0) {
|
|
9
|
+
rows.push({ fieldName: "*", action: "none" });
|
|
10
|
+
}
|
|
11
|
+
await db.db.insert(redactionManifestTable).values(rows.map((row, index) => ({
|
|
12
|
+
id: `${manifest.id}:${index}`,
|
|
13
|
+
eventId,
|
|
14
|
+
eventType,
|
|
15
|
+
fieldName: row.fieldName,
|
|
16
|
+
action: row.action,
|
|
17
|
+
originalValueHash: null,
|
|
18
|
+
createdAt: manifest.createdAt,
|
|
19
|
+
})));
|
|
20
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Second Nature Host Setup Guide
|
|
2
|
+
|
|
3
|
+
This file ships inside the published plugin package.
|
|
4
|
+
|
|
5
|
+
Use it after installing `@haaaiawd/second-nature` in an OpenClaw host to complete the minimum runtime setup and avoid pretending the system is fully connected before it is.
|
|
6
|
+
|
|
7
|
+
## What to check first
|
|
8
|
+
|
|
9
|
+
Confirm these in order:
|
|
10
|
+
|
|
11
|
+
1. The plugin is installed and enabled.
|
|
12
|
+
2. `workspace/` exists in the host environment.
|
|
13
|
+
3. The anchor files exist:
|
|
14
|
+
- `workspace/SOUL.md`
|
|
15
|
+
- `workspace/USER.md`
|
|
16
|
+
- `workspace/IDENTITY.md`
|
|
17
|
+
- `workspace/MEMORY.md`
|
|
18
|
+
4. Platform credentials are present, or the missing ones are clearly identified.
|
|
19
|
+
5. The command surface is working before trying heartbeat or connector flows.
|
|
20
|
+
|
|
21
|
+
## Minimum workspace setup
|
|
22
|
+
|
|
23
|
+
If the anchor files are missing, create short first-person versions that are actually usable.
|
|
24
|
+
|
|
25
|
+
- `SOUL.md`: values, stance, what I care about, what I refuse to become
|
|
26
|
+
- `USER.md`: who the user is to me, how I should relate to them, what matters to them
|
|
27
|
+
- `IDENTITY.md`: who I am, my role, my behavioral boundaries
|
|
28
|
+
- `MEMORY.md`: stable facts and continuity worth carrying forward
|
|
29
|
+
|
|
30
|
+
Do not leave them as empty headings.
|
|
31
|
+
|
|
32
|
+
## Platform prerequisites
|
|
33
|
+
|
|
34
|
+
Check platform readiness honestly.
|
|
35
|
+
|
|
36
|
+
### Moltbook
|
|
37
|
+
|
|
38
|
+
Look for a usable credential first.
|
|
39
|
+
|
|
40
|
+
### InStreet
|
|
41
|
+
|
|
42
|
+
Check whether the credential is already `active` or still `pending_verification`.
|
|
43
|
+
|
|
44
|
+
### EvoMap
|
|
45
|
+
|
|
46
|
+
Check whether a `node_secret` already exists.
|
|
47
|
+
Without it, heartbeat, work discovery, and task claim will not be truly connected.
|
|
48
|
+
|
|
49
|
+
## Command surface to inspect
|
|
50
|
+
|
|
51
|
+
Use these first:
|
|
52
|
+
|
|
53
|
+
- `status`
|
|
54
|
+
- `credential`
|
|
55
|
+
- `quiet`
|
|
56
|
+
- `report`
|
|
57
|
+
- `session`
|
|
58
|
+
- `explain`
|
|
59
|
+
|
|
60
|
+
The purpose is simple:
|
|
61
|
+
|
|
62
|
+
1. verify the plugin is alive
|
|
63
|
+
2. verify commands are usable
|
|
64
|
+
3. see where credentials are blocked
|
|
65
|
+
4. see whether reports and explain flows already have evidence to read back
|
|
66
|
+
|
|
67
|
+
## About heartbeat
|
|
68
|
+
|
|
69
|
+
Do not claim heartbeat is connected unless there is evidence.
|
|
70
|
+
|
|
71
|
+
Look for:
|
|
72
|
+
|
|
73
|
+
- heartbeat-related records in `report`
|
|
74
|
+
- evidence in `explain`
|
|
75
|
+
- signs of `heartbeat_bridge` in runtime records
|
|
76
|
+
|
|
77
|
+
If that evidence does not exist, report that heartbeat bridge is not yet confirmed in the host.
|
|
78
|
+
|
|
79
|
+
## About direct user replies
|
|
80
|
+
|
|
81
|
+
Direct chat with the user should keep very light continuity.
|
|
82
|
+
|
|
83
|
+
- do keep continuity
|
|
84
|
+
- do not use post-reply tone
|
|
85
|
+
- do not pretend the direct user reply path is connected unless you can observe evidence
|
|
86
|
+
|
|
87
|
+
If continuity is not visible, report that the `user_reply` host entry is not yet confirmed.
|
|
88
|
+
|
|
89
|
+
## Reporting template
|
|
90
|
+
|
|
91
|
+
When setup inspection is done, report in this structure:
|
|
92
|
+
|
|
93
|
+
1. Plugin state
|
|
94
|
+
2. Workspace state
|
|
95
|
+
3. Platform credential state
|
|
96
|
+
4. Command/tool/service state
|
|
97
|
+
5. Heartbeat evidence
|
|
98
|
+
6. Direct user reply continuity evidence
|
|
99
|
+
7. Current blockers
|
|
100
|
+
|
|
101
|
+
## Important reminder
|
|
102
|
+
|
|
103
|
+
This guide is only for installation and host bring-up.
|
|
104
|
+
|
|
105
|
+
Long-term principles should move into:
|
|
106
|
+
|
|
107
|
+
- `workspace/SOUL.md`
|
|
108
|
+
- `workspace/USER.md`
|
|
109
|
+
- `workspace/IDENTITY.md`
|
|
110
|
+
- `workspace/MEMORY.md`
|
|
111
|
+
|
|
112
|
+
Do not depend on this file as the long-term memory source.
|