agentera 3.0.0-dev.4 → 3.0.0-dev.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/bundle/.agentera-npx-bundle.json +1 -1
- package/bundle/references/adapters/opencode.md +1 -1
- package/bundle/references/adapters/package-registry.yaml +0 -1
- package/bundle/references/adapters/package-surface-characterization.md +1 -2
- package/bundle/references/analysis/startup-measurement-contract.yaml +11 -11
- package/bundle/references/cli/agent-ready-state-contract.yaml +5 -5
- package/bundle/references/cli/audience-namespace-cli-migration.yaml +40 -26
- package/bundle/references/cli/bundle-skill-vocabulary.yaml +2 -30
- package/bundle/references/cli/capability-instruction-contract.yaml +98 -57
- package/bundle/references/cli/coexistence-probe.yaml +9 -0
- package/bundle/references/cli/routing-execution-vocabulary.yaml +6 -6
- package/bundle/references/cli/single-name-protocol.yaml +42 -0
- package/bundle/references/cli/update-channels.yaml +18 -2
- package/bundle/references/cli/upgrade-repair-wording.md +31 -0
- package/bundle/references/cli/v3-handoff-manifest.schema.yaml +98 -0
- package/bundle/references/cli/vocabulary-index.yaml +3 -3
- package/bundle/references/cli/vocabulary.md +34 -26
- package/bundle/references/meta/documentation-inventory.md +9 -3
- package/bundle/registry.json +1 -1
- package/bundle/skills/agentera/SKILL.md +50 -33
- package/bundle/skills/agentera/agents/dokumentera.toml +1 -1
- package/bundle/skills/agentera/agents/hej.toml +1 -1
- package/bundle/skills/agentera/agents/inspektera.toml +1 -1
- package/bundle/skills/agentera/agents/inspirera.toml +1 -1
- package/bundle/skills/agentera/agents/optimera.toml +1 -1
- package/bundle/skills/agentera/agents/orkestrera.toml +1 -1
- package/bundle/skills/agentera/agents/planera.toml +1 -1
- package/bundle/skills/agentera/agents/profilera.toml +1 -1
- package/bundle/skills/agentera/agents/realisera.toml +1 -1
- package/bundle/skills/agentera/agents/resonera.toml +1 -1
- package/bundle/skills/agentera/agents/visionera.toml +1 -1
- package/bundle/skills/agentera/agents/visualisera.toml +1 -1
- package/bundle/skills/agentera/capabilities/orkestrera/schemas/validation.yaml +26 -13
- package/bundle/skills/agentera/capability_schema_contract.yaml +33 -14
- package/bundle/skills/agentera/references/contract.md +2 -2
- package/bundle/skills/agentera/schemas/artifacts/decisions.yaml +1 -1
- package/bundle/skills/agentera/schemas/artifacts/progress.yaml +15 -36
- package/bundle/skills/agentera/schemas/artifacts/todo.yaml +14 -0
- package/dist/analytics/extractCorpus/cli.js +101 -0
- package/dist/analytics/extractCorpus/cli.js.map +1 -0
- package/dist/analytics/extractCorpus/copilotSessions.js +231 -0
- package/dist/analytics/extractCorpus/copilotSessions.js.map +1 -0
- package/dist/analytics/extractCorpus/core.js +357 -0
- package/dist/analytics/extractCorpus/core.js.map +1 -0
- package/dist/analytics/extractCorpus/corpus.js +132 -0
- package/dist/analytics/extractCorpus/corpus.js.map +1 -0
- package/dist/analytics/extractCorpus/cursorSessions.js +420 -0
- package/dist/analytics/extractCorpus/cursorSessions.js.map +1 -0
- package/dist/analytics/extractCorpus/filesystemSources.js +122 -0
- package/dist/analytics/extractCorpus/filesystemSources.js.map +1 -0
- package/dist/analytics/extractCorpus/index.js +9 -0
- package/dist/analytics/extractCorpus/index.js.map +1 -0
- package/dist/analytics/extractCorpus/jsonlSessions.js +185 -0
- package/dist/analytics/extractCorpus/jsonlSessions.js.map +1 -0
- package/dist/analytics/extractCorpus/sqliteSessions.js +275 -0
- package/dist/analytics/extractCorpus/sqliteSessions.js.map +1 -0
- package/dist/analytics/extractCorpus.js +2 -1790
- package/dist/analytics/extractCorpus.js.map +1 -1
- package/dist/analytics/usageStats.js +1 -1
- package/dist/analytics/usageStats.js.map +1 -1
- package/dist/capabilities/dokumentera/instructions.js +6 -0
- package/dist/capabilities/dokumentera/instructions.js.map +1 -0
- package/dist/capabilities/hej/instructions.js +6 -0
- package/dist/capabilities/hej/instructions.js.map +1 -0
- package/dist/capabilities/index.js +38 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/inspektera/instructions.js +6 -0
- package/dist/capabilities/inspektera/instructions.js.map +1 -0
- package/dist/capabilities/inspirera/instructions.js +6 -0
- package/dist/capabilities/inspirera/instructions.js.map +1 -0
- package/dist/capabilities/optimera/instructions.js +6 -0
- package/dist/capabilities/optimera/instructions.js.map +1 -0
- package/dist/capabilities/orkestrera/instructions.js +6 -0
- package/dist/capabilities/orkestrera/instructions.js.map +1 -0
- package/dist/capabilities/planera/instructions.js +6 -0
- package/dist/capabilities/planera/instructions.js.map +1 -0
- package/dist/capabilities/profilera/instructions.js +6 -0
- package/dist/capabilities/profilera/instructions.js.map +1 -0
- package/dist/capabilities/realisera/instructions.js +6 -0
- package/dist/capabilities/realisera/instructions.js.map +1 -0
- package/dist/capabilities/resonera/instructions.js +6 -0
- package/dist/capabilities/resonera/instructions.js.map +1 -0
- package/dist/capabilities/visionera/instructions.js +6 -0
- package/dist/capabilities/visionera/instructions.js.map +1 -0
- package/dist/capabilities/visualisera/instructions.js +6 -0
- package/dist/capabilities/visualisera/instructions.js.map +1 -0
- package/dist/cli/capabilityContext/benchmark.js +557 -0
- package/dist/cli/capabilityContext/benchmark.js.map +1 -0
- package/dist/cli/capabilityContext/bespoke.js +25 -0
- package/dist/cli/capabilityContext/bespoke.js.map +1 -0
- package/dist/cli/capabilityContext/closeout.js +230 -0
- package/dist/cli/capabilityContext/closeout.js.map +1 -0
- package/dist/cli/capabilityContext/contract.js +186 -0
- package/dist/cli/capabilityContext/contract.js.map +1 -0
- package/dist/cli/capabilityContext/evidence.js +446 -0
- package/dist/cli/capabilityContext/evidence.js.map +1 -0
- package/dist/cli/capabilityContext/index.js +4 -0
- package/dist/cli/capabilityContext/index.js.map +1 -0
- package/dist/cli/capabilityContext/orchestration.js +107 -0
- package/dist/cli/capabilityContext/orchestration.js.map +1 -0
- package/dist/cli/capabilityContext/planState.js +271 -0
- package/dist/cli/capabilityContext/planState.js.map +1 -0
- package/dist/cli/capabilityContext/progress.js +96 -0
- package/dist/cli/capabilityContext/progress.js.map +1 -0
- package/dist/cli/capabilityContext/realisera.js +174 -0
- package/dist/cli/capabilityContext/realisera.js.map +1 -0
- package/dist/cli/capabilityContext/shared.js +94 -0
- package/dist/cli/capabilityContext/shared.js.map +1 -0
- package/dist/cli/capabilityContext/slim.js +106 -0
- package/dist/cli/capabilityContext/slim.js.map +1 -0
- package/dist/cli/capabilityContext/startup.js +208 -0
- package/dist/cli/capabilityContext/startup.js.map +1 -0
- package/dist/cli/capabilityContext/types.js +43 -0
- package/dist/cli/capabilityContext/types.js.map +1 -0
- package/dist/cli/capabilityContext.js +1 -2420
- package/dist/cli/capabilityContext.js.map +1 -1
- package/dist/cli/commands/capability.js +1 -8
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/compact.js +1 -1
- package/dist/cli/commands/compact.js.map +1 -1
- package/dist/cli/commands/doctor.js +35 -6
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/lint.js +4 -36
- package/dist/cli/commands/lint.js.map +1 -1
- package/dist/cli/commands/query.js +1 -1
- package/dist/cli/commands/query.js.map +1 -1
- package/dist/cli/commands/report.js +11 -2
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/schema.js +1 -2
- package/dist/cli/commands/schema.js.map +1 -1
- package/dist/cli/commands/state/decisions.js +397 -0
- package/dist/cli/commands/state/decisions.js.map +1 -0
- package/dist/cli/commands/state/docs.js +93 -0
- package/dist/cli/commands/state/docs.js.map +1 -0
- package/dist/cli/commands/state/experiments.js +67 -0
- package/dist/cli/commands/state/experiments.js.map +1 -0
- package/dist/cli/commands/state/health.js +114 -0
- package/dist/cli/commands/state/health.js.map +1 -0
- package/dist/cli/commands/state/index.js +51 -0
- package/dist/cli/commands/state/index.js.map +1 -0
- package/dist/cli/commands/state/objective.js +68 -0
- package/dist/cli/commands/state/objective.js.map +1 -0
- package/dist/cli/commands/state/plan.js +172 -0
- package/dist/cli/commands/state/plan.js.map +1 -0
- package/dist/cli/commands/state/progress.js +47 -0
- package/dist/cli/commands/state/progress.js.map +1 -0
- package/dist/cli/commands/state/shared.js +15 -0
- package/dist/cli/commands/state/shared.js.map +1 -0
- package/dist/cli/commands/state/todo.js +121 -0
- package/dist/cli/commands/state/todo.js.map +1 -0
- package/dist/cli/commands/state.js +29 -18
- package/dist/cli/commands/state.js.map +1 -1
- package/dist/cli/commands/validate.js +44 -20
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/dispatch/check.js +328 -0
- package/dist/cli/dispatch/check.js.map +1 -0
- package/dist/cli/dispatch/index.js +177 -0
- package/dist/cli/dispatch/index.js.map +1 -0
- package/dist/cli/dispatch/lifecycle.js +492 -0
- package/dist/cli/dispatch/lifecycle.js.map +1 -0
- package/dist/cli/dispatch/prime.js +100 -0
- package/dist/cli/dispatch/prime.js.map +1 -0
- package/dist/cli/dispatch/shared.js +64 -0
- package/dist/cli/dispatch/shared.js.map +1 -0
- package/dist/cli/dispatch/state.js +149 -0
- package/dist/cli/dispatch/state.js.map +1 -0
- package/dist/cli/dispatch.js +1 -995
- package/dist/cli/dispatch.js.map +1 -1
- package/dist/cli/errors.js +53 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/help.js +1 -3
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/orientation.js +10 -7
- package/dist/cli/orientation.js.map +1 -1
- package/dist/cli/stateQuery.js +7 -0
- package/dist/cli/stateQuery.js.map +1 -1
- package/dist/cli/todoMarkdown.js +33 -0
- package/dist/cli/todoMarkdown.js.map +1 -0
- package/dist/hooks/common.js +8 -25
- package/dist/hooks/common.js.map +1 -1
- package/dist/hooks/compaction/apply.js +244 -0
- package/dist/hooks/compaction/apply.js.map +1 -0
- package/dist/hooks/compaction/dryRun.js +181 -0
- package/dist/hooks/compaction/dryRun.js.map +1 -0
- package/dist/hooks/compaction/index.js +23 -0
- package/dist/hooks/compaction/index.js.map +1 -0
- package/dist/hooks/compaction/parse.js +129 -0
- package/dist/hooks/compaction/parse.js.map +1 -0
- package/dist/hooks/compaction/retention.js +197 -0
- package/dist/hooks/compaction/retention.js.map +1 -0
- package/dist/hooks/compaction/status.js +243 -0
- package/dist/hooks/compaction/status.js.map +1 -0
- package/dist/hooks/compaction/types.js +6 -0
- package/dist/hooks/compaction/types.js.map +1 -0
- package/dist/hooks/compaction.js +20 -20
- package/dist/hooks/compaction.js.map +1 -1
- package/dist/hooks/cursorPreToolUse.js +1 -1
- package/dist/hooks/cursorPreToolUse.js.map +1 -1
- package/dist/hooks/sessionStart.js +4 -4
- package/dist/hooks/sessionStart.js.map +1 -1
- package/dist/hooks/sessionStop.js +3 -12
- package/dist/hooks/sessionStop.js.map +1 -1
- package/dist/hooks/validateArtifact/agentFacing.js +10 -0
- package/dist/hooks/validateArtifact/agentFacing.js.map +1 -0
- package/dist/hooks/validateArtifact/index.js +149 -0
- package/dist/hooks/validateArtifact/index.js.map +1 -0
- package/dist/hooks/validateArtifact/markdown.js +95 -0
- package/dist/hooks/validateArtifact/markdown.js.map +1 -0
- package/dist/hooks/validateArtifact/runtime.js +83 -0
- package/dist/hooks/validateArtifact/runtime.js.map +1 -0
- package/dist/hooks/validateArtifact/schema.js +455 -0
- package/dist/hooks/validateArtifact/schema.js.map +1 -0
- package/dist/hooks/validateArtifact/traversal.js +105 -0
- package/dist/hooks/validateArtifact/traversal.js.map +1 -0
- package/dist/hooks/validateArtifact/violations.js +105 -0
- package/dist/hooks/validateArtifact/violations.js.map +1 -0
- package/dist/hooks/validateArtifact.js +40 -49
- package/dist/hooks/validateArtifact.js.map +1 -1
- package/dist/migrate/v2HandoffManifest.js +333 -0
- package/dist/migrate/v2HandoffManifest.js.map +1 -0
- package/dist/registries/artifactProtocolIds.js +77 -0
- package/dist/registries/artifactProtocolIds.js.map +1 -0
- package/dist/registries/capabilityContract.js +12 -11
- package/dist/registries/capabilityContract.js.map +1 -1
- package/dist/registries/evaluatorHandoffContract.js +171 -0
- package/dist/registries/evaluatorHandoffContract.js.map +1 -0
- package/dist/release/releaseMetadata.js +235 -0
- package/dist/release/releaseMetadata.js.map +1 -0
- package/dist/setup/codex/agents.js +96 -0
- package/dist/setup/codex/agents.js.map +1 -0
- package/dist/setup/codex/cli.js +161 -0
- package/dist/setup/codex/cli.js.map +1 -0
- package/dist/setup/codex/configToml.js +644 -0
- package/dist/setup/codex/configToml.js.map +1 -0
- package/dist/setup/codex/constants.js +29 -0
- package/dist/setup/codex/constants.js.map +1 -0
- package/dist/setup/codex/installRoot.js +64 -0
- package/dist/setup/codex/installRoot.js.map +1 -0
- package/dist/setup/codex/state.js +270 -0
- package/dist/setup/codex/state.js.map +1 -0
- package/dist/setup/codex.js +11 -1055
- package/dist/setup/codex.js.map +1 -1
- package/dist/setup/doctor/core.js +300 -0
- package/dist/setup/doctor/core.js.map +1 -0
- package/dist/setup/doctor/diagnostics.js +247 -0
- package/dist/setup/doctor/diagnostics.js.map +1 -0
- package/dist/setup/doctor/opencode.js +281 -0
- package/dist/setup/doctor/opencode.js.map +1 -0
- package/dist/setup/doctor/report.js +474 -0
- package/dist/setup/doctor/report.js.map +1 -0
- package/dist/setup/doctor.js +9 -1296
- package/dist/setup/doctor.js.map +1 -1
- package/dist/setup/opencode.js +13 -0
- package/dist/setup/opencode.js.map +1 -0
- package/dist/setup/smokeChecks.js +1 -1
- package/dist/setup/smokeChecks.js.map +1 -1
- package/dist/state/progressCommit.js +1 -1
- package/dist/state/progressCommit.js.map +1 -1
- package/dist/state/startupAnalysis/benchmark.js +367 -0
- package/dist/state/startupAnalysis/benchmark.js.map +1 -0
- package/dist/state/startupAnalysis/contract.js +122 -0
- package/dist/state/startupAnalysis/contract.js.map +1 -0
- package/dist/state/startupAnalysis/helpers.js +332 -0
- package/dist/state/startupAnalysis/helpers.js.map +1 -0
- package/dist/state/startupAnalysis/index.js +7 -0
- package/dist/state/startupAnalysis/index.js.map +1 -0
- package/dist/state/startupAnalysis/metrics.js +334 -0
- package/dist/state/startupAnalysis/metrics.js.map +1 -0
- package/dist/state/startupAnalysis/records.js +195 -0
- package/dist/state/startupAnalysis/records.js.map +1 -0
- package/dist/state/startupAnalysis/report.js +123 -0
- package/dist/state/startupAnalysis/report.js.map +1 -0
- package/dist/state/startupAnalysis/threshold.js +500 -0
- package/dist/state/startupAnalysis/threshold.js.map +1 -0
- package/dist/state/startupAnalysis.js +2 -1952
- package/dist/state/startupAnalysis.js.map +1 -1
- package/dist/upgrade/coexistenceProbe.js +83 -0
- package/dist/upgrade/coexistenceProbe.js.map +1 -0
- package/dist/upgrade/doctor.js +41 -2
- package/dist/upgrade/doctor.js.map +1 -1
- package/dist/upgrade/migrateArtifactsV1ToV2.js +0 -1
- package/dist/upgrade/migrateArtifactsV1ToV2.js.map +1 -1
- package/dist/upgrade/migrateArtifactsV2ToV3.js +5 -83
- package/dist/upgrade/migrateArtifactsV2ToV3.js.map +1 -1
- package/dist/upgrade/nextMajorDoctor.js +136 -0
- package/dist/upgrade/nextMajorDoctor.js.map +1 -0
- package/dist/upgrade/projectIntegration.js +3 -1
- package/dist/upgrade/projectIntegration.js.map +1 -1
- package/dist/upgrade/runtimeMigration.js +32 -5
- package/dist/upgrade/runtimeMigration.js.map +1 -1
- package/dist/upgrade/v3CapabilitySurface.js +15 -0
- package/dist/upgrade/v3CapabilitySurface.js.map +1 -0
- package/dist/upgrade/versionResolution.js +12 -4
- package/dist/upgrade/versionResolution.js.map +1 -1
- package/dist/validate/appHomeContract.js +4 -4
- package/dist/validate/appHomeContract.js.map +1 -1
- package/dist/validate/capability.js +11 -3
- package/dist/validate/capability.js.map +1 -1
- package/dist/validate/selfAudit.js +62 -20
- package/dist/validate/selfAudit.js.map +1 -1
- package/dist/validate/vocabularyAuthority.js +298 -0
- package/dist/validate/vocabularyAuthority.js.map +1 -0
- package/package.json +4 -4
- package/bundle/references/v1-section-mapping.md +0 -47
- package/bundle/skills/agentera/capabilities/dokumentera/instructions.md +0 -428
- package/bundle/skills/agentera/capabilities/hej/instructions.md +0 -331
- package/bundle/skills/agentera/capabilities/inspektera/instructions.md +0 -514
- package/bundle/skills/agentera/capabilities/inspirera/instructions.md +0 -280
- package/bundle/skills/agentera/capabilities/optimera/instructions.md +0 -437
- package/bundle/skills/agentera/capabilities/orkestrera/instructions.md +0 -433
- package/bundle/skills/agentera/capabilities/planera/instructions.md +0 -368
- package/bundle/skills/agentera/capabilities/profilera/instructions.md +0 -419
- package/bundle/skills/agentera/capabilities/realisera/instructions.md +0 -403
- package/bundle/skills/agentera/capabilities/resonera/instructions.md +0 -329
- package/bundle/skills/agentera/capabilities/visionera/instructions.md +0 -309
- package/bundle/skills/agentera/capabilities/visualisera/instructions.md +0 -400
- package/bundle/skills/hej/.claude-plugin/plugin.json +0 -6
- package/bundle/skills/hej/SKILL.md +0 -69
- package/bundle/skills/hej/agents/hej.toml +0 -11
- package/bundle/skills/hej/agents/openai.yaml +0 -8
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { Flt, formatFloat, pyFmt, pyJsonDumps, pyJsonString } from "./helpers.js";
|
|
4
|
+
export const STARTUP_REPORT_MARKDOWN = "startup-overhead-report.md";
|
|
5
|
+
export const STARTUP_REPORT_JSON = "startup-overhead-report.json";
|
|
6
|
+
/** Python json.dumps(value, indent=2, sort_keys=True) — multiline, ensure_ascii, Flt-aware. */
|
|
7
|
+
function pyJsonIndent(value, level = 0, indent = " ") {
|
|
8
|
+
const pad = indent.repeat(level);
|
|
9
|
+
const childPad = indent.repeat(level + 1);
|
|
10
|
+
if (value === null || value === undefined)
|
|
11
|
+
return "null";
|
|
12
|
+
if (value === true)
|
|
13
|
+
return "true";
|
|
14
|
+
if (value === false)
|
|
15
|
+
return "false";
|
|
16
|
+
if (value instanceof Flt)
|
|
17
|
+
return formatFloat(value.v);
|
|
18
|
+
if (typeof value === "number")
|
|
19
|
+
return String(value);
|
|
20
|
+
if (typeof value === "string")
|
|
21
|
+
return pyJsonString(value);
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
if (value.length === 0)
|
|
24
|
+
return "[]";
|
|
25
|
+
const items = value.map((v) => childPad + pyJsonIndent(v, level + 1, indent));
|
|
26
|
+
return "[\n" + items.join(",\n") + "\n" + pad + "]";
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === "object") {
|
|
29
|
+
const keys = Object.keys(value).sort();
|
|
30
|
+
if (keys.length === 0)
|
|
31
|
+
return "{}";
|
|
32
|
+
const items = keys.map((k) => childPad + pyJsonString(k) + ": " + pyJsonIndent(value[k], level + 1, indent));
|
|
33
|
+
return "{\n" + items.join(",\n") + "\n" + pad + "}";
|
|
34
|
+
}
|
|
35
|
+
return "null";
|
|
36
|
+
}
|
|
37
|
+
function markdownTable(headers, rows) {
|
|
38
|
+
const lines = [
|
|
39
|
+
"| " + headers.join(" | ") + " |",
|
|
40
|
+
"| " + headers.map(() => "---").join(" | ") + " |",
|
|
41
|
+
];
|
|
42
|
+
if (rows.length === 0) {
|
|
43
|
+
return [...lines, "| " + headers.map(() => "none").join(" | ") + " |"];
|
|
44
|
+
}
|
|
45
|
+
return [...lines, ...rows.map((row) => "| " + row.map((v) => pyFmt(v)).join(" | ") + " |")];
|
|
46
|
+
}
|
|
47
|
+
export function renderStartupReport(metrics) {
|
|
48
|
+
const threshold = (metrics.threshold_derivation ?? {}).action_thresholds ?? {};
|
|
49
|
+
const envelopeThreshold = threshold.startup_envelope ?? {};
|
|
50
|
+
const guidanceThreshold = threshold.targeted_guidance ?? {};
|
|
51
|
+
const recommendation = metrics.startup_recommendation ?? {};
|
|
52
|
+
const measuredDistribution = (metrics.threshold_derivation ?? {}).measured_distribution ?? {};
|
|
53
|
+
const runtimeCoverage = Array.isArray(metrics.runtime_coverage) ? metrics.runtime_coverage : [];
|
|
54
|
+
const capabilityCounts = metrics.per_capability_state_counts ?? {};
|
|
55
|
+
const lines = [
|
|
56
|
+
"# Agentera Startup State-Access Analysis",
|
|
57
|
+
"",
|
|
58
|
+
"This report is local-only and privacy-preserving. It measures raw Agentera artifact access after CLI state calls during capability startup/state gathering.",
|
|
59
|
+
"",
|
|
60
|
+
"## Boundary Source",
|
|
61
|
+
"",
|
|
62
|
+
`- Contract version: \`${pyFmt(metrics.contract_version)}\``,
|
|
63
|
+
`- Boundary source: \`${pyFmt(metrics.boundary_source)}\``,
|
|
64
|
+
`- Boundary commit: \`${pyFmt(metrics.boundary_commit)}\``,
|
|
65
|
+
`- Boundary timestamp: \`${pyFmt(metrics.boundary_committed_at)}\``,
|
|
66
|
+
`- Corpus adapter version: \`${pyFmt(metrics.corpus_adapter_version)}\``,
|
|
67
|
+
"",
|
|
68
|
+
"## Benchmark Window",
|
|
69
|
+
"",
|
|
70
|
+
`- Mode: \`${pyFmt(metrics.benchmark_mode)}\``,
|
|
71
|
+
`- Previous watermark: \`${pyFmt(metrics.benchmark_previous_watermark_at)}\``,
|
|
72
|
+
`- Window started after: \`${pyFmt(metrics.benchmark_window_started_after)}\``,
|
|
73
|
+
`- Watermark: \`${pyFmt(metrics.benchmark_watermark_at)}\``,
|
|
74
|
+
"",
|
|
75
|
+
"## Runtime Coverage",
|
|
76
|
+
"",
|
|
77
|
+
];
|
|
78
|
+
const runtimeRows = [];
|
|
79
|
+
for (const status of runtimeCoverage) {
|
|
80
|
+
if (status && typeof status === "object" && !Array.isArray(status)) {
|
|
81
|
+
runtimeRows.push([
|
|
82
|
+
status.runtime ?? "unknown",
|
|
83
|
+
status.status ?? "unknown",
|
|
84
|
+
status.reason ?? "unknown",
|
|
85
|
+
status.record_count ?? 0,
|
|
86
|
+
status.candidate_count ?? 0,
|
|
87
|
+
status.error_count ?? 0,
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
lines.push(...markdownTable(["Runtime", "Status", "Reason", "Records", "Candidates", "Errors"], runtimeRows));
|
|
92
|
+
lines.push("", "## Metrics", "", `- Total state-gathering sequences: \`${pyFmt(metrics.total_state_sequences)}\``, `- Sequences with raw artifact access after CLI: \`${pyFmt(metrics.state_sequences_with_raw_after_cli)}\``, `- Sequences with redundant raw artifact access: \`${pyFmt(metrics.state_sequences_with_redundant_raw_access)}\``, `- Raw-after-CLI sequence rate: \`${pyFmt(metrics.raw_after_cli_sequence_rate)}\``, `- Redundant raw sequence rate: \`${pyFmt(metrics.redundant_raw_sequence_rate)}\``, `- CLI state command counts: \`${pyJsonDumps(metrics.cli_state_command_counts ?? {})}\``, `- Raw artifact access after CLI counts: \`${pyJsonDumps(metrics.raw_artifact_access_after_cli_counts ?? {})}\``, `- Redundant raw artifact access counts: \`${pyJsonDumps(metrics.redundant_raw_artifact_access_counts ?? {})}\``, "", "## Estimated Token Impact", "", `- Token estimator version: \`${pyFmt(metrics.token_estimator_version)}\``, `- Estimated raw-after-CLI tokens: \`${pyFmt(metrics.estimated_raw_after_cli_tokens)}\``, `- Estimated redundant raw tokens: \`${pyFmt(metrics.estimated_redundant_raw_tokens)}\``, `- Estimated raw-after-CLI tokens by artifact: \`${pyJsonDumps(metrics.estimated_raw_after_cli_tokens_by_artifact ?? {})}\``, `- Estimated redundant raw tokens by artifact: \`${pyJsonDumps(metrics.estimated_redundant_raw_tokens_by_artifact ?? {})}\``, `- Estimated tokens saved vs previous: \`${pyFmt(metrics.estimated_tokens_saved_vs_previous)}\``, `- Estimated tokens saved null reason: \`${pyFmt(metrics.estimated_tokens_saved_vs_previous_null_reason)}\``, "");
|
|
93
|
+
const capabilityRows = [];
|
|
94
|
+
for (const capability of Object.keys(capabilityCounts).sort()) {
|
|
95
|
+
const counts = capabilityCounts[capability];
|
|
96
|
+
if (counts && typeof counts === "object" && !Array.isArray(counts)) {
|
|
97
|
+
capabilityRows.push([
|
|
98
|
+
capability,
|
|
99
|
+
counts.state_sequences ?? 0,
|
|
100
|
+
counts.cli_state_call ?? 0,
|
|
101
|
+
counts.raw_artifact_access_after_cli ?? 0,
|
|
102
|
+
counts.redundant_raw_artifact_access ?? 0,
|
|
103
|
+
counts.capability_prose_read ?? 0,
|
|
104
|
+
]);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
lines.push(...markdownTable(["Capability", "Sequences", "CLI Calls", "Raw After CLI", "Redundant Raw", "Prose Reads"], capabilityRows));
|
|
108
|
+
lines.push("", "## Threshold Rationale", "", `- Startup envelope threshold credible: \`${pyFmt(envelopeThreshold.credible)}\``, `- Redundant-sequence threshold: \`${pyFmt(envelopeThreshold.redundant_sequence_threshold)}\``, `- Startup envelope selection reason: ${pyFmt(envelopeThreshold.selection_reason)}`, `- Targeted-guidance selection reason: ${pyFmt(guidanceThreshold.selection_reason)}`, `- Measured distribution: \`${pyJsonDumps(measuredDistribution)}\``, "", "## Recommendation", "", `- Action: \`${pyFmt(recommendation.action)}\``, `- Measured trigger: \`${pyFmt(recommendation.measured_trigger)}\``, `- Rationale: ${pyFmt(recommendation.rationale)}`, `- Implementation recommended: \`${pyFmt(metrics.implementation_recommended)}\``, "", "## Privacy Caveats", "", "- Raw transcript text is not emitted.", "- Full local paths and raw store paths are not emitted.", "- Session identifiers are salted or omitted.", "- Raw artifact accesses use canonical artifact_id labels such as `plan`, not filesystem paths.", "- Runtime coverage may be incomplete or degraded; inspect `confidence_caveats` before selecting follow-up work.", "");
|
|
109
|
+
return lines.join("\n");
|
|
110
|
+
}
|
|
111
|
+
export function writeStartupReports(metrics, outputDir) {
|
|
112
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
113
|
+
const jsonPath = path.join(outputDir, STARTUP_REPORT_JSON);
|
|
114
|
+
const markdownPath = path.join(outputDir, STARTUP_REPORT_MARKDOWN);
|
|
115
|
+
fs.writeFileSync(jsonPath, pyJsonIndent(metrics) + "\n");
|
|
116
|
+
fs.writeFileSync(markdownPath, renderStartupReport(metrics));
|
|
117
|
+
return { structured: jsonPath, human_readable: markdownPath };
|
|
118
|
+
}
|
|
119
|
+
// ===========================================================================
|
|
120
|
+
// Slice 6: benchmark persistence + intermediate building + corpus-file extraction
|
|
121
|
+
// (extract_*_from_runtime_stores depends on extract_corpus and lands in Phase 10)
|
|
122
|
+
// ===========================================================================
|
|
123
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/state/startupAnalysis/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import { canonicalArtifactLabel, hashLabel, loadContract } from "./contract.js";
|
|
2
|
+
import { inc, counterDict, countMatches, recordLabel, recordThresholdText, detailMetrics, thresholdWarnings, detailLossStatus, argumentsText, CLI_COMMAND_ARTIFACTS, QUERY_ARTIFACTS, toolName, toolArgument, capabilityInvocation, introCapability, BUDGET_PRESSURE_RE, FULL_PLAN_BUDGET_RE, POST_AUDIT_FLAG_RE, } from "./helpers.js";
|
|
3
|
+
export const THRESHOLD_EVIDENCE_ENVELOPE = "threshold_evidence_scan_v1";
|
|
4
|
+
export const THRESHOLD_CLASSIFICATION_ENVELOPE = "threshold_evidence_classification_v1";
|
|
5
|
+
export const STATE_EVENT_CLASSES = new Set([
|
|
6
|
+
"cli_state_call",
|
|
7
|
+
"raw_artifact_access",
|
|
8
|
+
"capability_prose_read",
|
|
9
|
+
"implementation_boundary",
|
|
10
|
+
"non_state_context",
|
|
11
|
+
]);
|
|
12
|
+
export const BOUNDARY_DEGRADATION_REASONS = new Set([
|
|
13
|
+
"pre_boundary_record",
|
|
14
|
+
"missing_timestamp",
|
|
15
|
+
"malformed_record",
|
|
16
|
+
"missing_conversation_key",
|
|
17
|
+
"no_agentera_state_sequence",
|
|
18
|
+
"privacy_redaction_required",
|
|
19
|
+
]);
|
|
20
|
+
export const BOUNDED_RUNTIME_STATUSES = new Set([
|
|
21
|
+
"ok",
|
|
22
|
+
"available",
|
|
23
|
+
"missing",
|
|
24
|
+
"sparse",
|
|
25
|
+
"degraded",
|
|
26
|
+
"skipped",
|
|
27
|
+
]);
|
|
28
|
+
export const BOUNDED_RUNTIME_REASONS = new Set([
|
|
29
|
+
"candidate_files_found",
|
|
30
|
+
"disabled",
|
|
31
|
+
"extractor_unimplemented",
|
|
32
|
+
"no_candidate_files",
|
|
33
|
+
"no_runtime_stores_approved",
|
|
34
|
+
"no_matching_records",
|
|
35
|
+
"records_extracted",
|
|
36
|
+
"schema_divergent",
|
|
37
|
+
"store_absent",
|
|
38
|
+
"store_locked",
|
|
39
|
+
"store_not_directory",
|
|
40
|
+
"store_unreadable",
|
|
41
|
+
]);
|
|
42
|
+
export function boundedRuntimeStatus(status) {
|
|
43
|
+
const runtime = String(status.runtime ?? "unknown");
|
|
44
|
+
const state = String(status.status ?? "degraded");
|
|
45
|
+
const reason = String(status.reason ?? "schema_divergent");
|
|
46
|
+
const item = {
|
|
47
|
+
runtime,
|
|
48
|
+
status: BOUNDED_RUNTIME_STATUSES.has(state) ? state : "degraded",
|
|
49
|
+
reason: BOUNDED_RUNTIME_REASONS.has(reason) ? reason : "schema_divergent",
|
|
50
|
+
};
|
|
51
|
+
for (const key of ["candidate_count", "record_count", "error_count"]) {
|
|
52
|
+
const value = status[key];
|
|
53
|
+
if (typeof value === "number" && Number.isInteger(value))
|
|
54
|
+
item[key] = value;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(status.remediation_labels)) {
|
|
57
|
+
item.remediation_labels = status.remediation_labels.map((l) => String(l));
|
|
58
|
+
}
|
|
59
|
+
return item;
|
|
60
|
+
}
|
|
61
|
+
export const STATE_CLI_COMMANDS = new Set([
|
|
62
|
+
"hej",
|
|
63
|
+
"prime",
|
|
64
|
+
"plan",
|
|
65
|
+
"progress",
|
|
66
|
+
"health",
|
|
67
|
+
"todo",
|
|
68
|
+
"decisions",
|
|
69
|
+
"docs",
|
|
70
|
+
"objective",
|
|
71
|
+
"experiments",
|
|
72
|
+
"query",
|
|
73
|
+
]);
|
|
74
|
+
export function startupConversationKey(record) {
|
|
75
|
+
const key = record.conversation_key;
|
|
76
|
+
if (typeof key === "string" && key)
|
|
77
|
+
return key;
|
|
78
|
+
const sid = record.session_id;
|
|
79
|
+
if (typeof sid === "string" && sid)
|
|
80
|
+
return sid;
|
|
81
|
+
const data = record.data;
|
|
82
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
83
|
+
const dsid = data.session_id;
|
|
84
|
+
if (typeof dsid === "string" && dsid)
|
|
85
|
+
return dsid;
|
|
86
|
+
}
|
|
87
|
+
const ssid = record.source_id;
|
|
88
|
+
if (typeof ssid === "string" && ssid)
|
|
89
|
+
return ssid;
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function stateCliCommand(command) {
|
|
93
|
+
if (!command)
|
|
94
|
+
return null;
|
|
95
|
+
const tokens = command.replace(/"/g, " ").replace(/'/g, " ").split(/\s+/).filter((t) => t);
|
|
96
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
97
|
+
if (tokens[i].endsWith("agentera") && STATE_CLI_COMMANDS.has(tokens[i + 1])) {
|
|
98
|
+
return tokens[i + 1];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
function stateCliArtifacts(command, stateCommand) {
|
|
104
|
+
if (stateCommand === "query") {
|
|
105
|
+
const tokens = command.replace(/"/g, " ").replace(/'/g, " ").split(/\s+/).filter((t) => t);
|
|
106
|
+
for (let i = 0; i < tokens.length - 1; i++) {
|
|
107
|
+
if (tokens[i].endsWith("agentera") && tokens[i + 1] === "query") {
|
|
108
|
+
for (const arg of tokens.slice(i + 2)) {
|
|
109
|
+
const label = QUERY_ARTIFACTS[arg.toLowerCase()];
|
|
110
|
+
if (label)
|
|
111
|
+
return new Set([label]);
|
|
112
|
+
}
|
|
113
|
+
return new Set();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return new Set(CLI_COMMAND_ARTIFACTS[stateCommand] ?? []);
|
|
118
|
+
}
|
|
119
|
+
export function classifyStartupEvent(record) {
|
|
120
|
+
if (!record || typeof record !== "object" || Array.isArray(record) || record.source_kind !== "tool_call") {
|
|
121
|
+
return ["non_state_context", null, null, new Set()];
|
|
122
|
+
}
|
|
123
|
+
const tool = toolName(record).toLowerCase();
|
|
124
|
+
const command = toolArgument(record, "command");
|
|
125
|
+
if (tool === "bash") {
|
|
126
|
+
const stateCommand = stateCliCommand(command);
|
|
127
|
+
if (stateCommand) {
|
|
128
|
+
return ["cli_state_call", null, stateCommand, stateCliArtifacts(command, stateCommand)];
|
|
129
|
+
}
|
|
130
|
+
return ["implementation_boundary", null, null, new Set()];
|
|
131
|
+
}
|
|
132
|
+
const argsText = argumentsText(record).replace(/\\/g, "/");
|
|
133
|
+
if (["read", "grep", "glob"].includes(tool) &&
|
|
134
|
+
(argsText.includes("skills/agentera/capabilities/") ||
|
|
135
|
+
argsText.includes("skills/agentera/SKILL.md") ||
|
|
136
|
+
argsText.includes("skills/agentera/protocol.yaml"))) {
|
|
137
|
+
return ["capability_prose_read", argsText.includes("SKILL.md") ? "SKILL.md" : null, null, new Set()];
|
|
138
|
+
}
|
|
139
|
+
const artifactLabel = ["read", "grep", "glob"].includes(tool) ? canonicalArtifactLabel(argsText) : null;
|
|
140
|
+
if (artifactLabel) {
|
|
141
|
+
return ["raw_artifact_access", artifactLabel, null, new Set()];
|
|
142
|
+
}
|
|
143
|
+
if (["apply_patch", "edit", "write"].includes(tool)) {
|
|
144
|
+
return ["implementation_boundary", null, null, new Set()];
|
|
145
|
+
}
|
|
146
|
+
return ["non_state_context", null, null, new Set()];
|
|
147
|
+
}
|
|
148
|
+
function eventWarningKeys(event) {
|
|
149
|
+
const keys = [];
|
|
150
|
+
for (const warning of event.warnings ?? []) {
|
|
151
|
+
if (!warning || typeof warning !== "object")
|
|
152
|
+
continue;
|
|
153
|
+
const family = warning.family;
|
|
154
|
+
const category = warning.category;
|
|
155
|
+
if (typeof family === "string" && typeof category === "string")
|
|
156
|
+
keys.push(`${family}.${category}`);
|
|
157
|
+
}
|
|
158
|
+
return keys;
|
|
159
|
+
}
|
|
160
|
+
function eventClassification(event, coverageCaveated) {
|
|
161
|
+
const status = event.detail_loss_status;
|
|
162
|
+
if (status === "possible_useful_detail_removed")
|
|
163
|
+
return "likely_false_positive";
|
|
164
|
+
if (status === "retained_artifact_false_positive_signal")
|
|
165
|
+
return "likely_false_positive";
|
|
166
|
+
if (status === "possible_compression_without_anchor_loss" || status === "not_detected")
|
|
167
|
+
return "legitimate_pressure";
|
|
168
|
+
if (coverageCaveated)
|
|
169
|
+
return "unsupported_by_available_coverage";
|
|
170
|
+
return "inconclusive";
|
|
171
|
+
}
|
|
172
|
+
function categoryClassification(counts) {
|
|
173
|
+
if (counts.likely_false_positive)
|
|
174
|
+
return "likely_false_positive";
|
|
175
|
+
if (counts.unsupported_by_available_coverage)
|
|
176
|
+
return "unsupported_by_available_coverage";
|
|
177
|
+
if (counts.inconclusive)
|
|
178
|
+
return "inconclusive";
|
|
179
|
+
return "legitimate_pressure";
|
|
180
|
+
}
|
|
181
|
+
function nowIsoSeconds() {
|
|
182
|
+
return new Date().toISOString().replace(/\.\d{3}Z$/, "+00:00");
|
|
183
|
+
}
|
|
184
|
+
export function scanThresholdEvidence(corpus, opts) {
|
|
185
|
+
const salt = opts.salt;
|
|
186
|
+
const loaded = opts.contract ?? loadContract();
|
|
187
|
+
let records = corpus && typeof corpus === "object" && !Array.isArray(corpus) ? (corpus.records ?? []) : [];
|
|
188
|
+
if (!Array.isArray(records))
|
|
189
|
+
records = [];
|
|
190
|
+
let metadata = corpus && typeof corpus === "object" && !Array.isArray(corpus) ? (corpus.metadata ?? {}) : {};
|
|
191
|
+
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata))
|
|
192
|
+
metadata = {};
|
|
193
|
+
let runtimeStatuses = metadata.runtime_statuses;
|
|
194
|
+
if (!Array.isArray(runtimeStatuses))
|
|
195
|
+
runtimeStatuses = [];
|
|
196
|
+
const runtimeCoverage = runtimeStatuses
|
|
197
|
+
.filter((s) => s && typeof s === "object" && !Array.isArray(s))
|
|
198
|
+
.map((s) => boundedRuntimeStatus(s));
|
|
199
|
+
const coverageCaveats = [];
|
|
200
|
+
if (runtimeCoverage.length === 0) {
|
|
201
|
+
coverageCaveats.push("No runtime coverage metadata was available for threshold evidence scanning.");
|
|
202
|
+
}
|
|
203
|
+
if (runtimeCoverage.some((s) => ["missing", "sparse", "degraded", "skipped"].includes(s.status))) {
|
|
204
|
+
coverageCaveats.push("Runtime coverage is incomplete or degraded; absence of warning evidence is not proof of absence.");
|
|
205
|
+
}
|
|
206
|
+
const groups = new Map();
|
|
207
|
+
const degradations = [];
|
|
208
|
+
for (const record of records) {
|
|
209
|
+
if (!record || typeof record !== "object" || Array.isArray(record)) {
|
|
210
|
+
degradations.push({ reason: "malformed_record" });
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const key = startupConversationKey(record);
|
|
214
|
+
if (key === null) {
|
|
215
|
+
degradations.push({ record: recordLabel(record, salt), reason: "missing_conversation_key" });
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (!groups.has(key))
|
|
219
|
+
groups.set(key, []);
|
|
220
|
+
groups.get(key).push(record);
|
|
221
|
+
}
|
|
222
|
+
const warningCounts = {};
|
|
223
|
+
const artifactCounts = {};
|
|
224
|
+
const capabilityCounts = {};
|
|
225
|
+
const sourceCounts = {};
|
|
226
|
+
const detailStatusCounts = {};
|
|
227
|
+
const warningEvents = [];
|
|
228
|
+
for (const [conversationKey, items] of groups) {
|
|
229
|
+
items.sort((a, b) => {
|
|
230
|
+
const ta = String(a.timestamp ?? "");
|
|
231
|
+
const tb = String(b.timestamp ?? "");
|
|
232
|
+
return ta < tb ? -1 : ta > tb ? 1 : 0;
|
|
233
|
+
});
|
|
234
|
+
let capability = "unknown";
|
|
235
|
+
let pending = [];
|
|
236
|
+
for (const record of items) {
|
|
237
|
+
const text = recordThresholdText(record);
|
|
238
|
+
const data = record.data && typeof record.data === "object" && !Array.isArray(record.data) ? record.data : {};
|
|
239
|
+
const actor = data.actor;
|
|
240
|
+
if (actor === "user") {
|
|
241
|
+
capability = capabilityInvocation(text) || "unknown";
|
|
242
|
+
pending = [];
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (actor === "assistant") {
|
|
246
|
+
capability = introCapability(text) || capability;
|
|
247
|
+
}
|
|
248
|
+
const warnings = thresholdWarnings(text);
|
|
249
|
+
if (warnings.length > 0) {
|
|
250
|
+
const artifactLabel = canonicalArtifactLabel(text, loaded) || "unknown";
|
|
251
|
+
const beforeMetrics = detailMetrics(text);
|
|
252
|
+
const event = {
|
|
253
|
+
event_label: recordLabel(record, salt),
|
|
254
|
+
conversation: hashLabel("session", conversationKey, salt),
|
|
255
|
+
capability,
|
|
256
|
+
artifact_label: artifactLabel,
|
|
257
|
+
warnings,
|
|
258
|
+
detail_loss_status: "not_assessed",
|
|
259
|
+
rewrite_followup: null,
|
|
260
|
+
observed_counts: {
|
|
261
|
+
warning_word_count: beforeMetrics.word_count,
|
|
262
|
+
warning_anchor_count: beforeMetrics.anchor_count,
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
warningEvents.push(event);
|
|
266
|
+
pending.push({ event, metrics: beforeMetrics });
|
|
267
|
+
inc(artifactCounts, artifactLabel);
|
|
268
|
+
inc(capabilityCounts, capability);
|
|
269
|
+
for (const warning of warnings) {
|
|
270
|
+
inc(warningCounts, `${warning.family}.${warning.category}`);
|
|
271
|
+
inc(sourceCounts, warning.threshold_source);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (pending.length > 0 && record.source_kind === "tool_call") {
|
|
275
|
+
const [eventClass] = classifyStartupEvent(record);
|
|
276
|
+
if (eventClass === "implementation_boundary") {
|
|
277
|
+
const afterMetrics = detailMetrics(text);
|
|
278
|
+
for (const pendingItem of pending) {
|
|
279
|
+
const event = pendingItem.event;
|
|
280
|
+
if (event.rewrite_followup !== null)
|
|
281
|
+
continue;
|
|
282
|
+
const status = detailLossStatus(pendingItem.metrics, afterMetrics);
|
|
283
|
+
event.detail_loss_status = status;
|
|
284
|
+
event.rewrite_followup = {
|
|
285
|
+
event_label: recordLabel(record, salt),
|
|
286
|
+
event_class: eventClass,
|
|
287
|
+
word_count_delta: afterMetrics.word_count - pendingItem.metrics.word_count,
|
|
288
|
+
anchor_count_delta: afterMetrics.anchor_count - pendingItem.metrics.anchor_count,
|
|
289
|
+
};
|
|
290
|
+
inc(detailStatusCounts, status);
|
|
291
|
+
}
|
|
292
|
+
pending = [];
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
for (const pendingItem of pending) {
|
|
297
|
+
inc(detailStatusCounts, pendingItem.event.detail_loss_status);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (degradations.length > 0) {
|
|
301
|
+
coverageCaveats.push("One or more records were skipped because they were malformed or lacked conversation identity.");
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
output_envelope: THRESHOLD_EVIDENCE_ENVELOPE,
|
|
305
|
+
contract_version: loaded.version,
|
|
306
|
+
generated_at: nowIsoSeconds(),
|
|
307
|
+
total_records: records.length,
|
|
308
|
+
runtime_coverage: runtimeCoverage,
|
|
309
|
+
coverage_caveats: [...new Set(coverageCaveats)],
|
|
310
|
+
counts: {
|
|
311
|
+
warning_events: warningEvents.length,
|
|
312
|
+
by_warning: counterDict(warningCounts),
|
|
313
|
+
by_artifact: counterDict(artifactCounts),
|
|
314
|
+
by_capability: counterDict(capabilityCounts),
|
|
315
|
+
by_threshold_source: counterDict(sourceCounts),
|
|
316
|
+
by_detail_loss_status: counterDict(detailStatusCounts),
|
|
317
|
+
},
|
|
318
|
+
warning_events: warningEvents,
|
|
319
|
+
degradations,
|
|
320
|
+
privacy_redaction_summary: {
|
|
321
|
+
raw_transcript_text: "not_emitted",
|
|
322
|
+
raw_tool_arguments: "not_emitted",
|
|
323
|
+
full_local_paths: "not_emitted",
|
|
324
|
+
raw_store_paths: "not_emitted",
|
|
325
|
+
session_ids: "salted_or_not_emitted",
|
|
326
|
+
artifact_labels: "canonical_only",
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
export function scanRetainedThresholdEvidence(artifacts, opts) {
|
|
331
|
+
const salt = opts.salt;
|
|
332
|
+
const loaded = opts.contract ?? loadContract();
|
|
333
|
+
const warningCounts = {};
|
|
334
|
+
const artifactCounts = {};
|
|
335
|
+
const sourceCounts = {};
|
|
336
|
+
const detailStatusCounts = {};
|
|
337
|
+
const warningEvents = [];
|
|
338
|
+
for (const sourceLabel of Object.keys(artifacts).sort()) {
|
|
339
|
+
const text = artifacts[sourceLabel];
|
|
340
|
+
if (typeof sourceLabel !== "string" || typeof text !== "string")
|
|
341
|
+
continue;
|
|
342
|
+
const artifactLabel = canonicalArtifactLabel(sourceLabel, loaded) || canonicalArtifactLabel(text, loaded) || "unknown";
|
|
343
|
+
const warnings = thresholdWarnings(text);
|
|
344
|
+
if (warnings.length === 0)
|
|
345
|
+
continue;
|
|
346
|
+
const postAuditMarkers = countMatches(POST_AUDIT_FLAG_RE, text);
|
|
347
|
+
const budgetMentions = countMatches(BUDGET_PRESSURE_RE, text);
|
|
348
|
+
const fullPlanBudgetPressure = artifactLabel === "plan" && budgetMentions > 0 && FULL_PLAN_BUDGET_RE.test(text);
|
|
349
|
+
const detailStatus = postAuditMarkers && fullPlanBudgetPressure ? "retained_artifact_false_positive_signal" : "not_assessed";
|
|
350
|
+
const event = {
|
|
351
|
+
event_label: hashLabel("record", sourceLabel, salt),
|
|
352
|
+
conversation: "retained_artifacts",
|
|
353
|
+
capability: "agentera",
|
|
354
|
+
artifact_label: artifactLabel,
|
|
355
|
+
evidence_source: "retained_artifact",
|
|
356
|
+
warnings,
|
|
357
|
+
detail_loss_status: detailStatus,
|
|
358
|
+
rewrite_followup: null,
|
|
359
|
+
observed_counts: {
|
|
360
|
+
post_audit_flag_markers: postAuditMarkers,
|
|
361
|
+
budget_pressure_mentions: budgetMentions,
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
warningEvents.push(event);
|
|
365
|
+
inc(artifactCounts, artifactLabel);
|
|
366
|
+
inc(detailStatusCounts, detailStatus);
|
|
367
|
+
for (const warning of warnings) {
|
|
368
|
+
inc(warningCounts, `${warning.family}.${warning.category}`);
|
|
369
|
+
inc(sourceCounts, warning.threshold_source);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
output_envelope: THRESHOLD_EVIDENCE_ENVELOPE,
|
|
374
|
+
contract_version: loaded.version,
|
|
375
|
+
generated_at: nowIsoSeconds(),
|
|
376
|
+
total_records: Object.keys(artifacts).length,
|
|
377
|
+
runtime_coverage: [],
|
|
378
|
+
coverage_caveats: [],
|
|
379
|
+
counts: {
|
|
380
|
+
warning_events: warningEvents.length,
|
|
381
|
+
by_warning: counterDict(warningCounts),
|
|
382
|
+
by_artifact: counterDict(artifactCounts),
|
|
383
|
+
by_capability: warningEvents.length > 0 ? { agentera: warningEvents.length } : {},
|
|
384
|
+
by_threshold_source: counterDict(sourceCounts),
|
|
385
|
+
by_detail_loss_status: counterDict(detailStatusCounts),
|
|
386
|
+
},
|
|
387
|
+
warning_events: warningEvents,
|
|
388
|
+
degradations: [],
|
|
389
|
+
privacy_redaction_summary: {
|
|
390
|
+
raw_artifact_text: "not_emitted",
|
|
391
|
+
raw_transcript_text: "not_emitted",
|
|
392
|
+
raw_tool_arguments: "not_emitted",
|
|
393
|
+
full_local_paths: "not_emitted",
|
|
394
|
+
artifact_labels: "canonical_only",
|
|
395
|
+
},
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
export function classifyThresholdEvidence(scan) {
|
|
399
|
+
let events = scan.warning_events;
|
|
400
|
+
if (!Array.isArray(events))
|
|
401
|
+
events = [];
|
|
402
|
+
let coverageCaveats = scan.coverage_caveats;
|
|
403
|
+
if (!Array.isArray(coverageCaveats))
|
|
404
|
+
coverageCaveats = [];
|
|
405
|
+
const byCategory = new Map();
|
|
406
|
+
const coverageCaveated = coverageCaveats.length > 0;
|
|
407
|
+
const unsupported = coverageCaveats.length > 0 && events.length === 0;
|
|
408
|
+
for (const event of events) {
|
|
409
|
+
if (!event || typeof event !== "object" || Array.isArray(event))
|
|
410
|
+
continue;
|
|
411
|
+
const classification = eventClassification(event, coverageCaveated);
|
|
412
|
+
const artifact = typeof event.artifact_label === "string" ? event.artifact_label : "unknown";
|
|
413
|
+
const capability = typeof event.capability === "string" ? event.capability : "unknown";
|
|
414
|
+
const detailStatus = typeof event.detail_loss_status === "string" ? event.detail_loss_status : "not_assessed";
|
|
415
|
+
for (const key of eventWarningKeys(event)) {
|
|
416
|
+
let entry = byCategory.get(key);
|
|
417
|
+
if (!entry) {
|
|
418
|
+
entry = {
|
|
419
|
+
warning: key,
|
|
420
|
+
event_count: 0,
|
|
421
|
+
artifacts: new Set(),
|
|
422
|
+
capabilities: new Set(),
|
|
423
|
+
classification_counts: {},
|
|
424
|
+
detail_loss_status_counts: {},
|
|
425
|
+
event_labels: [],
|
|
426
|
+
};
|
|
427
|
+
byCategory.set(key, entry);
|
|
428
|
+
}
|
|
429
|
+
entry.event_count += 1;
|
|
430
|
+
entry.artifacts.add(artifact);
|
|
431
|
+
entry.capabilities.add(capability);
|
|
432
|
+
inc(entry.classification_counts, classification);
|
|
433
|
+
inc(entry.detail_loss_status_counts, detailStatus);
|
|
434
|
+
if (typeof event.event_label === "string")
|
|
435
|
+
entry.event_labels.push(event.event_label);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const categories = [];
|
|
439
|
+
let repeatedFalsePositive = false;
|
|
440
|
+
const classificationCounts = {};
|
|
441
|
+
for (const key of [...byCategory.keys()].sort()) {
|
|
442
|
+
const entry = byCategory.get(key);
|
|
443
|
+
const classification = categoryClassification(entry.classification_counts);
|
|
444
|
+
inc(classificationCounts, classification);
|
|
445
|
+
if (classification === "likely_false_positive" && entry.event_count >= 2)
|
|
446
|
+
repeatedFalsePositive = true;
|
|
447
|
+
categories.push({
|
|
448
|
+
warning: key,
|
|
449
|
+
classification,
|
|
450
|
+
event_count: entry.event_count,
|
|
451
|
+
artifacts: [...entry.artifacts].sort(),
|
|
452
|
+
capabilities: [...entry.capabilities].sort(),
|
|
453
|
+
event_classification_counts: counterDict(entry.classification_counts),
|
|
454
|
+
detail_loss_status_counts: counterDict(entry.detail_loss_status_counts),
|
|
455
|
+
event_labels: entry.event_labels,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
if (unsupported)
|
|
459
|
+
inc(classificationCounts, "unsupported_by_available_coverage");
|
|
460
|
+
let recommendation;
|
|
461
|
+
if (repeatedFalsePositive) {
|
|
462
|
+
recommendation = {
|
|
463
|
+
action: "consider_minimal_threshold_or_diagnostic_change",
|
|
464
|
+
reason: "At least one warning category has repeated redacted evidence of possible useful detail removal.",
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
else if (unsupported) {
|
|
468
|
+
recommendation = {
|
|
469
|
+
action: "defer_without_threshold_change",
|
|
470
|
+
reason: "Available runtime coverage cannot support a false-positive conclusion.",
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
recommendation = {
|
|
475
|
+
action: "no_threshold_change_yet",
|
|
476
|
+
reason: "False-positive evidence is absent, single-instance, legitimate pressure, or inconclusive.",
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
output_envelope: THRESHOLD_CLASSIFICATION_ENVELOPE,
|
|
481
|
+
input_envelope: scan.output_envelope,
|
|
482
|
+
generated_at: nowIsoSeconds(),
|
|
483
|
+
categories,
|
|
484
|
+
counts: {
|
|
485
|
+
by_classification: counterDict(classificationCounts),
|
|
486
|
+
category_count: categories.length,
|
|
487
|
+
repeated_false_positive_categories: categories.filter((c) => c.classification === "likely_false_positive" && c.event_count >= 2).length,
|
|
488
|
+
},
|
|
489
|
+
recommendation,
|
|
490
|
+
coverage_caveats: coverageCaveats.map((c) => String(c)),
|
|
491
|
+
privacy_redaction_summary: scan.privacy_redaction_summary || {
|
|
492
|
+
raw_transcript_text: "not_emitted",
|
|
493
|
+
raw_tool_arguments: "not_emitted",
|
|
494
|
+
},
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
// ===========================================================================
|
|
498
|
+
// Slice 3: startup record classification into state-gathering sequences
|
|
499
|
+
// ===========================================================================
|
|
500
|
+
//# sourceMappingURL=threshold.js.map
|