akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.4
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 +731 -0
- package/dist/akm +94 -196
- package/dist/cli/shared.js +6 -2
- package/dist/cli.js +22 -9
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +2 -2
- package/dist/commands/health/checks.js +30 -75
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +0 -38
- package/dist/commands/health/improve-metrics.js +123 -562
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +11 -106
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -73
- package/dist/commands/health.js +122 -143
- package/dist/commands/improve/consolidate/chunking.js +25 -100
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +538 -1075
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1075
- package/dist/commands/improve/eligibility.js +126 -400
- package/dist/commands/improve/execution.js +3 -5
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +29 -166
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +12 -7
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +443 -1063
- package/dist/commands/improve/ledger.js +114 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +459 -1172
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +14 -118
- package/dist/commands/improve/memory/memory-improve.js +4 -3
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -10
- package/dist/commands/improve/preparation.js +851 -2339
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +621 -1367
- package/dist/commands/improve/salience.js +46 -232
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +323 -0
- package/dist/commands/proposal/drain.js +251 -644
- package/dist/commands/proposal/proposal-cli.js +3 -18
- package/dist/commands/proposal/proposal-types.js +20 -41
- package/dist/commands/proposal/proposal.js +1 -2
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +502 -1487
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +13 -89
- package/dist/commands/read/curate.js +63 -413
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +2 -13
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +7 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +2 -11
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/stash-cli.js +1 -1
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +9 -8
- package/dist/commands/tasks/tasks.js +326 -930
- package/dist/commands/tasks/validate.js +42 -21
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +0 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +11 -12
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +291 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +1 -33
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +163 -68
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +21 -95
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-lock.js +76 -173
- package/dist/core/logs-db.js +2 -2
- package/dist/core/paths.js +0 -27
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +108 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +293 -1012
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/graph-db.js +106 -46
- package/dist/indexer/ensure-index.js +44 -85
- package/dist/indexer/graph/graph-extraction.js +340 -562
- package/dist/indexer/graph/graph-related.js +130 -0
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +139 -151
- package/dist/indexer/indexer.js +524 -846
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +81 -90
- package/dist/indexer/passes/metadata.js +132 -200
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +1 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +181 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +2 -7
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +10 -15
- package/dist/llm/graph-extract.js +3 -12
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/metadata-enhance.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +2 -34
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +60 -23
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +1 -2
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +43937 -93313
- package/dist/scripts/akm-migrate.js +43697 -93071
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +0 -17
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +168 -0
- package/dist/storage/repositories/index-connection.js +34 -70
- package/dist/storage/repositories/index-entries-repository.js +69 -111
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +83 -269
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +192 -220
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +35 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +34 -27
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +129 -277
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +125 -745
- package/dist/tasks/backends/schtasks.js +101 -620
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/scheduler-binding.js +18 -238
- package/dist/tasks/scheduler-invocation.js +52 -52
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +361 -751
- package/dist/tasks/source/parse-task-source.js +160 -10
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +2 -2
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +41 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
- package/docs/reference/cli.md +182 -125
- package/docs/reference/configuration.md +49 -56
- package/docs/reference/data-and-telemetry.md +19 -20
- package/docs/reference/tasks.md +86 -38
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +87 -406
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -146
- package/dist/commands/improve/distill/promote-memory.js +0 -329
- package/dist/commands/improve/distill/quality-gate.js +0 -500
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -21
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/config/retired-experimental-keys-shim.js +0 -62
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -441
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -78
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -25,7 +25,6 @@ import { resolveImproveExecution } from "../improve/execution.js";
|
|
|
25
25
|
import { extractCommand } from "../improve/extract-cli.js";
|
|
26
26
|
import { resolveImproveStrategy } from "../improve/improve-strategies.js";
|
|
27
27
|
import { drainProposals } from "./drain.js";
|
|
28
|
-
import { resolveDrainPolicy } from "./drain-policies.js";
|
|
29
28
|
import { akmProposalAccept, akmProposalDiff, akmProposalList, akmProposalReject, akmProposalRevert, akmProposalShow, bulkAdjudicateProposals, } from "./proposal.js";
|
|
30
29
|
import { proposeCommand } from "./propose-cli.js";
|
|
31
30
|
export function mergeProposalDrainNotices(resolutionNotices, dispatchNotices) {
|
|
@@ -323,13 +322,9 @@ const proposalShowCommand = defineJsonCommand({
|
|
|
323
322
|
const proposalDrainCommand = defineJsonCommand({
|
|
324
323
|
meta: {
|
|
325
324
|
name: "drain",
|
|
326
|
-
description: "Drain the
|
|
325
|
+
description: "Drain the pending proposal backlog: accept what a quality judge passed, reject empty diffs, leave the rest for judgment or review",
|
|
327
326
|
},
|
|
328
327
|
args: {
|
|
329
|
-
policy: {
|
|
330
|
-
type: "string",
|
|
331
|
-
description: "Built-in preset (personal-stash|conservative|manual) or path to a policy file",
|
|
332
|
-
},
|
|
333
328
|
"dry-run": {
|
|
334
329
|
type: "boolean",
|
|
335
330
|
description: "List what would be accepted/rejected/deferred without writing.",
|
|
@@ -345,10 +340,6 @@ const proposalDrainCommand = defineJsonCommand({
|
|
|
345
340
|
type: "string",
|
|
346
341
|
description: "Hard per-run accept ceiling. Accepts beyond this are reported as skippedByCap.",
|
|
347
342
|
},
|
|
348
|
-
"max-diff-lines": {
|
|
349
|
-
type: "string",
|
|
350
|
-
description: "Defer (never promote) accepts whose proposed content exceeds this many lines.",
|
|
351
|
-
},
|
|
352
343
|
"older-than": {
|
|
353
344
|
type: "string",
|
|
354
345
|
description: "Only consider proposals created more than this many days ago.",
|
|
@@ -365,7 +356,7 @@ const proposalDrainCommand = defineJsonCommand({
|
|
|
365
356
|
},
|
|
366
357
|
strategy: {
|
|
367
358
|
type: "string",
|
|
368
|
-
description: "Read the triage block (
|
|
359
|
+
description: "Read the triage block (applyMode, ceilings, judgment) from this improve strategy.",
|
|
369
360
|
},
|
|
370
361
|
},
|
|
371
362
|
async run({ args, rawArgs }) {
|
|
@@ -378,20 +369,17 @@ const proposalDrainCommand = defineJsonCommand({
|
|
|
378
369
|
// always override config; config supplies defaults for any flag omitted.
|
|
379
370
|
const selectedStrategy = resolveImproveStrategy(args.strategy, cfg);
|
|
380
371
|
const triageConfig = selectedStrategy.config.processes?.triage;
|
|
381
|
-
const policy = resolveDrainPolicy(args.policy ?? triageConfig?.policy);
|
|
382
372
|
const dryRun = args["dry-run"] === true;
|
|
383
373
|
const applyMode = args.promote === true ? "promote" : (triageConfig?.applyMode ?? "queue");
|
|
384
374
|
const maxAccepts = parsePositiveIntFlag(args["max-accepts"], "--max-accepts") ??
|
|
385
375
|
triageConfig?.maxAcceptsPerRun ??
|
|
386
376
|
25;
|
|
387
|
-
const maxDiffLines = parsePositiveIntFlag(args["max-diff-lines"], "--max-diff-lines") ??
|
|
388
|
-
triageConfig?.maxDiffLines;
|
|
389
377
|
const rawOlderThan = parsePositiveIntFlag(args["older-than"], "--older-than");
|
|
390
378
|
const olderThanMs = rawOlderThan !== undefined ? rawOlderThan * 86_400_000 : undefined;
|
|
391
379
|
// Promotion in promote mode is destructive (commits to git, no batch revert).
|
|
392
380
|
if (applyMode === "promote" && !dryRun) {
|
|
393
381
|
const { confirmDestructive } = await import("../../cli/confirm.js");
|
|
394
|
-
const confirmed = await confirmDestructive(
|
|
382
|
+
const confirmed = await confirmDestructive("Drain and promote judge-passed pending proposals? Promotions commit to git and cannot be batch-reverted.", { yes: args.yes === true });
|
|
395
383
|
if (!confirmed) {
|
|
396
384
|
process.stderr.write("Aborted.\n");
|
|
397
385
|
return;
|
|
@@ -444,11 +432,9 @@ const proposalDrainCommand = defineJsonCommand({
|
|
|
444
432
|
result = await withLlmStage("drain", () => drainProposals({
|
|
445
433
|
stashDir,
|
|
446
434
|
config: cfg,
|
|
447
|
-
policy,
|
|
448
435
|
applyMode,
|
|
449
436
|
maxAccepts,
|
|
450
437
|
dryRun,
|
|
451
|
-
...(maxDiffLines !== undefined ? { maxDiffLines } : {}),
|
|
452
438
|
...(excludeIds ? { excludeIds } : {}),
|
|
453
439
|
judgment,
|
|
454
440
|
}));
|
|
@@ -461,7 +447,6 @@ const proposalDrainCommand = defineJsonCommand({
|
|
|
461
447
|
output("proposal-drain", {
|
|
462
448
|
schemaVersion: 1,
|
|
463
449
|
ok: true,
|
|
464
|
-
policy: policy.name,
|
|
465
450
|
applyMode,
|
|
466
451
|
dryRun,
|
|
467
452
|
strategy: selectedStrategy.name,
|
|
@@ -1,37 +1,24 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
// ── Source allow-list (F-4 / #385) ──────────────────────────────────────────
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Rationale (W3C PROV-DM 2013): Provenance records require typed, validated
|
|
9
|
-
* sources for meaningful aggregation. Accept-rate-per-source is the core
|
|
10
|
-
* self-measurement metric for recursive self-improvement: if reflect proposals
|
|
11
|
-
* are accepted at 20% and distill proposals at 60%, that guides resource
|
|
12
|
-
* allocation. Free-text typos (`"reflct"`) produce unaggregatable events.
|
|
13
|
-
*
|
|
14
|
-
* Automated sources (those in {@link AUTOMATED_PROPOSAL_SOURCES}) require a
|
|
15
|
-
* `sourceRun` field for full PROV-DM traceability.
|
|
5
|
+
* Valid proposal `source` values (#385): typed sources keep accept-rate per
|
|
6
|
+
* source aggregatable (PROV-DM). An unknown value is accepted with a warning.
|
|
16
7
|
*/
|
|
17
8
|
export const PROPOSAL_SOURCES = [
|
|
18
|
-
// Automated sources — require sourceRun for traceability.
|
|
19
9
|
"reflect",
|
|
20
10
|
"distill",
|
|
21
11
|
"consolidate",
|
|
22
12
|
"extract",
|
|
23
13
|
"improve",
|
|
24
|
-
// Semi-automated / tool-driven.
|
|
25
14
|
"feedback",
|
|
26
|
-
// Human-initiated / CLI-driven.
|
|
27
15
|
"propose",
|
|
28
16
|
"remember",
|
|
29
17
|
"import",
|
|
30
|
-
// Internal / system.
|
|
31
18
|
"distill_quality_rejected",
|
|
32
19
|
"schema-repair",
|
|
33
20
|
];
|
|
34
|
-
/** Automated sources
|
|
21
|
+
/** Automated sources, which should carry a `sourceRun`. */
|
|
35
22
|
export const AUTOMATED_PROPOSAL_SOURCES = [
|
|
36
23
|
"reflect",
|
|
37
24
|
"distill",
|
|
@@ -40,38 +27,30 @@ export const AUTOMATED_PROPOSAL_SOURCES = [
|
|
|
40
27
|
"improve",
|
|
41
28
|
"schema-repair",
|
|
42
29
|
];
|
|
43
|
-
/**
|
|
44
|
-
* Check whether a string is a valid {@link ProposalSource}.
|
|
45
|
-
* Unknown source values are accepted with a runtime warning rather than a hard
|
|
46
|
-
* error, to allow extensions without breaking existing callers.
|
|
47
|
-
*/
|
|
48
30
|
export function isValidProposalSource(source) {
|
|
49
31
|
return PROPOSAL_SOURCES.includes(source);
|
|
50
32
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Check whether a source value is an automated source requiring `sourceRun`.
|
|
53
|
-
*/
|
|
54
33
|
export function isAutomatedProposalSource(source) {
|
|
55
34
|
return AUTOMATED_PROPOSAL_SOURCES.includes(source);
|
|
56
35
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Gate-decision reason token for a promote refusal caused by the TARGET
|
|
59
|
-
* changing after mint — often akm's own bookkeeping, not a merit judgement on
|
|
60
|
-
* the proposed content (STALE, R20). The drain stamps this on the auto-reject
|
|
61
|
-
* it issues instead of retrying a promote that will fail identically forever;
|
|
62
|
-
* {@link isStaleTargetRejection} and the rejection-backoff guard
|
|
63
|
-
* (`repository.ts`'s `checkFingerprintAndBackoff`) both key off the exact
|
|
64
|
-
* string so they can't drift apart.
|
|
65
|
-
*/
|
|
36
|
+
/** A promote refused because the target changed after mint (STALE, R20) — not a merit judgement. */
|
|
66
37
|
export const STALE_TARGET_GATE_REASON = "stale-target";
|
|
38
|
+
export const EXPIRED_GATE_REASON = "expired";
|
|
39
|
+
export const ASSET_MISSING_GATE_REASON = "asset-missing";
|
|
40
|
+
const PROCEDURAL_GATE_REASONS = new Set([
|
|
41
|
+
STALE_TARGET_GATE_REASON,
|
|
42
|
+
EXPIRED_GATE_REASON,
|
|
43
|
+
ASSET_MISSING_GATE_REASON,
|
|
44
|
+
]);
|
|
67
45
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* and the accept-rate health metric (`health/accept-rate.ts`) — exclude these
|
|
73
|
-
* rows so a procedural refusal doesn't misrepresent content quality.
|
|
46
|
+
* A rejection nobody judged on its content (stale target, expiry, orphan
|
|
47
|
+
* purge). The "previously rejected" prompt context and the accept-rate metric
|
|
48
|
+
* leave these out. Expiries archived before the gate reason existed are known
|
|
49
|
+
* by their review reason.
|
|
74
50
|
*/
|
|
75
|
-
export function
|
|
76
|
-
|
|
51
|
+
export function isProceduralRejection(proposal) {
|
|
52
|
+
if (proposal.gateDecision?.outcome === "auto-rejected" && PROCEDURAL_GATE_REASONS.has(proposal.gateDecision.reason)) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return proposal.review?.reason?.startsWith("expired:") === true;
|
|
77
56
|
}
|
|
@@ -15,7 +15,7 @@ import { resolveStashDir } from "../../core/common.js";
|
|
|
15
15
|
import { loadConfig } from "../../core/config/config.js";
|
|
16
16
|
import { resolveWriteTarget } from "../../core/write-source.js";
|
|
17
17
|
import { withAssetMutationLease } from "../../indexer/index-writer-lock.js";
|
|
18
|
-
import { diffProposal, listProposals, preflightProposalPromotion, promoteProposal, proposalContent,
|
|
18
|
+
import { diffProposal, listProposals, preflightProposalPromotion, promoteProposal, proposalContent, rejectProposalDurably, resolveProposalId, revertProposal, } from "./repository.js";
|
|
19
19
|
import { validateProposal } from "./validators/proposals.js";
|
|
20
20
|
// ── Shared helpers ──────────────────────────────────────────────────────────
|
|
21
21
|
function resolveStash(stashDir) {
|
|
@@ -104,7 +104,6 @@ export async function akmProposalReject(options) {
|
|
|
104
104
|
const config = options.config ?? loadConfig();
|
|
105
105
|
const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, config);
|
|
106
106
|
const proposalId = resolveProposalId(stash, options.id, options.ctx).id;
|
|
107
|
-
await recoverProposalTransactionsForStash(stash, config, options.ctx, proposalId);
|
|
108
107
|
const updated = rejectProposalDurably(stash, proposalId, options.reason, options.ctx, options.gateDecision);
|
|
109
108
|
return {
|
|
110
109
|
schemaVersion: 1,
|
|
@@ -19,15 +19,16 @@ import { resolveStashDir } from "../../core/common.js";
|
|
|
19
19
|
import { generatedContentRejection } from "../../core/content-safety.js";
|
|
20
20
|
import { UsageError } from "../../core/errors.js";
|
|
21
21
|
import { appendEvent } from "../../core/events.js";
|
|
22
|
+
import { redactSensitiveText } from "../../core/redaction.js";
|
|
22
23
|
import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
|
|
23
24
|
import { warn } from "../../core/warn.js";
|
|
24
25
|
import { deriveEntryProvenance } from "../../indexer/installations.js";
|
|
25
26
|
import { fallbackAnnouncement } from "../../integrations/agent/engine-fallback.js";
|
|
26
|
-
import {
|
|
27
|
-
import { prepareInlineExecution } from "../../integrations/agent/inline-execution.js";
|
|
27
|
+
import { buildExecution, resolveExecution } from "../../integrations/agent/execution.js";
|
|
28
28
|
import { buildProposePrompt, parseAgentProposalPayload } from "../../integrations/agent/prompts.js";
|
|
29
|
+
import { assertRunnerCredentials, collectDispatchSensitiveValues, runExecution, } from "../../integrations/agent/runner-dispatch.js";
|
|
29
30
|
import { baseFailureFields, enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
|
|
30
|
-
import { createProposal,
|
|
31
|
+
import { createProposal, resolveProposalQueueTarget, } from "./repository.js";
|
|
31
32
|
function failureEnvelope(result, type, name, engine, notices, fallbackReason = "non_zero_exit") {
|
|
32
33
|
return {
|
|
33
34
|
...baseFailureFields(result, fallbackReason),
|
|
@@ -41,56 +42,43 @@ function failureEnvelope(result, type, name, engine, notices, fallbackReason = "
|
|
|
41
42
|
function noticeFields(notices) {
|
|
42
43
|
return notices.length > 0 ? { notices } : {};
|
|
43
44
|
}
|
|
44
|
-
/** Materialize required credentials through the real runner boundary, without provider I/O. */
|
|
45
|
-
async function preflightProposalDispatch(lowered, runOptions) {
|
|
46
|
-
return acquireLoweredExecutionDispatchLease(lowered, {
|
|
47
|
-
...(runOptions.envSource ? { envSource: runOptions.envSource } : {}),
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
45
|
/** Resolve, lower, and dispatch the already-rendered proposal prompt. */
|
|
51
46
|
async function dispatchProposalPrompt(prompt, config, options, onDispatchReady) {
|
|
52
47
|
const current = {
|
|
53
48
|
...(options.engine !== undefined ? { engine: options.engine } : {}),
|
|
54
49
|
...(options.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
|
|
55
50
|
};
|
|
56
|
-
const prepared =
|
|
51
|
+
const prepared = resolveExecution({
|
|
57
52
|
content: prompt,
|
|
58
53
|
config,
|
|
59
|
-
invocationKind: "direct",
|
|
60
54
|
...(Object.keys(current).length > 0 ? { current } : {}),
|
|
61
55
|
});
|
|
62
56
|
const engineName = prepared.request.engine.name;
|
|
63
57
|
const announcement = fallbackAnnouncement(prepared.fallbackEngineName, engineName);
|
|
64
58
|
if (announcement)
|
|
65
59
|
warn(announcement);
|
|
66
|
-
const lowered =
|
|
60
|
+
const lowered = buildExecution(prepared.request, prepared.runner);
|
|
67
61
|
const interactive = !options.runAgentOptions?.spawn;
|
|
68
62
|
const runOptions = {
|
|
69
63
|
stdio: interactive ? "interactive" : "captured",
|
|
70
64
|
parseOutput: "text",
|
|
71
65
|
...(options.runAgentOptions ?? {}),
|
|
72
66
|
};
|
|
73
|
-
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
disposeLoweredExecutionDispatchLease(lease);
|
|
92
|
-
throw error;
|
|
93
|
-
}
|
|
67
|
+
// Validate every required symbolic credential before the entry event opens
|
|
68
|
+
// durable state. Provider/runtime failures still occur after the event,
|
|
69
|
+
// preserving the command-attempt observability contract.
|
|
70
|
+
assertRunnerCredentials(lowered.runner, runOptions.envSource);
|
|
71
|
+
onDispatchReady();
|
|
72
|
+
options.onDispatchReady?.();
|
|
73
|
+
const result = await runExecution(lowered, { runOptions });
|
|
74
|
+
return {
|
|
75
|
+
result,
|
|
76
|
+
engineName,
|
|
77
|
+
...(lowered.runner.kind === "llm" ? {} : { engineBin: lowered.runner.profile.bin }),
|
|
78
|
+
notices: lowered.notices,
|
|
79
|
+
sensitiveValues: collectDispatchSensitiveValues(lowered.runner, {}, runOptions.envSource),
|
|
80
|
+
interactive,
|
|
81
|
+
};
|
|
94
82
|
}
|
|
95
83
|
/**
|
|
96
84
|
* WI-8.5a — the fully-qualified `bundle//conceptId` item_ref for a proposal
|
|
@@ -158,153 +146,139 @@ export async function akmPropose(options) {
|
|
|
158
146
|
// no synthetic persona, conversation turn, schema, or tool selection is
|
|
159
147
|
// introduced while it crosses the shared resolved/lowered boundary.
|
|
160
148
|
const dispatch = await dispatchProposalPrompt(prompt, config, options, () => emitProposeInvoked(target.source, options));
|
|
161
|
-
const { result, engineName, notices,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
error: enoentHintMessage(dispatch.engineBin ?? engineName),
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
return failureEnvelope(result, options.type, options.name, engineName, notices);
|
|
172
|
-
}
|
|
173
|
-
// 5. Resolve the proposal content.
|
|
174
|
-
// Path A: opencode wrote the draft file — read it directly (no stdout parse).
|
|
175
|
-
// Path B: fallback to stdout JSON parse for non-file-writing agents.
|
|
176
|
-
let payload;
|
|
177
|
-
if (fs.existsSync(resolvedDraftPath)) {
|
|
178
|
-
const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
|
|
179
|
-
fs.unlinkSync(resolvedDraftPath);
|
|
180
|
-
payload = {
|
|
181
|
-
ref: proposeItemRef(target.source, options.type, options.name),
|
|
182
|
-
content: draftContent,
|
|
149
|
+
const { result, engineName, notices, sensitiveValues } = dispatch;
|
|
150
|
+
if (!result.ok) {
|
|
151
|
+
// B3: ENOENT / not-found gives an actionable hint.
|
|
152
|
+
if (isEnoentFailure(result)) {
|
|
153
|
+
return {
|
|
154
|
+
...failureEnvelope(result, options.type, options.name, engineName, notices),
|
|
155
|
+
error: enoentHintMessage(dispatch.engineBin ?? engineName),
|
|
183
156
|
};
|
|
184
157
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
payload = parseAgentProposalPayload(result.stdout ?? "");
|
|
204
|
-
}
|
|
205
|
-
catch (err) {
|
|
206
|
-
return {
|
|
207
|
-
schemaVersion: 2,
|
|
208
|
-
ok: false,
|
|
209
|
-
reason: "parse_error",
|
|
210
|
-
error: err instanceof Error ? err.message : String(err),
|
|
211
|
-
type: options.type,
|
|
212
|
-
name: options.name,
|
|
213
|
-
engine: engineName,
|
|
214
|
-
exitCode: result.exitCode,
|
|
215
|
-
stdout: result.stdout,
|
|
216
|
-
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
217
|
-
...noticeFields(notices),
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
const unsafeContent = generatedContentRejection(payload.content, redactWithLoweredExecutionDispatchLease(lease, payload.content));
|
|
222
|
-
if (unsafeContent) {
|
|
158
|
+
return failureEnvelope(result, options.type, options.name, engineName, notices);
|
|
159
|
+
}
|
|
160
|
+
// 5. Resolve the proposal content.
|
|
161
|
+
// Path A: opencode wrote the draft file — read it directly (no stdout parse).
|
|
162
|
+
// Path B: fallback to stdout JSON parse for non-file-writing agents.
|
|
163
|
+
let payload;
|
|
164
|
+
if (fs.existsSync(resolvedDraftPath)) {
|
|
165
|
+
const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
|
|
166
|
+
fs.unlinkSync(resolvedDraftPath);
|
|
167
|
+
payload = {
|
|
168
|
+
ref: proposeItemRef(target.source, options.type, options.name),
|
|
169
|
+
content: draftContent,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// B1: When interactive mode was used and stdout is empty, the agent did not
|
|
174
|
+
// write the draft file and stdout was not captured — surface an actionable error.
|
|
175
|
+
if (dispatch.interactive && (result.stdout ?? "") === "") {
|
|
223
176
|
return {
|
|
224
177
|
schemaVersion: 2,
|
|
225
178
|
ok: false,
|
|
226
179
|
reason: "parse_error",
|
|
227
|
-
error:
|
|
180
|
+
error: "Agent did not write draft file and stdout was not captured (interactive mode). Check that the agent CLI understood the file-write instruction, or configure a headless profile with stdio: 'captured'.",
|
|
228
181
|
type: options.type,
|
|
229
182
|
name: options.name,
|
|
230
183
|
engine: engineName,
|
|
231
184
|
exitCode: result.exitCode,
|
|
185
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
232
186
|
...noticeFields(notices),
|
|
233
187
|
};
|
|
234
188
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
// well-formed and the type still matches the requested type.
|
|
238
|
-
const expectedRef = proposeItemRef(target.source, options.type, options.name);
|
|
239
|
-
let ref = expectedRef;
|
|
240
|
-
if (payload.ref) {
|
|
241
|
-
let parsedRef;
|
|
242
|
-
try {
|
|
243
|
-
parsedRef = parseRefInput(payload.ref);
|
|
244
|
-
}
|
|
245
|
-
catch (err) {
|
|
246
|
-
return {
|
|
247
|
-
schemaVersion: 2,
|
|
248
|
-
ok: false,
|
|
249
|
-
reason: "parse_error",
|
|
250
|
-
error: err instanceof Error ? err.message : String(err),
|
|
251
|
-
type: options.type,
|
|
252
|
-
name: options.name,
|
|
253
|
-
engine: engineName,
|
|
254
|
-
exitCode: result.exitCode,
|
|
255
|
-
stdout: result.stdout,
|
|
256
|
-
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
257
|
-
...noticeFields(notices),
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
if (parsedRef.type !== options.type) {
|
|
261
|
-
return {
|
|
262
|
-
schemaVersion: 2,
|
|
263
|
-
ok: false,
|
|
264
|
-
reason: "parse_error",
|
|
265
|
-
error: `Agent returned ref type ${parsedRef.type} but expected ${options.type}`,
|
|
266
|
-
type: options.type,
|
|
267
|
-
name: options.name,
|
|
268
|
-
engine: engineName,
|
|
269
|
-
exitCode: result.exitCode,
|
|
270
|
-
stdout: result.stdout,
|
|
271
|
-
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
272
|
-
...noticeFields(notices),
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
ref = proposeItemRef(target.source, parsedRef.type, parsedRef.name);
|
|
189
|
+
try {
|
|
190
|
+
payload = parseAgentProposalPayload(result.stdout ?? "");
|
|
276
191
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
// With force:true, the result is always a Proposal (never skipped).
|
|
292
|
-
if (isProposalSkipped(proposalResult)) {
|
|
293
|
-
// Should never happen when force:true, but be defensive.
|
|
294
|
-
throw new Error(`Unexpected skip in propose command: ${proposalResult.message}`);
|
|
192
|
+
catch (err) {
|
|
193
|
+
return {
|
|
194
|
+
schemaVersion: 2,
|
|
195
|
+
ok: false,
|
|
196
|
+
reason: "parse_error",
|
|
197
|
+
error: err instanceof Error ? err.message : String(err),
|
|
198
|
+
type: options.type,
|
|
199
|
+
name: options.name,
|
|
200
|
+
engine: engineName,
|
|
201
|
+
exitCode: result.exitCode,
|
|
202
|
+
stdout: result.stdout,
|
|
203
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
204
|
+
...noticeFields(notices),
|
|
205
|
+
};
|
|
295
206
|
}
|
|
296
|
-
|
|
207
|
+
}
|
|
208
|
+
const unsafeContent = generatedContentRejection(payload.content, redactSensitiveText(payload.content, sensitiveValues));
|
|
209
|
+
if (unsafeContent) {
|
|
297
210
|
return {
|
|
298
211
|
schemaVersion: 2,
|
|
299
|
-
ok:
|
|
300
|
-
|
|
301
|
-
|
|
212
|
+
ok: false,
|
|
213
|
+
reason: "parse_error",
|
|
214
|
+
error: unsafeContent,
|
|
215
|
+
type: options.type,
|
|
216
|
+
name: options.name,
|
|
302
217
|
engine: engineName,
|
|
303
|
-
|
|
218
|
+
exitCode: result.exitCode,
|
|
304
219
|
...noticeFields(notices),
|
|
305
220
|
};
|
|
306
221
|
}
|
|
307
|
-
|
|
308
|
-
|
|
222
|
+
// 6. Insert the proposal. Note: we allow the agent's `ref` to normalise the
|
|
223
|
+
// asset name (e.g. path-cleanup), but only after validating that the ref is
|
|
224
|
+
// well-formed and the type still matches the requested type.
|
|
225
|
+
const expectedRef = proposeItemRef(target.source, options.type, options.name);
|
|
226
|
+
let ref = expectedRef;
|
|
227
|
+
if (payload.ref) {
|
|
228
|
+
let parsedRef;
|
|
229
|
+
try {
|
|
230
|
+
parsedRef = parseRefInput(payload.ref);
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
return {
|
|
234
|
+
schemaVersion: 2,
|
|
235
|
+
ok: false,
|
|
236
|
+
reason: "parse_error",
|
|
237
|
+
error: err instanceof Error ? err.message : String(err),
|
|
238
|
+
type: options.type,
|
|
239
|
+
name: options.name,
|
|
240
|
+
engine: engineName,
|
|
241
|
+
exitCode: result.exitCode,
|
|
242
|
+
stdout: result.stdout,
|
|
243
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
244
|
+
...noticeFields(notices),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
if (parsedRef.type !== options.type) {
|
|
248
|
+
return {
|
|
249
|
+
schemaVersion: 2,
|
|
250
|
+
ok: false,
|
|
251
|
+
reason: "parse_error",
|
|
252
|
+
error: `Agent returned ref type ${parsedRef.type} but expected ${options.type}`,
|
|
253
|
+
type: options.type,
|
|
254
|
+
name: options.name,
|
|
255
|
+
engine: engineName,
|
|
256
|
+
exitCode: result.exitCode,
|
|
257
|
+
stdout: result.stdout,
|
|
258
|
+
...(result.stderr ? { stderr: result.stderr } : {}),
|
|
259
|
+
...noticeFields(notices),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
ref = proposeItemRef(target.source, parsedRef.type, parsedRef.name);
|
|
309
263
|
}
|
|
264
|
+
const createInput = {
|
|
265
|
+
ref,
|
|
266
|
+
source: "propose",
|
|
267
|
+
sourceRun: `propose-${Date.now()}`,
|
|
268
|
+
target,
|
|
269
|
+
payload: {
|
|
270
|
+
content: payload.content,
|
|
271
|
+
...(payload.frontmatter ? { frontmatter: payload.frontmatter } : {}),
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
const proposal = createProposal(stash, createInput, options.ctx);
|
|
275
|
+
return {
|
|
276
|
+
schemaVersion: 2,
|
|
277
|
+
ok: true,
|
|
278
|
+
proposal,
|
|
279
|
+
ref: proposal.ref,
|
|
280
|
+
engine: engineName,
|
|
281
|
+
durationMs: result.durationMs,
|
|
282
|
+
...noticeFields(notices),
|
|
283
|
+
};
|
|
310
284
|
}
|