@hassangameryt/freeflow 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +2 -2
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +96 -149
- package/capabilities/cognitive-routing/SKILL.md +21 -129
- package/capabilities/cognitive-routing/references/coordinator.md +163 -0
- package/capabilities/cognitive-routing/references/worker.md +38 -0
- package/capabilities/compaction/SKILL.md +3 -3
- package/capabilities/compaction/references/summary-format.md +26 -15
- package/capabilities/messaging/SKILL.md +49 -0
- package/capabilities/task-memory/SKILL.md +87 -0
- package/command-surface.json +6 -54
- package/gemini-extension.json +1 -1
- package/hooks/claude/hooks.json +13 -3
- package/hooks/codex/hooks.json +2 -1
- package/hooks/shared/runtime-context.mjs +69 -77
- package/package.json +25 -8
- package/pi-extension/dist/ask-user/ask.js +108 -0
- package/pi-extension/dist/ask-user/form.js +250 -0
- package/pi-extension/dist/ask-user/questions.js +66 -0
- package/pi-extension/dist/ask-user/tool.js +124 -0
- package/pi-extension/dist/cognitive-routing/assembler.js +35 -11
- package/pi-extension/dist/cognitive-routing/bootstrap.js +90 -0
- package/pi-extension/dist/cognitive-routing/config.js +3 -4
- package/pi-extension/dist/cognitive-routing/event-store.js +4 -1
- package/pi-extension/dist/cognitive-routing/gate.js +20 -5
- package/pi-extension/dist/cognitive-routing/handlers.js +15 -13
- package/pi-extension/dist/cognitive-routing/model-control.js +17 -8
- package/pi-extension/dist/cognitive-routing/projection.js +23 -6
- package/pi-extension/dist/cognitive-routing/provenance.js +3 -1
- package/pi-extension/dist/cognitive-routing/render.js +15 -15
- package/pi-extension/dist/cognitive-routing/runtime.js +4 -2
- package/pi-extension/dist/cognitive-routing/schemas.js +4 -4
- package/pi-extension/dist/cognitive-routing/session.js +3 -1
- package/pi-extension/dist/cognitive-routing/sources.js +29 -4
- package/pi-extension/dist/cognitive-routing/state.js +18 -8
- package/pi-extension/dist/cognitive-routing/status.js +4 -3
- package/pi-extension/dist/cognitive-routing/tools.js +29 -15
- package/pi-extension/dist/cognitive-routing/types.js +10 -1
- package/pi-extension/dist/compaction/carry.js +36 -22
- package/pi-extension/dist/compaction/config.js +4 -2
- package/pi-extension/dist/compaction/controller.js +52 -29
- package/pi-extension/dist/compaction/harness.js +19 -3
- package/pi-extension/dist/compaction/results.js +14 -13
- package/pi-extension/dist/compaction/tool.js +6 -6
- package/pi-extension/dist/host/catalog.js +20 -35
- package/pi-extension/dist/host/config-validation.js +233 -0
- package/pi-extension/dist/host/config.js +78 -91
- package/pi-extension/dist/host/inbound.js +142 -0
- package/pi-extension/dist/host/projection-tags.js +1 -1
- package/pi-extension/dist/host/prompts.js +24 -13
- package/pi-extension/dist/host/read-only-session.js +6 -1
- package/pi-extension/dist/host/request-history.js +7 -3
- package/pi-extension/dist/host/rows.js +25 -0
- package/pi-extension/dist/host/runtime-state.js +17 -2
- package/pi-extension/dist/host/section-keeper.js +85 -0
- package/pi-extension/dist/host/settings/freeflow-command.js +846 -93
- package/pi-extension/dist/host/settings/settings-view.js +27 -8
- package/pi-extension/dist/host/status.js +19 -5
- package/pi-extension/dist/index.js +638 -72
- package/pi-extension/dist/messaging/config.js +27 -0
- package/pi-extension/dist/messaging/messaging.js +398 -0
- package/pi-extension/dist/messaging/registry.js +57 -0
- package/pi-extension/dist/messaging/render.js +90 -0
- package/pi-extension/dist/messaging/tools.js +109 -0
- package/pi-extension/dist/messaging/transport.js +101 -0
- package/pi-extension/dist/provider-support/cache/keepalive.js +16 -4
- package/pi-extension/dist/task-memory/config.js +49 -0
- package/pi-extension/dist/task-memory/registry.js +119 -0
- package/pi-extension/dist/task-memory/render.js +107 -0
- package/pi-extension/dist/task-memory/runtime.js +994 -0
- package/pi-extension/dist/task-memory/tool.js +233 -0
- package/pi-extension/dist/tool-execution/apply-patch/tool.js +1 -1
- package/pi-extension/dist/tool-execution/background.js +220 -28
- package/pi-extension/dist/tool-execution/config.js +14 -3
- package/pi-extension/dist/tool-execution/file-tracking.js +24 -4
- package/pi-extension/dist/tool-execution/guidance-notices.js +124 -0
- package/pi-extension/dist/tool-execution/skill-reads.js +143 -0
- package/pi-extension/dist/tool-execution/tools.js +2 -2
- package/runtime/prompts/cognitive-routing.md +4 -4
- package/runtime/prompts/core.md +24 -14
- package/runtime/prompts/interaction-contract.md +7 -4
- package/runtime/prompts/tool-execution.md +3 -16
- package/runtime/prompts/working-method.md +16 -99
- package/skills/deliver-work/SKILL.md +76 -0
- package/skills/deliver-work/references/branch-closeout.md +134 -0
- package/skills/deliver-work/references/commit.md +83 -0
- package/skills/deliver-work/references/launch.md +94 -0
- package/skills/deliver-work/references/release.md +85 -0
- package/skills/deliver-work/scripts/commit-state.mjs +139 -0
- package/skills/deliver-work/scripts/delivery-state.mjs +107 -0
- package/skills/deliver-work/scripts/lib/git-state.mjs +178 -0
- package/skills/deliver-work/scripts/push-route.mjs +122 -0
- package/skills/deliver-work/scripts/release-preflight.mjs +177 -0
- package/skills/discuss-work/SKILL.md +148 -0
- package/skills/{discuss → discuss-work}/references/discussion-continuity.md +10 -27
- package/skills/discuss-work/references/learning-action.md +36 -0
- package/skills/discuss-work/scripts/choices.mjs +101 -0
- package/skills/discuss-work/scripts/lib/choices.mjs +159 -0
- package/skills/evaluate-behavior/SKILL.md +107 -0
- package/skills/evaluate-behavior/references/authoring.md +381 -0
- package/skills/evaluate-behavior/references/coding-tasks.md +145 -0
- package/skills/evaluate-behavior/references/conversations-pipelines-judges.md +177 -0
- package/skills/evaluate-behavior/references/design-and-measurement.md +273 -0
- package/skills/evaluate-behavior/references/running-and-evidence.md +245 -0
- package/skills/evaluate-behavior/scripts/claude-guard.mjs +76 -0
- package/skills/evaluate-behavior/scripts/guard-rules.mjs +309 -0
- package/skills/evaluate-behavior/scripts/lib/agreement.mjs +90 -0
- package/skills/evaluate-behavior/scripts/lib/arms.mjs +55 -0
- package/skills/evaluate-behavior/scripts/lib/budget.mjs +87 -0
- package/skills/evaluate-behavior/scripts/lib/build-source.mjs +287 -0
- package/skills/evaluate-behavior/scripts/lib/clear.mjs +74 -0
- package/skills/evaluate-behavior/scripts/lib/container.mjs +395 -0
- package/skills/evaluate-behavior/scripts/lib/decision.mjs +418 -0
- package/skills/evaluate-behavior/scripts/lib/definitions.mjs +1072 -0
- package/skills/evaluate-behavior/scripts/lib/freeflow.mjs +103 -0
- package/skills/evaluate-behavior/scripts/lib/grade-command.mjs +591 -0
- package/skills/evaluate-behavior/scripts/lib/grade-comparison.mjs +90 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-interaction.mjs +19 -18
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-support.mjs +32 -5
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-workspace.mjs +28 -12
- package/skills/evaluate-behavior/scripts/lib/grade.mjs +101 -0
- package/skills/evaluate-behavior/scripts/lib/hooks.mjs +98 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/confinement.mjs +196 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/constraints.mjs +111 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/index.mjs +48 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/isolation.mjs +74 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/launch.mjs +123 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/model-call.mjs +73 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/recorder.mjs +178 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/session.mjs +494 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/skills.mjs +81 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/index.mjs +31 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/names.mjs +3 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/confinement.mjs +173 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/host.mjs +148 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/index.mjs +70 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/isolation.mjs +81 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/model-call.mjs +79 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/process.mjs +241 -0
- package/skills/{evaluate-skill/scripts/lib → evaluate-behavior/scripts/lib/hosts/pi}/rpc.mjs +144 -26
- package/skills/evaluate-behavior/scripts/lib/identity.mjs +82 -0
- package/skills/evaluate-behavior/scripts/lib/judge.mjs +688 -0
- package/skills/evaluate-behavior/scripts/lib/metrics.mjs +332 -0
- package/skills/evaluate-behavior/scripts/lib/model-call.mjs +17 -0
- package/skills/evaluate-behavior/scripts/lib/participants.mjs +616 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/process.mjs +22 -0
- package/skills/evaluate-behavior/scripts/lib/queue.mjs +54 -0
- package/skills/evaluate-behavior/scripts/lib/reference.mjs +343 -0
- package/skills/evaluate-behavior/scripts/lib/reuse.mjs +277 -0
- package/skills/evaluate-behavior/scripts/lib/review.mjs +933 -0
- package/skills/evaluate-behavior/scripts/lib/runner.mjs +732 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/sandbox.mjs +119 -14
- package/skills/evaluate-behavior/scripts/lib/scan-shell.mjs +457 -0
- package/skills/evaluate-behavior/scripts/lib/scan.mjs +479 -0
- package/skills/evaluate-behavior/scripts/lib/seal.mjs +91 -0
- package/skills/evaluate-behavior/scripts/lib/shell.mjs +560 -0
- package/skills/evaluate-behavior/scripts/lib/source-override.mjs +64 -0
- package/skills/evaluate-behavior/scripts/lib/subject-file.mjs +88 -0
- package/skills/{evaluate-skill/scripts/lib/pi.mjs → evaluate-behavior/scripts/lib/subject.mjs} +235 -265
- package/skills/evaluate-behavior/scripts/lib/task-copy.mjs +124 -0
- package/skills/evaluate-behavior/scripts/lib/trials.mjs +524 -0
- package/skills/evaluate-behavior/scripts/lib/validity.mjs +68 -0
- package/skills/evaluate-behavior/scripts/lib/view-html.mjs +454 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/view.mjs +159 -18
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/pi-command-tool.mjs +21 -6
- package/skills/evaluate-behavior/scripts/pi-container-route.mjs +23 -0
- package/skills/evaluate-behavior/scripts/pi-guard.mjs +77 -0
- package/skills/evaluate-behavior/scripts/pi-login-refresh.mjs +31 -0
- package/skills/evaluate-behavior/scripts/skill-eval.mjs +586 -0
- package/skills/execute-work/SKILL.md +96 -104
- package/skills/execute-work/references/code-practices.md +27 -51
- package/skills/execute-work/references/design.md +271 -0
- package/skills/execute-work/references/diagnose.md +117 -0
- package/skills/execute-work/references/migration.md +108 -0
- package/skills/execute-work/references/simplify.md +65 -0
- package/skills/execute-work/scripts/self-review.mjs +422 -0
- package/skills/execute-work/scripts/touch-map.mjs +290 -0
- package/skills/review-work/SKILL.md +89 -65
- package/skills/review-work/references/adjudication.md +94 -0
- package/skills/review-work/references/artifact.md +198 -0
- package/skills/review-work/references/evals-and-judges.md +66 -0
- package/skills/review-work/references/work.md +177 -0
- package/skills/review-work/scripts/check-brief.mjs +128 -0
- package/skills/review-work/scripts/review-packet.mjs +233 -0
- package/skills/setup-freeflow/SKILL.md +68 -17
- package/skills/track-work/SKILL.md +52 -20
- package/skills/track-work/references/handoff.md +190 -0
- package/skills/track-work/references/projects.md +51 -0
- package/skills/track-work/references/working-record-format.md +36 -18
- package/skills/track-work/scripts/lib/document.mjs +17 -13
- package/skills/track-work/scripts/lib/format.mjs +2 -0
- package/skills/track-work/scripts/lib/recover.mjs +254 -0
- package/skills/track-work/scripts/lib/registry.mjs +656 -0
- package/skills/track-work/scripts/lib/search.mjs +40 -0
- package/skills/track-work/scripts/lib/store.mjs +46 -15
- package/skills/track-work/scripts/lib/views.mjs +50 -1
- package/skills/track-work/scripts/working-record.mjs +232 -13
- package/skills/verify-work/SKILL.md +45 -37
- package/skills/verify-work/references/feature-map.md +120 -0
- package/skills/verify-work/references/runtime-evidence.md +203 -0
- package/skills/verify-work/references/test-design.md +25 -6
- package/skills/verify-work/scripts/test-changes.mjs +246 -0
- package/skills/write-docs/SKILL.md +113 -25
- package/skills/write-docs/references/documentation-shapes.md +68 -3
- package/skills/write-docs/references/spec-and-plan-shapes.md +308 -0
- package/skills/write-docs/scripts/artifact-check.mjs +148 -0
- package/skills/write-docs/scripts/docs-check.mjs +96 -6
- package/skills/write-docs/scripts/plan-lint.mjs +123 -0
- package/skills/write-skill/SKILL.md +92 -52
- package/skills/write-skill/references/activation-and-wording.md +143 -0
- package/skills/write-skill/references/placement-and-dependencies.md +154 -0
- package/skills/write-skill/scripts/lib/compare.mjs +701 -0
- package/skills/write-skill/scripts/lib/skill-author.mjs +197 -3
- package/skills/write-skill/scripts/skill-author.mjs +51 -8
- package/capabilities/cognitive-routing/references/both-mode.md +0 -36
- package/capabilities/cognitive-routing/references/executor-mode.md +0 -48
- package/capabilities/cognitive-routing/references/helper-mode.md +0 -47
- package/plugin.json +0 -33
- package/skills/action-selection/SKILL.md +0 -92
- package/skills/action-selection/references/trajectory-stalls.md +0 -73
- package/skills/bypass/SKILL.md +0 -153
- package/skills/commit-work/SKILL.md +0 -93
- package/skills/commit-work/references/git-state-edges.md +0 -94
- package/skills/commit-work/references/simple-push.md +0 -94
- package/skills/commit-work/references/staging-decisions.md +0 -106
- package/skills/decision-gate/SKILL.md +0 -87
- package/skills/design-for-depth/SKILL.md +0 -108
- package/skills/design-for-depth/references/design-pressure-signals.md +0 -84
- package/skills/design-for-depth/references/implementation-decisions.md +0 -76
- package/skills/design-for-depth/references/interface-design-loop.md +0 -105
- package/skills/design-for-depth/references/module-and-dependency-design.md +0 -117
- package/skills/design-for-depth/references/state-and-failure-boundaries.md +0 -125
- package/skills/diagnose-failure/SKILL.md +0 -140
- package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +0 -50
- package/skills/diagnose-failure/references/flaky-and-performance-diagnosis.md +0 -51
- package/skills/discuss/SKILL.md +0 -140
- package/skills/evaluate-skill/SKILL.md +0 -188
- package/skills/evaluate-skill/references/evaluation-definition-schema.md +0 -415
- package/skills/evaluate-skill/references/evaluation-design.md +0 -112
- package/skills/evaluate-skill/references/execution-and-evidence.md +0 -111
- package/skills/evaluate-skill/references/review-and-revision.md +0 -94
- package/skills/evaluate-skill/scripts/lib/definitions.mjs +0 -448
- package/skills/evaluate-skill/scripts/lib/grade-comparison.mjs +0 -60
- package/skills/evaluate-skill/scripts/lib/grade.mjs +0 -64
- package/skills/evaluate-skill/scripts/lib/review.mjs +0 -196
- package/skills/evaluate-skill/scripts/lib/runner.mjs +0 -405
- package/skills/evaluate-skill/scripts/lib/trials.mjs +0 -103
- package/skills/evaluate-skill/scripts/pi-guard.mjs +0 -181
- package/skills/evaluate-skill/scripts/skill-eval.mjs +0 -182
- package/skills/execute-work/references/execute-work-edges.md +0 -78
- package/skills/finish-branch/SKILL.md +0 -117
- package/skills/finish-branch/references/integration-options.md +0 -80
- package/skills/handoff/SKILL.md +0 -82
- package/skills/handoff/references/handoff-templates.md +0 -150
- package/skills/launch-work/SKILL.md +0 -116
- package/skills/launch-work/references/launch-readiness.md +0 -85
- package/skills/migration-work/SKILL.md +0 -115
- package/skills/migration-work/references/migration-lifecycle.md +0 -82
- package/skills/release-work/SKILL.md +0 -118
- package/skills/release-work/references/release-evidence.md +0 -78
- package/skills/review-artifact/SKILL.md +0 -143
- package/skills/review-artifact/references/adjudicate-artifact-review.md +0 -101
- package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +0 -159
- package/skills/review-work/references/adjudicate-work-review.md +0 -97
- package/skills/review-work/references/independent-work-reviewer-contract.md +0 -139
- package/skills/review-work/references/security-risk-lens.md +0 -67
- package/skills/setup-freeflow/references/activation-contract.md +0 -103
- package/skills/setup-freeflow/references/host-setup.md +0 -67
- package/skills/simplify-code/SKILL.md +0 -85
- package/skills/simplify-code/references/simplification-patterns.md +0 -70
- package/skills/verify-work/references/browser-runtime-evidence.md +0 -51
- package/skills/verify-work/references/integration-evidence.md +0 -49
- package/skills/verify-work/references/performance-evidence.md +0 -59
- package/skills/workflow/SKILL.md +0 -171
- package/skills/workflow/references/domain-skill-composition.md +0 -45
- package/skills/write-plan/SKILL.md +0 -92
- package/skills/write-plan/references/plan-shapes.md +0 -156
- package/skills/write-skill/references/activation-boundaries.md +0 -106
- package/skills/write-skill/references/agent-first-instructions.md +0 -133
- package/skills/write-skill/references/progressive-disclosure.md +0 -129
- package/skills/write-skill/references/skill-dependency-graphs.md +0 -192
- package/skills/write-spec/SKILL.md +0 -85
- package/skills/write-spec/references/artifact-standards.md +0 -86
- package/skills/write-spec/references/decision-records.md +0 -80
- package/skills/write-spec/references/spec-shapes.md +0 -143
- /package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/evidence.mjs +0 -0
- /package/skills/{evaluate-skill → evaluate-behavior}/scripts/pi-observer.mjs +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Local release preflight (references/release.md, "Preflight The Exact Release"): the declared version and whether it
|
|
3
|
+
// is valid and new, whether its tag already exists locally and where it points, the changelog's state for it, the
|
|
4
|
+
// source (branch, clean tree, HEAD), and for an npm package what `npm pack --dry-run` would publish. It changes
|
|
5
|
+
// nothing and publishes nothing. Registry state needs the network and is reported unavailable.
|
|
6
|
+
// Usage: release-preflight.mjs [--version <x.y.z>] [--tag-prefix <v>] [--root <repository>] [--no-pack] [--json]
|
|
7
|
+
// --version defaults to the declared version. Exit code 0 when no problem was found, 1 when one was, 2 on a usage
|
|
8
|
+
// error or outside a Git repository.
|
|
9
|
+
import { spawnSync } from "node:child_process";
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { parseArgs } from "node:util";
|
|
13
|
+
import {
|
|
14
|
+
branchState,
|
|
15
|
+
changelog,
|
|
16
|
+
git,
|
|
17
|
+
latestTag,
|
|
18
|
+
projectVersion,
|
|
19
|
+
repositoryRoot,
|
|
20
|
+
workingState,
|
|
21
|
+
} from "./lib/git-state.mjs";
|
|
22
|
+
|
|
23
|
+
const USAGE =
|
|
24
|
+
"Usage: release-preflight.mjs [--version <x.y.z>] [--tag-prefix <v>] [--root <repository>] [--no-pack] [--json]";
|
|
25
|
+
let values;
|
|
26
|
+
try {
|
|
27
|
+
({ values } = parseArgs({
|
|
28
|
+
options: {
|
|
29
|
+
version: { type: "string" },
|
|
30
|
+
"tag-prefix": { type: "string", default: "v" },
|
|
31
|
+
root: { type: "string" },
|
|
32
|
+
"no-pack": { type: "boolean", default: false },
|
|
33
|
+
json: { type: "boolean", default: false },
|
|
34
|
+
},
|
|
35
|
+
}));
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(`${error.message}\n${USAGE}`);
|
|
38
|
+
process.exit(2);
|
|
39
|
+
}
|
|
40
|
+
const root = repositoryRoot(values.root ?? ".");
|
|
41
|
+
if (!root) {
|
|
42
|
+
console.error("not inside a Git repository");
|
|
43
|
+
process.exit(2);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const problems = [];
|
|
47
|
+
const facts = [];
|
|
48
|
+
const declared = projectVersion(root);
|
|
49
|
+
const version = values.version ?? declared?.version ?? null;
|
|
50
|
+
const SEMVER = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$/;
|
|
51
|
+
if (!version) problems.push("no version: none declared (package.json, pyproject.toml, Cargo.toml) and none given");
|
|
52
|
+
else {
|
|
53
|
+
if (!SEMVER.test(version)) problems.push(`version ${version} is not a valid x.y.z version`);
|
|
54
|
+
if (values.version && declared?.version && declared.version !== values.version)
|
|
55
|
+
problems.push(`version ${values.version} differs from the declared ${declared.version} (${declared.source})`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const tagName = version ? `${values["tag-prefix"]}${version}` : null;
|
|
59
|
+
const tagCommit = tagName ? git(root, ["rev-list", "-n", "1", `refs/tags/${tagName}`]) : null;
|
|
60
|
+
const branch = branchState(root);
|
|
61
|
+
if (tagCommit) {
|
|
62
|
+
if (tagCommit === branch.head)
|
|
63
|
+
facts.push(`tag ${tagName} exists locally and points at HEAD: a release of this commit may already be tagged`);
|
|
64
|
+
else problems.push(`tag ${tagName} already exists locally at ${tagCommit.slice(0, 12)}, not HEAD: never move it`);
|
|
65
|
+
}
|
|
66
|
+
const previous = latestTag(root);
|
|
67
|
+
if (previous && version && SEMVER.test(version)) {
|
|
68
|
+
const parse = (text) =>
|
|
69
|
+
text
|
|
70
|
+
.replace(/^[^\d]*/, "")
|
|
71
|
+
.split(/[-+]/)[0]
|
|
72
|
+
.split(".")
|
|
73
|
+
.map(Number);
|
|
74
|
+
const [a, b] = [parse(version), parse(previous.tag)];
|
|
75
|
+
const newer = a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
|
|
76
|
+
if (newer < 0 && previous.tag !== tagName)
|
|
77
|
+
problems.push(`version ${version} is older than the latest tag ${previous.tag}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const notes = changelog(root);
|
|
81
|
+
if (!notes) facts.push("no changelog found");
|
|
82
|
+
else {
|
|
83
|
+
const released = version && notes.versions.includes(version);
|
|
84
|
+
if (released) facts.push(`${notes.file} has a section for ${version}`);
|
|
85
|
+
else if (notes.unreleased?.entries)
|
|
86
|
+
facts.push(`${notes.file}: ${notes.unreleased.entries} Unreleased entries, no ${version} section yet`);
|
|
87
|
+
else problems.push(`${notes.file} has no ${version ?? "version"} section and no Unreleased entries`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const working = workingState(root);
|
|
91
|
+
const dirty = working.staged.length + working.unstaged.length + working.conflicted.length;
|
|
92
|
+
if (branch.detached) facts.push(`detached HEAD at ${branch.head.slice(0, 12)}`);
|
|
93
|
+
if (dirty) problems.push(`${dirty} uncommitted change(s): a release is built from a commit`);
|
|
94
|
+
if (working.untracked.length) facts.push(`${working.untracked.length} untracked path(s): check none would be packed`);
|
|
95
|
+
if (branch.upstream && branch.ahead) facts.push(`${branch.ahead} commit(s) not on ${branch.upstream} (local refs)`);
|
|
96
|
+
|
|
97
|
+
// What npm would publish, from a dry run that runs no lifecycle scripts.
|
|
98
|
+
let pack = null;
|
|
99
|
+
if (!values["no-pack"] && existsSync(join(root, "package.json"))) {
|
|
100
|
+
const run = spawnSync("npm", ["pack", "--dry-run", "--ignore-scripts", "--json"], {
|
|
101
|
+
cwd: root,
|
|
102
|
+
encoding: "utf8",
|
|
103
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
104
|
+
});
|
|
105
|
+
try {
|
|
106
|
+
const [result] = JSON.parse(run.stdout);
|
|
107
|
+
const files = result.files.map((file) => file.path);
|
|
108
|
+
const unexpected = files.filter((path) =>
|
|
109
|
+
/(^|\/)(\.env(\..*)?|\.npmrc|.*\.(pem|key|p12)|\.freeflow\/|node_modules\/|.*\.log)$|(^|\/)\.freeflow\//.test(
|
|
110
|
+
path,
|
|
111
|
+
),
|
|
112
|
+
);
|
|
113
|
+
pack = {
|
|
114
|
+
name: result.name,
|
|
115
|
+
version: result.version,
|
|
116
|
+
files: files.length,
|
|
117
|
+
size: result.size,
|
|
118
|
+
unpackedSize: result.unpackedSize,
|
|
119
|
+
unexpected,
|
|
120
|
+
};
|
|
121
|
+
if (result.version !== version) problems.push(`npm would pack version ${result.version}, not ${version}`);
|
|
122
|
+
if (unexpected.length)
|
|
123
|
+
problems.push(`npm would publish files that look private: ${unexpected.slice(0, 10).join(", ")}`);
|
|
124
|
+
const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
125
|
+
for (const entry of [
|
|
126
|
+
manifest.main,
|
|
127
|
+
...Object.values(typeof manifest.bin === "string" ? { bin: manifest.bin } : (manifest.bin ?? {})),
|
|
128
|
+
].filter(Boolean))
|
|
129
|
+
if (!files.includes(entry.replace(/^\.\//, "")))
|
|
130
|
+
problems.push(`package entry ${entry} is not in the packed files`);
|
|
131
|
+
} catch {
|
|
132
|
+
pack = { error: (run.stderr || run.stdout || "npm pack failed").trim().split("\n").slice(-3).join(" ") };
|
|
133
|
+
problems.push(`npm pack --dry-run failed: ${pack.error}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const report = {
|
|
138
|
+
command: "release-preflight",
|
|
139
|
+
root,
|
|
140
|
+
version,
|
|
141
|
+
declared,
|
|
142
|
+
tag: { name: tagName, exists: Boolean(tagCommit), commit: tagCommit?.slice(0, 12) ?? null },
|
|
143
|
+
latestTag: previous,
|
|
144
|
+
source: {
|
|
145
|
+
branch: branch.branch,
|
|
146
|
+
head: branch.head,
|
|
147
|
+
subject: branch.subject,
|
|
148
|
+
dirty,
|
|
149
|
+
untracked: working.untracked.length,
|
|
150
|
+
},
|
|
151
|
+
changelog: notes,
|
|
152
|
+
pack,
|
|
153
|
+
problems,
|
|
154
|
+
facts,
|
|
155
|
+
unavailable: [
|
|
156
|
+
"whether the version is already on the registry",
|
|
157
|
+
"remote tags",
|
|
158
|
+
"CI on the release commit",
|
|
159
|
+
"signing and publish permissions",
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
if (values.json) console.log(JSON.stringify(report, null, 2));
|
|
163
|
+
else {
|
|
164
|
+
console.log(
|
|
165
|
+
`Release ${version ?? "(no version)"} as ${tagName ?? "(no tag)"} from ${branch.branch ?? "detached HEAD"} ${branch.head?.slice(0, 12) ?? ""} ${branch.subject ?? ""}`,
|
|
166
|
+
);
|
|
167
|
+
if (pack && !pack.error)
|
|
168
|
+
console.log(`npm pack: ${pack.name}@${pack.version}, ${pack.files} files, ${pack.size} bytes packed`);
|
|
169
|
+
for (const fact of facts) console.log(`- ${fact}`);
|
|
170
|
+
console.log(
|
|
171
|
+
problems.length
|
|
172
|
+
? `Problems (${problems.length}):\n${problems.map((each) => `- ${each}`).join("\n")}`
|
|
173
|
+
: "No problem found locally.",
|
|
174
|
+
);
|
|
175
|
+
console.log(`Unavailable without the network: ${report.unavailable.join("; ")}.`);
|
|
176
|
+
}
|
|
177
|
+
process.exit(problems.length ? 1 : 0);
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: discuss-work
|
|
3
|
+
description: "Use whenever what to do, or how, is not settled yet: exploring a problem, comparing options or approaches, questioning assumptions, brainstorming, planning an approach, or revisiting a direction after new evidence. Read it at a task's first request, before your first tool call, to decide with the user what you will do, where you stop and which choices are theirs before anything is built, fixed or changed. Also use mid-work when a choice the user owns comes up (behavior, names, defaults, scope, cost, risk) or sources conflict; when a question needs a quick experiment before building on it; when a discussion or its decisions must outlast the conversation; and when the user asks to skip or lighten optional steps such as a plan, a review or a record."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Discuss Work
|
|
7
|
+
|
|
8
|
+
Work out with the user what to do, and how, while that is still open; agree the work and every choice that is the user's before building; keep those choices in one decision list through the work; and account for them at the end.
|
|
9
|
+
|
|
10
|
+
A **user-owned choice** changes something the user will see or live with: behavior, names, text or public interfaces the user meets, defaults, what happens on error, data written or lost, scope, compatibility or migration, permissions, security, privacy, cost, or other risk. Mechanics that change none of these are yours to choose. The [Interaction Contract](../../runtime/prompts/interaction-contract.md) governs what the user's turn asks for.
|
|
11
|
+
|
|
12
|
+
The **Rules** below are binding; if one cannot be met, stop and say why. Everything else is **judgment**: follow its stated goal, and adapt when a different choice serves that goal better.
|
|
13
|
+
|
|
14
|
+
## Routes
|
|
15
|
+
|
|
16
|
+
| Situation | Go to |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| What to do, or how, is still open | Explore, below |
|
|
19
|
+
| A task that builds or changes behavior, before the first edit | Agree Before Building, below |
|
|
20
|
+
| A user-owned choice or conflicting sources mid-work | Choices During The Work, below |
|
|
21
|
+
| Writing or checking the decision list, or the agreement, handover or catch-up built from it | Run [choices](scripts/choices.mjs), as Build The Decision List says |
|
|
22
|
+
| A question existing evidence cannot settle but running something could | [learning action](references/learning-action.md) |
|
|
23
|
+
| Discussion state, an emerging route or its Checkpoints must outlast the conversation | [discussion continuity](references/discussion-continuity.md) |
|
|
24
|
+
| Representation, interfaces, ownership, state or failure behavior could materially change a technical recommendation | Execute Work's [design](../execute-work/references/design.md) |
|
|
25
|
+
| A reported or recurring failure needs a cause rather than options | Execute Work's [diagnose](../execute-work/references/diagnose.md) |
|
|
26
|
+
| Agreed, concrete work | [Execute Work](../execute-work/SKILL.md) |
|
|
27
|
+
|
|
28
|
+
## Rules
|
|
29
|
+
|
|
30
|
+
- Conversation, convergence, a recommendation or a recorded proposal never authorizes building. On a task that builds or changes behavior, send the agreement before the first edit and wait for the user's answer, unless a case in "When To Skip" applies.
|
|
31
|
+
- Leave priorities, behavior, constraints and tradeoffs the user owns to the user. After asking, stop: do not perform the blocked action until the user answers, and never settle a user-owned choice by proceeding.
|
|
32
|
+
- Never ask the user to choose between factual claims that evidence can settle; look them up.
|
|
33
|
+
- An answer decides only what it answers. A question, criticism, hypothesis, condition, or request for more information is not a decision: respond to it and keep waiting. Urgency, prior effort, or general approval to continue settles no choice that was not named.
|
|
34
|
+
- Keep supported facts and the user's decisions apart from hypotheses, proposals and open choices. Your recommendation or default never becomes a requirement or a Decision because it is repeated, recorded or built; record as a Decision only what the user accepted.
|
|
35
|
+
- Every user-owned choice the work makes goes in the decision list, whether or not anyone answered it. A technical choice that changes something the user will see goes in the plain list.
|
|
36
|
+
- Never weaken required behavior to make an approach look simpler.
|
|
37
|
+
|
|
38
|
+
## Explore
|
|
39
|
+
|
|
40
|
+
Goal: enough shared understanding to choose the next sound action, at the depth the user asked for.
|
|
41
|
+
|
|
42
|
+
Respond to the substance before steering the process. A request to discuss keeps the user involved: gather what the question needs, say what it implies, and come back at the next meaningful question or supported conclusion. A direct request that settles the outcome and leaves the approach to you needs no discussion when existing evidence can resolve the remaining facts and reversible local choices.
|
|
43
|
+
|
|
44
|
+
Name which understanding is missing, and establish only that: **what** (the problem, desired result, accepted behavior, constraints, non-goals, what counts as success) or **how** (mechanism, dependencies, affected boundaries, tradeoffs, the evidence needed in the actual environment). When reopening, name what changed and keep what still holds; a new local obstacle does not reopen the whole task.
|
|
45
|
+
|
|
46
|
+
Before inspecting, name the missing fact and how its answer could change the discussion, and check whether current evidence already answers it. Read the focused source, caller, contract or observation that answers it, not a survey, and read more only when the result leaves a material question open; inspect code, tests, docs, supplied material and current primary sources for external versions or interfaces rather than asking the user for facts you can find. Source inspection cannot establish unobserved runtime behavior. Stop when the evidence supports the next decision; do not collect every later dependency or plan the exact implementation while the outcome is still open.
|
|
47
|
+
|
|
48
|
+
Carry your share of the thinking: say what the evidence and intent imply, challenge unsupported claims and consequential assumptions, compare only materially different paths that could realistically be chosen with what each sacrifices and assumes, recommend the best-supported one and what would change it, and revise when evidence changes. Keep one consequential uncertainty in focus; no questionnaire, no invented alternatives for ordinary choices. Before recommending a new obligation, tell a requirement from a limitation of the current approach, and give its consequence in the user's terms ("requires changing and distributing a patched host," not "needs a provenance interface"), with a simpler in-scope alternative when one is supported.
|
|
49
|
+
|
|
50
|
+
When the likely work is clear, propose coherent outcomes and their dependencies, near-term work concrete and later work directional. End the discussion when the next sound action no longer depends on open direction, or a learning action, user decision, wait or stop is clear; not because more could be explored. Return what the next step needs: supported understanding, tentative approach, open questions that matter, evidence, the recommended or accepted next action, and what is still unauthorized. Stable accepted content that needs a durable source becomes a Spec, and an ordered strategy that must outlast the conversation a Plan, through [Write Docs](../write-docs/SKILL.md); neither is mandatory. When the user asks to build, agree it below; when they leave the rest of the investigation and implementation to you, do not make them finish planning it or gather again what the discussion found.
|
|
51
|
+
|
|
52
|
+
## Agree Before Building
|
|
53
|
+
|
|
54
|
+
### Build The Decision List
|
|
55
|
+
|
|
56
|
+
Goal: before editing, every place where the request, the repository and the developer docs leave a user-owned choice open is written down with your default.
|
|
57
|
+
|
|
58
|
+
Read the request in the layers Execute Work's [Read The Request](../execute-work/SKILL.md#read-the-request) lists, and find what the change touches; each open choice becomes one item, and what those sources settle is not listed. Write technical items too (names, files, data structures, the code you will copy, exact messages): listing them is how you notice choices you would otherwise make unseen.
|
|
59
|
+
|
|
60
|
+
Each item has:
|
|
61
|
+
|
|
62
|
+
- an ID: `P1`, `P2`… for plain items the user sees, `T1`, `T2`… for technical ones;
|
|
63
|
+
- the choice, for a plain item phrased as what the user will see or live with ("When several jobs pile up, should the oldest run first or the newest?", not "Queue or stack?");
|
|
64
|
+
- your default and why: what matches existing behavior and is easiest to reverse, citing where;
|
|
65
|
+
- for a technical item, the plain item it serves (`T3 -> P1`);
|
|
66
|
+
- its state: `proposed`, `agreed` (the user answered; quote them), `default` (no one answered), `changed` (with why), `new` (found after the agreement; the user has not seen it), or `dropped`.
|
|
67
|
+
|
|
68
|
+
Write one line per item, plain items first:
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
- P1 [agreed] When jobs pile up, which runs first? -> oldest first (the scheduler does, src/sched.ts:40). You: "go" (2026-10-20). Shows at: src/queue.ts:12
|
|
72
|
+
- P2 [new] Text when the queue is full -> "Queue full, try later". Shows at: src/queue.ts:30
|
|
73
|
+
- T1 [default] FIFO array in queue.ts -> serves P1
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Check the list with [choices](scripts/choices.mjs): `node <discuss-work-directory>/scripts/choices.mjs validate --list <file|->`, or `--record <record.md>` for the task's `sources/decisions.md`. It refuses a bad ID, state or `T -> P` link, or a plain item without a default.
|
|
77
|
+
|
|
78
|
+
### Send The Agreement
|
|
79
|
+
|
|
80
|
+
Goal: the user can agree in one word or correct one line.
|
|
81
|
+
|
|
82
|
+
Send one reply, not a dialog, before the first edit:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
What I'll do: <the outcome>
|
|
86
|
+
Where I stop: <done when; what I won't touch>
|
|
87
|
+
Your decisions: 1. <a choice the request leaves open, as the user meets it>. I'd go with <default>, because <reason>.
|
|
88
|
+
2. ...
|
|
89
|
+
Technical: <N> more choices; say "show technical" to see them.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`choices.mjs agreement --do <outcome> --stop <where you stop>` renders this reply from the list. Show the technical list in full when the user asks or has said they always want it, and leave the line out when they have said never. With no plain items, say so and still wait.
|
|
93
|
+
|
|
94
|
+
`Where I stop` names the endpoint the user can hold you to, and where you come back. After discussing several possible Slices, an ambiguous "proceed" needs it settled: the next Slice and return, or the whole task? Do not ask when the user already named the endpoint.
|
|
95
|
+
|
|
96
|
+
"Go", "fine", "your call" and "just do it" accept every default: those items become `agreed`. A correction changes only the item it names. Then build within the agreement, through to where you stop.
|
|
97
|
+
|
|
98
|
+
### When To Skip
|
|
99
|
+
|
|
100
|
+
Goal: stop wherever an unseen choice could change the result, and nowhere else.
|
|
101
|
+
|
|
102
|
+
- A question, discussion or review that changes nothing needs no agreement.
|
|
103
|
+
- A change the user specified exactly ("change `state=draft` to `state=final` in target.txt"), or a run where no one can answer (a routed worker, an unattended run), counts as the agreement: take your defaults for anything it leaves open (state `default`) and put the whole list in your final report.
|
|
104
|
+
|
|
105
|
+
A request that looks clear is not a skip: the choices it leaves open are the ones you have not noticed yet.
|
|
106
|
+
|
|
107
|
+
When the user explicitly asks to skip an optional step, such as waiting for this agreement, a plan, a review or a record, skip only what they named, for as long as they said. It changes no authority, no checkpoint they selected, and no claim: a check they decline leaves its claim unverified. Without the wait, take your defaults (state `default`), still ask one question before a hard-to-reverse choice, and put the whole list in your final report. When a standing skip must survive context loss and a Working Record exists, record it in the Work agreement through Track Work.
|
|
108
|
+
|
|
109
|
+
### Keep The List
|
|
110
|
+
|
|
111
|
+
Goal: after an interruption or compaction, the next context knows what the user decided and what you only assumed.
|
|
112
|
+
|
|
113
|
+
Without a Working Record, the list lives in the conversation; never create a record only to hold it. With one, [Track Work](../track-work/SKILL.md) says where the agreement, the user's answers and the list live.
|
|
114
|
+
|
|
115
|
+
Under [Cognitive Routing](../../capabilities/cognitive-routing/SKILL.md), only Coordinator keeps the list and asks the user; a worker returns the choices it made.
|
|
116
|
+
|
|
117
|
+
## Choices During The Work
|
|
118
|
+
|
|
119
|
+
Goal: no choice is made silently, and the user is interrupted only when the work cannot go on without them.
|
|
120
|
+
|
|
121
|
+
- A new choice that blocks the next step: settle its facts first, then ask one question (Ask One Question) and wait.
|
|
122
|
+
- A new choice that does not block: take your default, add it as `new`, and continue.
|
|
123
|
+
- A default that proves wrong: mark it `changed` with why; if it changes an `agreed` item, that needs the user's yes.
|
|
124
|
+
- Several at once: ask the earliest one whose answer decides whether the others matter. Mid-work questions come one at a time; the agreement is the only list you send.
|
|
125
|
+
- Work that turns out larger with the same outcome stays covered: continue without asking.
|
|
126
|
+
- A remedy that makes a user-owned choice needs a new yes: explain its concrete consequence and the realistic alternatives, then ask.
|
|
127
|
+
- New evidence that reopens the direction itself, not one bounded choice: go back to Explore for what changed.
|
|
128
|
+
|
|
129
|
+
When sources the work relies on disagree, state each one's exact claim, scope and status (current, accepted, draft, historical, generated) and apply the repository's own precedence; code is not right because it runs, and tests are not requirements because they fail. Ask only when precedence does not settle it and the answer changes the result.
|
|
130
|
+
|
|
131
|
+
## Ask One Question
|
|
132
|
+
|
|
133
|
+
Goal: the user decides from one look, knows what you recommend, and their answer settles exactly what you asked.
|
|
134
|
+
|
|
135
|
+
When the host has a question tool (`ask_user` on Pi with Freeflow, `AskUserQuestion` on Claude Code), a bounded choice of two to four real options usually goes in its dialog, with what you found and why it matters in your reply. Ask in your reply when the choice needs more explanation, or no dialog can be shown.
|
|
136
|
+
|
|
137
|
+
- The question is one full sentence about the outcome the user owns ("Ship Task Memory on or off by default?"), not the mechanics ("Which value for `taskMemory.enabled`?").
|
|
138
|
+
- Give two to four real options, each a few words with what choosing it does and costs; leave out dominated, unsafe, unavailable and hypothetical ones, and never add "Other".
|
|
139
|
+
- Put your recommendation first, its label ending in "(Recommended)", when evidence supports one.
|
|
140
|
+
- If the user closes the dialog, ask in your reply and do not act on the choice meanwhile.
|
|
141
|
+
|
|
142
|
+
Record the question and the user's answer in their words.
|
|
143
|
+
|
|
144
|
+
## Account At The End
|
|
145
|
+
|
|
146
|
+
Goal: before you claim done, the user sees every choice they have not seen.
|
|
147
|
+
|
|
148
|
+
The decision check runs in [Review Work](../review-work/SKILL.md)'s self-review of work, against this list. Find the choices the work made that the agreement did not settle, reading the change for anything the user would see: names, messages, defaults, behavior on error or in cases nobody specified, data written, and conventions copied from nearby code. Bring each `agreed` item with where the user agreed it (the work agreement, a Decision such as `D-003`, or their message) and the `file:line`, test or output that shows it was done as agreed, and each `changed` item with its reason; add each choice the diff shows that no item covers as `new`. Choices for the user stay in this list, never in a Decision, which holds only what the user accepted; building a choice does not settle it. The hand-over (the pull request through [Deliver Work](../deliver-work/SKILL.md), or the final report) shows what done looks like against what was done, and only the `new`, `changed` and `default` items. Agreed items stay out. `choices.mjs handover` lists those items; after an unattended run, `choices.mjs catch-up --record <record.md>` lists the defaults taken, the choices waiting and what ran.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Discussion Continuity
|
|
2
2
|
|
|
3
|
-
Read this before preserving discussion across context loss, creating or updating durable
|
|
3
|
+
Read this when discussion state, an emerging route or its Checkpoints must outlast the conversation: before preserving discussion across context loss, creating or updating a Working Record or another durable source from discussion, or carrying a proposed or selected Checkpoint beyond the current context.
|
|
4
4
|
|
|
5
|
-
This reference is judgment: adapt it to the discussion. Its binding statements restate [Discuss](../SKILL.md)
|
|
5
|
+
This reference is judgment: adapt it to the discussion. Its binding statements restate [Discuss Work](../SKILL.md) or Track Work Rules.
|
|
6
6
|
|
|
7
|
-
Discussion state is not automatically a Working Record, Spec, Plan, checkpoint, or authority. Preserve the required outcome separately from the current approach, and distinguish the user's
|
|
7
|
+
Discussion state is not automatically a Working Record, Spec, Plan, checkpoint, or authority. Preserve the required outcome separately from the current approach, and distinguish the user's work agreement from proposals that have not been selected.
|
|
8
8
|
|
|
9
9
|
## Keep It In Conversation When Possible
|
|
10
10
|
|
|
@@ -27,7 +27,7 @@ Prefer natural prose. Use structured fields only when they prevent ambiguity or
|
|
|
27
27
|
|
|
28
28
|
Do not preserve a transcript, repeated rationale, rejected alternatives that no longer matter, or every discussion turn. Retain a rejected approach when losing its reason would cause the next context to repeat it.
|
|
29
29
|
|
|
30
|
-
## Choose Durable
|
|
30
|
+
## Choose A Durable Destination By Purpose
|
|
31
31
|
|
|
32
32
|
Use a durable destination only when losing the state could cause later misalignment:
|
|
33
33
|
|
|
@@ -42,15 +42,7 @@ Do not create an artifact merely because discussion occurred. Prefer an existing
|
|
|
42
42
|
|
|
43
43
|
## Preserve Through Track Work
|
|
44
44
|
|
|
45
|
-
Discuss owns exploration and meaning. [Track Work](../../track-work/SKILL.md) owns the Working Record and its lifecycle.
|
|
46
|
-
|
|
47
|
-
```text
|
|
48
|
-
Discuss
|
|
49
|
-
-> supported state worth preserving
|
|
50
|
-
-> Track Work performs one atomic update
|
|
51
|
-
-> Discuss confirms the preserved meaning
|
|
52
|
-
-> continue discussion or return to Workflow
|
|
53
|
-
```
|
|
45
|
+
Discuss Work owns exploration and meaning. [Track Work](../../track-work/SKILL.md) owns the Working Record and its lifecycle: preserve supported state in one atomic update through it, then confirm the preserved meaning.
|
|
54
46
|
|
|
55
47
|
A Working Record is appropriate when:
|
|
56
48
|
|
|
@@ -62,17 +54,17 @@ A Working Record is appropriate when:
|
|
|
62
54
|
|
|
63
55
|
Preserve only supported state that could affect later interpretation or action. Give each detailed fact one canonical owner. Track Work should store current meaning rather than append discussion chronology.
|
|
64
56
|
|
|
65
|
-
When the initial record need arises from discussion, preserve the state that justified the record in the first authorized atomic update. Do not create an empty shell and lose the decisions, proposals, or uncertainty that made continuity necessary.
|
|
57
|
+
When the initial record need arises from discussion, preserve the state that justified the record in the first authorized atomic update. Do not create an empty shell and lose the decisions, proposals, or uncertainty that made continuity necessary. Once a record exists, use it as working memory during the discussion, updating it at meaningful boundaries (accepted choices, open questions, options still considered, material the user supplies, the route as it emerges) as Track Work describes.
|
|
66
58
|
|
|
67
|
-
When a rough route is useful, preserve provisional Slices, the Checkpoints between them, and their actual dependencies without pretending the later implementation is settled. Keep the current
|
|
59
|
+
When a rough route is useful, preserve provisional Slices, the Checkpoints between them, and their actual dependencies without pretending the later implementation is settled. Keep the current Slice concrete and later work directional. Use the existing Current Context, Current Work, Future Work, and History fields; do not add a second phase or context-cycle ledger.
|
|
68
60
|
|
|
69
61
|
Preserve the agreed outcome, scope, and user-facing return condition when losing them could interrupt covered work or permit drift. Authorization to investigate or propose a design is not acceptance of its production consequences. When learning changes the approach, retain the question, strongest evidence and limits, remaining uncertainty, artifact disposition, and affected later work—not the prototype's construction history.
|
|
70
62
|
|
|
71
|
-
After preservation, return to
|
|
63
|
+
After preservation, return to the discussion unless the user chose another route. Record mutation does not transfer ownership or authorize execution.
|
|
72
64
|
|
|
73
65
|
## Carry Checkpoints On The Route
|
|
74
66
|
|
|
75
|
-
A commit, publication, review, user decision, or planned handoff that the discussion anticipates is a Checkpoint on the route, not a Slice. With a record, propose it in Future Work using Track Work's Checkpoint types and states: `proposed` while only anticipated, `pending` once
|
|
67
|
+
A commit, publication, review, user decision, or planned handoff that the discussion anticipates is a Checkpoint on the route, not a Slice. With a record, propose it in Future Work using Track Work's Checkpoint types and states: `proposed` while only anticipated, `pending` once the user selects it. Without a record, keep it in the conversation.
|
|
76
68
|
|
|
77
69
|
Keep local commit authority separate from push or publication, and keep migration, release, and launch separately controlled.
|
|
78
70
|
|
|
@@ -91,17 +83,8 @@ Authority or user decision needed:
|
|
|
91
83
|
|
|
92
84
|
Do not restart from zero, rewrite unaffected decisions, or narrate completed work.
|
|
93
85
|
|
|
94
|
-
After context loss, recover
|
|
86
|
+
After context loss, recover the record as Track Work's "Recover After Context Loss" says before relying on it. Compare current sections and relevant History with current user direction, accepted artifacts, and live evidence. Reconcile affected meaning and dependent future work; do not repeat a disproved approach or preserve a stale plan merely because the record contains it. With intact context, use `resume` or targeted reads only when needed.
|
|
95
87
|
|
|
96
88
|
## Stop
|
|
97
89
|
|
|
98
90
|
Stop preserving when the current meaning and one next useful action can be reconstructed safely.
|
|
99
|
-
|
|
100
|
-
Do not turn continuity into:
|
|
101
|
-
|
|
102
|
-
- a transcript;
|
|
103
|
-
- a mandatory artifact;
|
|
104
|
-
- a second source of authority;
|
|
105
|
-
- a frozen architecture;
|
|
106
|
-
- an automatic checkpoint;
|
|
107
|
-
- a reason to begin execution.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Learning Action
|
|
2
|
+
|
|
3
|
+
Read this when existing evidence cannot settle a material question and running something could: before proposing an experiment or prototype, while running one, and when its evidence comes back.
|
|
4
|
+
|
|
5
|
+
This reference is judgment: adapt it to the question. Its binding statements restate [Discuss Work](../SKILL.md) or [Execute Work](../../execute-work/SKILL.md) Rules.
|
|
6
|
+
|
|
7
|
+
## Decide Whether To Run One
|
|
8
|
+
|
|
9
|
+
Use an experiment or prototype when existing evidence cannot settle a material question and exercising behavior can distinguish the remaining answers. A separate prototype should isolate the uncertainty more safely or economically than changing production; unfamiliarity alone does not require one.
|
|
10
|
+
|
|
11
|
+
If the work is an accepted useful outcome regardless of what it teaches, treat it as delivery work, not an experiment; do not disguise implementation as learning. Incidental learning does not change its authority or acceptance boundary.
|
|
12
|
+
|
|
13
|
+
## Frame It
|
|
14
|
+
|
|
15
|
+
Frame the action before proposing it:
|
|
16
|
+
|
|
17
|
+
- the question and its consequence for the accepted outcome or approach;
|
|
18
|
+
- plausible answers and the observation that would distinguish them;
|
|
19
|
+
- the smallest adequate prototype or observer;
|
|
20
|
+
- permitted effects, environment, and production exclusion;
|
|
21
|
+
- expected evidence and return conditions: question answered, observing limit reached, or further work requiring a different question or expanded scope;
|
|
22
|
+
- what would justify discarding, revising, or proposing promotion.
|
|
23
|
+
|
|
24
|
+
Add a time or cost boundary when repetition or setup could grow; do not demand an exact token prediction. If no adequate observer is available within scope, state the limitation rather than inventing a proof.
|
|
25
|
+
|
|
26
|
+
Check that the agreement covers the framed action, preserve it through [Track Work](../../track-work/SKILL.md) when needed, then run it through Execute Work. Existing authority may already cover the experiment; its name does not create another approval gate.
|
|
27
|
+
|
|
28
|
+
## Run It
|
|
29
|
+
|
|
30
|
+
Answer the one declared question with the least building that can, within the limits the framing set. Report a negative or inconclusive result as plainly as a positive one, and do not polish a prototype toward a favorable answer. A successful demonstration is not production acceptance: never promote exploratory code into production unless that promotion is deliberately selected and its effects authorized.
|
|
31
|
+
|
|
32
|
+
## Assess What It Showed
|
|
33
|
+
|
|
34
|
+
Assess returned evidence against the original question. Negative or inconclusive evidence is a valid result; one failed technique does not prove every alternative impossible. When it reports a new prerequisite, tell a limitation of the observer or chosen approach from a requirement of the intended outcome before recommending more work.
|
|
35
|
+
|
|
36
|
+
Revise only the affected understanding. When continuity matters, preserve the consequence for the task, the remaining uncertainty, and what happens to the exploratory artifacts, as [discussion continuity](discussion-continuity.md) describes. Stop assessing when the supported next direction or the unresolved decision is clear.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Checks and renders Discuss Work's decision list (SKILL.md, "Build The Decision List"), so its format is a tool's job
|
|
3
|
+
// and the agent's attention stays on the choices:
|
|
4
|
+
// validate IDs, states, T -> P links, a default on every plain item, the user's words on agreed items, a reason on
|
|
5
|
+
// changed ones;
|
|
6
|
+
// agreement the reply sent before building: What I'll do / Where I stop / Your decisions / Technical: N;
|
|
7
|
+
// handover the items the hand-over shows: new, changed and default;
|
|
8
|
+
// catch-up after an unattended run: defaults taken, choices waiting, changes, and what ran, from the Working
|
|
9
|
+
// Record's current Slice Material updates (read through Track Work's `working-record.mjs view resume`).
|
|
10
|
+
// Usage: choices.mjs <validate|agreement|handover|catch-up> (--list <file|-> | --record <record.md>)
|
|
11
|
+
// [--do <outcome> --stop <where you stop>] [--show-technical] [--json]
|
|
12
|
+
// --list reads a file or stdin (no Working Record: the list lives in the conversation); --record reads the task's
|
|
13
|
+
// sources/decisions.md beside the record. Each item is one line, "- P1 [state] choice -> default ..." (a technical
|
|
14
|
+
// item "-> serves P1"); other lines are ignored. Every view validates first. Exit code 0 when the list is valid
|
|
15
|
+
// (warnings do not fail it), 1 when it has errors, 2 on a usage error.
|
|
16
|
+
import { spawnSync } from "node:child_process";
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
18
|
+
import { dirname, join, resolve } from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
import { parseArgs } from "node:util";
|
|
21
|
+
import { parseChoices, renderChoices } from "./lib/choices.mjs";
|
|
22
|
+
|
|
23
|
+
const USAGE = [
|
|
24
|
+
"Usage: choices.mjs <validate|agreement|handover|catch-up> (--list <file|-> | --record <record.md>)",
|
|
25
|
+
" [--do <outcome> --stop <where you stop>] [--show-technical] [--json]",
|
|
26
|
+
].join("\n");
|
|
27
|
+
const VIEWS = new Set(["validate", "agreement", "handover", "catch-up"]);
|
|
28
|
+
const WORKING_RECORD = resolve(dirname(fileURLToPath(import.meta.url)), "../../track-work/scripts/working-record.mjs");
|
|
29
|
+
|
|
30
|
+
function fail(message) {
|
|
31
|
+
console.error(message);
|
|
32
|
+
process.exit(2);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let parsed;
|
|
36
|
+
try {
|
|
37
|
+
parsed = parseArgs({
|
|
38
|
+
allowPositionals: true,
|
|
39
|
+
options: {
|
|
40
|
+
list: { type: "string" },
|
|
41
|
+
record: { type: "string" },
|
|
42
|
+
do: { type: "string" },
|
|
43
|
+
stop: { type: "string" },
|
|
44
|
+
"show-technical": { type: "boolean", default: false },
|
|
45
|
+
json: { type: "boolean", default: false },
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
} catch (error) {
|
|
49
|
+
fail(`${error.message}\n${USAGE}`);
|
|
50
|
+
}
|
|
51
|
+
const { values, positionals } = parsed;
|
|
52
|
+
const [view] = positionals;
|
|
53
|
+
if (!VIEWS.has(view) || positionals.length !== 1) fail(USAGE);
|
|
54
|
+
if (Boolean(values.list) === Boolean(values.record)) fail(`give --list <file|-> or --record <record.md>\n${USAGE}`);
|
|
55
|
+
if (view === "agreement" && (!values.do || !values.stop)) fail(`agreement needs --do and --stop\n${USAGE}`);
|
|
56
|
+
|
|
57
|
+
let listText;
|
|
58
|
+
let recordView = null;
|
|
59
|
+
if (values.record) {
|
|
60
|
+
const record = resolve(values.record);
|
|
61
|
+
if (!existsSync(record)) fail(`no such record: ${values.record}`);
|
|
62
|
+
const listPath = join(dirname(record), "sources", "decisions.md");
|
|
63
|
+
if (!existsSync(listPath)) fail(`no decision list at ${listPath}; Track Work keeps it there`);
|
|
64
|
+
listText = readFileSync(listPath, "utf8");
|
|
65
|
+
if (view === "catch-up") {
|
|
66
|
+
const run = spawnSync(process.execPath, [WORKING_RECORD, "view", "resume", "--record", record], {
|
|
67
|
+
encoding: "utf8",
|
|
68
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
69
|
+
});
|
|
70
|
+
if (run.status !== 0) fail(`working-record.mjs view resume failed: ${(run.stderr || run.stdout).trim()}`);
|
|
71
|
+
recordView = run.stdout;
|
|
72
|
+
}
|
|
73
|
+
} else if (values.list === "-") listText = readFileSync(0, "utf8");
|
|
74
|
+
else if (!existsSync(resolve(values.list))) fail(`no such list: ${values.list}`);
|
|
75
|
+
else listText = readFileSync(resolve(values.list), "utf8");
|
|
76
|
+
|
|
77
|
+
const list = parseChoices(listText);
|
|
78
|
+
const notes = [...list.errors.map((each) => `error: ${each}`), ...list.warnings.map((each) => `warning: ${each}`)];
|
|
79
|
+
if (!list.ok) {
|
|
80
|
+
if (values.json)
|
|
81
|
+
console.log(
|
|
82
|
+
JSON.stringify({ command: `choices ${view}`, ok: false, errors: list.errors, warnings: list.warnings }, null, 2),
|
|
83
|
+
);
|
|
84
|
+
else console.log(`Decision list has ${list.errors.length} error(s):\n${notes.map((each) => `- ${each}`).join("\n")}`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
const rendered = renderChoices(view, list, {
|
|
88
|
+
outcome: values.do,
|
|
89
|
+
stop: values.stop,
|
|
90
|
+
showTechnical: values["show-technical"],
|
|
91
|
+
recordText: recordView,
|
|
92
|
+
});
|
|
93
|
+
if (values.json)
|
|
94
|
+
console.log(
|
|
95
|
+
JSON.stringify(
|
|
96
|
+
{ command: `choices ${view}`, ok: true, warnings: list.warnings, ...rendered.data, text: rendered.text },
|
|
97
|
+
null,
|
|
98
|
+
2,
|
|
99
|
+
),
|
|
100
|
+
);
|
|
101
|
+
else console.log(`${notes.length ? `${notes.map((each) => `- ${each}`).join("\n")}\n\n` : ""}${rendered.text}`);
|