@event4u/agent-config 14.18.0 → 14.20.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +120 -129
- package/README.md +71 -149
- package/dist/agent-src/README.md +1 -1
- package/dist/agent-src/commands/agent-handoff.md +44 -43
- package/dist/agent-src/commands/review/changes.md +19 -19
- package/dist/agent-src/commands/review.md +2 -2
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +37 -4
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +2 -2
- package/dist/agent-src/rules/guidelines.md +1 -1
- package/dist/agent-src/rules/session-canary.md +2 -2
- package/dist/agent-src/rules/token-efficiency.md +1 -1
- package/dist/agent-src/rules/untrusted-input-defense.md +0 -2
- package/dist/agent-src/skills/adversarial-review/SKILL.md +0 -8
- package/dist/agent-src/skills/canvas-design/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/data/app-interface.csv +1 -1
- package/dist/agent-src/skills/design-intelligence/data/motion.csv +17 -17
- package/dist/agent-src/skills/design-intelligence/data/ux-guidelines.csv +2 -2
- package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +17 -0
- package/dist/agent-src/skills/design-intelligence/references/design-rules-checklist.md +4 -4
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/design-variations/SKILL.md +1 -1
- package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/fe-design/SKILL.md +32 -5
- package/dist/agent-src/skills/fe-design/references/craft-floor.md +7 -0
- package/dist/agent-src/skills/fe-design/references/design-patterns.md +47 -2
- package/dist/agent-src/skills/laravel-scheduling/SKILL.md +3 -1
- package/dist/agent-src/skills/markitdown/SKILL.md +1 -1
- package/dist/agent-src/skills/project-analyzer/SKILL.md +0 -6
- package/dist/agent-src/skills/react-native-setup/SKILL.md +3 -3
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/sequential-thinking/SKILL.md +18 -8
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +28 -6
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -3
- package/dist/agent-src/skills/ui-apply-generic/SKILL.md +1 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +1 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +17 -2
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +14 -1
- package/dist/agent-src/templates/scripts/telemetry/mcp_lite.ts +213 -0
- package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +16 -0
- package/dist/agent-src/templates/scripts/telemetry_report.ts +22 -2
- package/dist/cli/commands/recordTriggerEval.js +2 -2
- package/dist/cli/main.js +1 -1
- package/dist/cli/mcp/dispatch.js +10 -0
- package/dist/cli/mcp/stdio.js +33 -2
- package/dist/cli/mcp/telemetry.js +227 -0
- package/dist/cli-delegate/{chunk-AKJGUQNO.js → chunk-C6IPZRDA.js} +484 -353
- package/dist/cli-delegate/{chunk-CYH5SP6M.js → chunk-I6RHFQEG.js} +151 -16
- package/dist/cli-delegate/{chunk-7RXIKF62.js → chunk-NUMQHLS5.js} +304 -136
- package/dist/cli-delegate/{chunk-PMEKGDED.js → chunk-PI2GU3DP.js} +163 -1
- package/dist/cli-delegate/{chunk-7PRE6ZV2.js → chunk-YS6XTLEK.js} +199 -4
- package/dist/cli-delegate/chunk-ZVBOHSVF.js +1109 -0
- package/dist/cli-delegate/cmd_adr_effective.js +318 -81
- package/dist/cli-delegate/cmd_conformance.js +489 -121
- package/dist/cli-delegate/cmd_doctor.js +2 -2
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +42 -12
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_session_recycle.js +59 -902
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +34 -33
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +4455 -3025
- package/dist/install/install.mjs +975 -689
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +2087 -1134
- package/dist/scripts/_lib/model_tier.js +1 -1
- package/dist/scripts/mcp_server/telemetry.js +148 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/naming.md +1 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/security-lint-containment.md +46 -6
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +4 -4
- package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +1 -1
- package/docs/guidelines/design-antipatterns.md +87 -64
- package/docs/guidelines/redundancy-taxonomy.md +28 -0
- package/package.json +1 -1
- package/src/agent-src/README.md +1 -1
- package/src/agent-src/templates/scripts/telemetry/mcp_lite.ts +213 -0
- package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +16 -0
- package/src/agent-src/templates/scripts/telemetry_report.ts +22 -2
- package/src/config/assurance-capability-registry.json +9 -0
- package/src/config/ci-local-parity.yml +6 -0
- package/src/config/gate-coverage.yml +225 -0
- package/src/config/gate-violation-baselines.json +18 -6
- package/src/config/release-gate-locality.yml +12 -0
- package/src/scripts/_cli/cmd_doctor.ts +2 -2
- package/src/scripts/_cli/cmd_handoff.ts +1 -1
- package/src/scripts/_cli/cmd_session_recycle.ts +51 -3
- package/src/scripts/_cli/cmd_update.ts +1 -1
- package/src/scripts/_cli/cmd_versions.ts +1 -1
- package/src/scripts/_lib/adr_frontmatter.ts +44 -0
- package/src/scripts/_lib/audit_field_provenance.ts +44 -3
- package/src/scripts/_lib/consequence_objects.ts +152 -0
- package/src/scripts/_lib/exec_evidence.ts +7 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +2 -2
- package/src/scripts/_lib/host_capability.ts +38 -0
- package/src/scripts/_lib/host_permission_checks.ts +251 -0
- package/src/scripts/_lib/install_reach_checks.ts +33 -1
- package/src/scripts/_lib/mcp_bridge.ts +222 -10
- package/src/scripts/_lib/mcp_consent_residual.ts +173 -0
- package/src/scripts/_lib/model_tier.ts +1 -1
- package/src/scripts/_lib/obligation_frequency.ts +2 -2
- package/src/scripts/_lib/orchestration_record.ts +23 -1
- package/src/scripts/_lib/recycle_envelope_paths.ts +190 -0
- package/src/scripts/_lib/release_highlights.ts +93 -0
- package/src/scripts/_lib/release_material.ts +64 -1
- package/src/scripts/_lib/release_position.ts +96 -0
- package/src/scripts/_lib/review_skipped_record.ts +17 -1
- package/src/scripts/_lib/runtime_journal.ts +26 -3
- package/src/scripts/_lib/runtime_wiring_checks.ts +12 -1
- package/src/scripts/_lib/security_lint.ts +179 -7
- package/src/scripts/_lib/self_repair.ts +141 -6
- package/src/scripts/_lib/self_repair_store.ts +273 -7
- package/src/scripts/_lib/session_register.ts +11 -6
- package/src/scripts/_lib/sqlite_schema.ts +22 -0
- package/src/scripts/_lib/subagent_capsule.ts +155 -3
- package/src/scripts/_lib/surface.ts +86 -0
- package/src/scripts/_lib/ui_authority.ts +116 -0
- package/src/scripts/adr/regenerate_index.ts +54 -1
- package/src/scripts/adr_cite_check.ts +71 -15
- package/src/scripts/ai_council/clients.ts +1 -1
- package/src/scripts/autonomy_friction_corpus.ts +229 -0
- package/src/scripts/build_proof.ts +15 -2
- package/src/scripts/build_rule_trigger_matrix.ts +5 -0
- package/src/scripts/check_beta_review_markers.ts +141 -17
- package/src/scripts/check_enforcement_coverage.ts +1 -1
- package/src/scripts/check_enforcement_denominator.ts +121 -11
- package/src/scripts/check_finding_dispositions.ts +66 -9
- package/src/scripts/check_gate_coverage.ts +96 -0
- package/src/scripts/check_mcp_doc_drift.ts +217 -0
- package/src/scripts/check_pack_size.ts +321 -3
- package/src/scripts/check_release_highlights.ts +74 -1
- package/src/scripts/check_skill_activation_claim.ts +179 -0
- package/src/scripts/check_trigger_evals.ts +1 -1
- package/src/scripts/conformance_scan.ts +44 -3
- package/src/scripts/explain_run.ts +1 -1
- package/src/scripts/generate_capability_matrix.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +75 -1
- package/src/scripts/handoff_context_hook.ts +54 -7
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +14 -11
- package/src/scripts/hooks/augment-dispatcher.sh +1 -1
- package/src/scripts/hooks/category_a.ts +291 -0
- package/src/scripts/hooks/cline-dispatcher.sh +1 -1
- package/src/scripts/hooks/cursor-dispatcher.sh +11 -5
- package/src/scripts/hooks/dispatch_hook.ts +17 -22
- package/src/scripts/hooks/git_command_classifier.ts +156 -1
- package/src/scripts/hooks/host_lowering.ts +215 -0
- package/src/scripts/hooks/host_lowering.yaml +185 -0
- package/src/scripts/hooks/host_semantics.ts +105 -37
- package/src/scripts/hooks/journal_record_hook.ts +10 -0
- package/src/scripts/hooks/permission_gate.ts +117 -0
- package/src/scripts/hooks/session_eol_hook.ts +18 -7
- package/src/scripts/hooks_status.ts +12 -10
- package/src/scripts/install.ts +57 -86
- package/src/scripts/install_anthropic_key.sh +2 -2
- package/src/scripts/lint_agent_security.ts +316 -25
- package/src/scripts/lint_confusables.ts +42 -6
- package/src/scripts/lint_design_antipattern_parity.ts +80 -0
- package/src/scripts/lint_evidence_artifacts.ts +45 -1
- package/src/scripts/lint_handoffs.ts +0 -132
- package/src/scripts/lint_hidden_unicode.ts +49 -7
- package/src/scripts/lint_hook_manifest.ts +87 -3
- package/src/scripts/lint_instruction_smuggling.ts +42 -6
- package/src/scripts/lint_mcp_config_security.ts +42 -6
- package/src/scripts/lint_motion_authority_drift.ts +731 -0
- package/src/scripts/lint_readme_size.ts +158 -12
- package/src/scripts/lint_reasoning_fixtures.ts +216 -0
- package/src/scripts/lint_roadmap_later_disposition.ts +217 -27
- package/src/scripts/lint_skill_frontmatter_safety.ts +43 -7
- package/src/scripts/lint_skill_trigger_contradiction.ts +161 -0
- package/src/scripts/mcp_server/resources.ts +41 -0
- package/src/scripts/mcp_server/telemetry.ts +19 -4
- package/src/scripts/measure_sibling_naming.ts +150 -0
- package/src/scripts/orchestration_record.ts +12 -1
- package/src/scripts/redact_hook_capture.ts +1 -1
- package/src/scripts/release.ts +24 -24
- package/src/scripts/release_publication.ts +6 -2
- package/src/scripts/report_skill_activation.ts +319 -7
- package/src/scripts/schemas/review-findings.schema.json +5 -0
- package/src/scripts/schemas/skill.schema.json +2 -2
- package/src/scripts/self_repair_cli.ts +31 -1
- package/src/scripts/session_canary_hook.ts +1 -1
- package/src/scripts/session_register_hook.ts +4 -3
- package/src/scripts/skill_scout.ts +69 -0
- package/src/scripts/trigger_eval_grandfather.json +5 -1
- package/src/scripts/validate_agent_settings.ts +1 -1
- package/dist/cli-delegate/chunk-2GNWGMAL.js +0 -172
- package/dist/cli-delegate/chunk-LPPWO5CE.js +0 -161
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
// Per `agents/roadmaps/archive/road-to-mcp-full-coverage.md` §Phase 1 J4 +
|
|
4
4
|
// `docs/contracts/mcp-tool-stub-envelope.md`, both transports log every
|
|
5
5
|
// `tools/call` with `{tool_name, client_id_hash, ts, transport,
|
|
6
|
-
// outcome}`.
|
|
6
|
+
// outcome}`. The stdio-lite surface (`src/cli/mcp/`) appends a sixth,
|
|
7
|
+
// optional `host` field; callers that do not know their client omit it and
|
|
8
|
+
// their records stay byte-identical to the frozen five-field envelope. Payload bodies are never logged; the client identifier is
|
|
7
9
|
// hashed at the server boundary so the queryable store never sees raw
|
|
8
10
|
// identity.
|
|
9
11
|
//
|
|
@@ -107,15 +109,26 @@ export function build_record(options: {
|
|
|
107
109
|
transport: string;
|
|
108
110
|
client_id_hash_value?: string | null | undefined;
|
|
109
111
|
ts?: string | null | undefined;
|
|
112
|
+
host?: string | null | undefined;
|
|
110
113
|
}): Record<string, unknown> {
|
|
111
|
-
const { tool_name, outcome, transport, client_id_hash_value, ts } = options;
|
|
112
|
-
|
|
114
|
+
const { tool_name, outcome, transport, client_id_hash_value, ts, host } = options;
|
|
115
|
+
const record: Record<string, unknown> = {
|
|
113
116
|
tool_name,
|
|
114
117
|
client_id_hash: client_id_hash_value || hash_client_id(),
|
|
115
118
|
ts: ts || _now_iso(),
|
|
116
119
|
transport,
|
|
117
120
|
outcome,
|
|
118
121
|
};
|
|
122
|
+
// `host` is APPENDED, and only when a caller supplies one, so a record
|
|
123
|
+
// written by a caller that does not know its client stays byte-identical
|
|
124
|
+
// to the five-field envelope the stub contract froze. It is a closed
|
|
125
|
+
// vocabulary resolved at the boundary (see `src/cli/mcp/telemetry.ts`),
|
|
126
|
+
// never a free-form string: a record type that cannot hold arbitrary text
|
|
127
|
+
// has no scrubber to fail.
|
|
128
|
+
if (typeof host === 'string' && host !== '') {
|
|
129
|
+
record.host = host;
|
|
130
|
+
}
|
|
131
|
+
return record;
|
|
119
132
|
}
|
|
120
133
|
|
|
121
134
|
/**
|
|
@@ -132,13 +145,15 @@ export function record_call(options: {
|
|
|
132
145
|
transport: string;
|
|
133
146
|
consumer_root?: string | null | undefined;
|
|
134
147
|
client_id_hash_value?: string | null | undefined;
|
|
148
|
+
host?: string | null | undefined;
|
|
135
149
|
}): Record<string, unknown> | null {
|
|
136
|
-
const { tool_name, outcome, transport, consumer_root, client_id_hash_value } = options;
|
|
150
|
+
const { tool_name, outcome, transport, consumer_root, client_id_hash_value, host } = options;
|
|
137
151
|
const record = build_record({
|
|
138
152
|
tool_name,
|
|
139
153
|
outcome,
|
|
140
154
|
transport,
|
|
141
155
|
client_id_hash_value,
|
|
156
|
+
host,
|
|
142
157
|
});
|
|
143
158
|
const target = _resolve_log_path(consumer_root ?? undefined);
|
|
144
159
|
try {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* measure_sibling_naming — how many skill descriptions name another skill.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-one-motion-authority` step 5.2. An inbox census claimed "44/299
|
|
5
|
+
* descriptions name a sibling" and shipped no definition of *naming* and no
|
|
6
|
+
* script, so the figure could be neither reproduced nor refuted. A companion
|
|
7
|
+
* claim of "218/299 bodies" reproduced under no reading of the tree at all.
|
|
8
|
+
* This script exists so the next such number is falsifiable.
|
|
9
|
+
*
|
|
10
|
+
* WHAT "NAMES A SIBLING" MEANS HERE, stated because the census did not.
|
|
11
|
+
*
|
|
12
|
+
* A description names a sibling when it contains the exact `name:` value of a
|
|
13
|
+
* DIFFERENT shipped skill, delimited so it is not a fragment of a longer
|
|
14
|
+
* identifier. `\b` is not enough: it puts a boundary between `brand` and the
|
|
15
|
+
* hyphen in `brand-identity`, so a bare `\b`-matched `brand` would score every
|
|
16
|
+
* mention of `brand-identity` as naming `brand` too. The delimiter here is
|
|
17
|
+
* "not `[A-Za-z0-9-]`" on both sides, which is the smallest rule that keeps
|
|
18
|
+
* `mcp` out of `mcp-builder` and `laravel` out of `laravel-dto`.
|
|
19
|
+
*
|
|
20
|
+
* A skill naming ITSELF does not count — that is a description, not a pointer.
|
|
21
|
+
*
|
|
22
|
+
* WHAT THE NUMBER IS AND IS NOT.
|
|
23
|
+
*
|
|
24
|
+
* A KNOWN AND UNFIXABLE FALSE POSITIVE, named rather than left for a reader to
|
|
25
|
+
* find: some skill names are ordinary English words, so a description can score
|
|
26
|
+
* a match by accident. `canvas-design` scores `brand` on the phrase "brand
|
|
27
|
+
* assets", which is not a pointer to the `brand` skill. Excluding short or
|
|
28
|
+
* common names would trade this for a false negative on the skills whose names
|
|
29
|
+
* really are those words, and there is no rule that gets both. The count is
|
|
30
|
+
* therefore an upper bound; the per-skill list is printed so a reader can see
|
|
31
|
+
* which matches are real.
|
|
32
|
+
*
|
|
33
|
+
* It is a count of descriptions that mention a sibling by name. It is NOT a
|
|
34
|
+
* measure of routing quality: a description can name a sibling uselessly, and a
|
|
35
|
+
* description that names none can be perfectly routable on its own keywords.
|
|
36
|
+
* The reason the count is worth having is narrower — the router reads
|
|
37
|
+
* descriptions and nothing else, so a family whose members never point at each
|
|
38
|
+
* other is a family the router cannot traverse.
|
|
39
|
+
*
|
|
40
|
+
* Exit code is 0 unless `--min <n>` is given and the count falls below it.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
import fs from 'node:fs';
|
|
44
|
+
import path from 'node:path';
|
|
45
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
46
|
+
|
|
47
|
+
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
48
|
+
const REPO_ROOT = path.resolve(HERE, '..', '..');
|
|
49
|
+
const SKILLS_REL = path.join('src', 'skills');
|
|
50
|
+
|
|
51
|
+
export interface SkillRecord { name: string; description: string }
|
|
52
|
+
|
|
53
|
+
/** Read `name:` and `description:` out of a SKILL.md frontmatter block. */
|
|
54
|
+
export function parseSkill(text: string): SkillRecord | null {
|
|
55
|
+
if (!text.startsWith('---')) return null;
|
|
56
|
+
const end = text.indexOf('\n---', 3);
|
|
57
|
+
if (end < 0) return null;
|
|
58
|
+
const fm = text.slice(3, end);
|
|
59
|
+
const name = /^name:\s*(.+)$/m.exec(fm)?.[1]?.trim() ?? '';
|
|
60
|
+
let description = /^description:\s*(.+)$/m.exec(fm)?.[1]?.trim() ?? '';
|
|
61
|
+
if ((description.startsWith('"') && description.endsWith('"'))
|
|
62
|
+
|| (description.startsWith("'") && description.endsWith("'"))) {
|
|
63
|
+
description = description.slice(1, -1);
|
|
64
|
+
}
|
|
65
|
+
description = description.replace(/\\"/g, '"');
|
|
66
|
+
if (name === '') return null;
|
|
67
|
+
return { name, description };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function loadSkills(root: string): SkillRecord[] {
|
|
71
|
+
const dir = path.join(root, SKILLS_REL);
|
|
72
|
+
if (!fs.existsSync(dir)) return [];
|
|
73
|
+
const out: SkillRecord[] = [];
|
|
74
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
75
|
+
if (!entry.isDirectory()) continue;
|
|
76
|
+
const file = path.join(dir, entry.name, 'SKILL.md');
|
|
77
|
+
if (!fs.existsSync(file)) continue;
|
|
78
|
+
const rec = parseSkill(fs.readFileSync(file, 'utf-8'));
|
|
79
|
+
if (rec !== null) out.push(rec);
|
|
80
|
+
}
|
|
81
|
+
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Identifier-boundary containment: `mcp` is not found inside `mcp-builder`. */
|
|
85
|
+
export function namesIdentifier(haystack: string, id: string): boolean {
|
|
86
|
+
let from = 0;
|
|
87
|
+
for (;;) {
|
|
88
|
+
const i = haystack.indexOf(id, from);
|
|
89
|
+
if (i < 0) return false;
|
|
90
|
+
const before = i === 0 ? '' : haystack[i - 1] ?? '';
|
|
91
|
+
const after = haystack[i + id.length] ?? '';
|
|
92
|
+
const isPart = (c: string): boolean => c !== '' && /[A-Za-z0-9-]/.test(c);
|
|
93
|
+
if (!isPart(before) && !isPart(after)) return true;
|
|
94
|
+
from = i + 1;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** For each skill, the OTHER skills its description names. Sorted, deterministic. */
|
|
99
|
+
export function siblingsNamed(skills: readonly SkillRecord[]): Map<string, string[]> {
|
|
100
|
+
const names = skills.map((s) => s.name);
|
|
101
|
+
const out = new Map<string, string[]>();
|
|
102
|
+
for (const s of skills) {
|
|
103
|
+
const hits = names
|
|
104
|
+
.filter((n) => n !== s.name && namesIdentifier(s.description, n))
|
|
105
|
+
.sort();
|
|
106
|
+
out.set(s.name, hits);
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
112
|
+
const rootFlag = argv.indexOf('--root');
|
|
113
|
+
const root = rootFlag >= 0 ? (argv[rootFlag + 1] ?? REPO_ROOT) : REPO_ROOT;
|
|
114
|
+
const minFlag = argv.indexOf('--min');
|
|
115
|
+
const min = minFlag >= 0 ? Number(argv[minFlag + 1]) : null;
|
|
116
|
+
const json = argv.includes('--json');
|
|
117
|
+
|
|
118
|
+
const skills = loadSkills(root);
|
|
119
|
+
const map = siblingsNamed(skills);
|
|
120
|
+
const naming = [...map].filter(([, v]) => v.length > 0);
|
|
121
|
+
|
|
122
|
+
if (json) {
|
|
123
|
+
process.stdout.write(`${JSON.stringify({
|
|
124
|
+
total: skills.length,
|
|
125
|
+
naming: naming.length,
|
|
126
|
+
entries: Object.fromEntries(naming),
|
|
127
|
+
}, null, 1)}\n`);
|
|
128
|
+
} else {
|
|
129
|
+
process.stdout.write(`scanned: ${String(skills.length)}\n`);
|
|
130
|
+
process.stdout.write(
|
|
131
|
+
`sibling-naming: ${String(naming.length)}/${String(skills.length)} description(s) name at least one other shipped skill\n\n`,
|
|
132
|
+
);
|
|
133
|
+
for (const [name, hits] of naming) {
|
|
134
|
+
process.stdout.write(` ${name} → ${hits.join(', ')}\n`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (min !== null && Number.isFinite(min) && naming.length < min) {
|
|
139
|
+
process.stderr.write(
|
|
140
|
+
`\n❌ measure_sibling_naming: ${String(naming.length)} below the declared floor of ${String(min)}\n`,
|
|
141
|
+
);
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (process.argv[1] !== undefined) {
|
|
148
|
+
const invoked = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
149
|
+
if (invoked === import.meta.url) process.exitCode = main();
|
|
150
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* ./scripts-run src/scripts/orchestration_record \
|
|
11
11
|
* --spawn-count 1 --token-delta -72000 --provenance measured \
|
|
12
12
|
* --tier-chosen lite --tier-source inferred --task-class read-only-fanout \
|
|
13
|
-
* [--tiers sonnet,opus] [--agent-combo implementer,judge] [--wall-clock-ms 18500] [--dispatch-outcome DONE] \
|
|
13
|
+
* [--rules-applied a,b] [--tiers sonnet,opus] [--agent-combo implementer,judge] [--wall-clock-ms 18500] [--dispatch-outcome DONE] \
|
|
14
14
|
* [--first-pass-success true|false] [--escalated true|false] \
|
|
15
15
|
* [--init-tokens 1200] [--payload-hash <hex8-64>] [--lookup-class definition|references|string-existence|report-run] \
|
|
16
16
|
* [--route-taken primitive|subagent|ask] [--budget-hit true|false] [--correctness-match true|false] \
|
|
@@ -141,6 +141,17 @@ export function main(argv: string[] = process.argv.slice(2)): number {
|
|
|
141
141
|
if (raw === undefined) return undefined;
|
|
142
142
|
return raw.split(',').map((v) => v.trim()).filter(Boolean);
|
|
143
143
|
})(),
|
|
144
|
+
// `--rules-applied=a,b` records the rules the run actually carried.
|
|
145
|
+
// Unlike `--skills-applied`, an OMITTED flag and an empty value mean
|
|
146
|
+
// the same thing here: audit-log-v1 makes `rules_applied` mandatory on
|
|
147
|
+
// every line, so `[]` is how "nothing observed" is spelled, and there
|
|
148
|
+
// is no absent-key slot to distinguish it from. What this flag replaced
|
|
149
|
+
// is the fabricated `['delegation-policy']` this producer wrote on
|
|
150
|
+
// every line until 2026-09-07.
|
|
151
|
+
rules_applied: str(flags, 'rules-applied')
|
|
152
|
+
?.split(',')
|
|
153
|
+
.map((v) => v.trim())
|
|
154
|
+
.filter(Boolean),
|
|
144
155
|
task_size_estimate: int(flags, 'task-size-estimate'),
|
|
145
156
|
wall_clock_ms: int(flags, 'wall-clock-ms'),
|
|
146
157
|
dispatch_tokens: int(flags, 'dispatch-tokens'),
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Ported from the retired Python `redact_hook_capture.py` (Phase 8 / Wave 8g).
|
|
6
6
|
*
|
|
7
|
-
* Reads JSON capture files written by `dispatch_hook.
|
|
7
|
+
* Reads JSON capture files written by `dispatch_hook.ts` (when
|
|
8
8
|
* `AGENT_HOOK_CAPTURE_DIR` is set) and produces a redacted version
|
|
9
9
|
* suitable for pasting into the verified-platforms roadmap.
|
|
10
10
|
*
|
package/src/scripts/release.ts
CHANGED
|
@@ -49,8 +49,10 @@
|
|
|
49
49
|
* Idempotency: pass `--resume` to recover from a partial failure. Each
|
|
50
50
|
* step then probes existing state (branch, commit, PR, tag, GitHub
|
|
51
51
|
* Release) and skips work that is already done, instead of erroring out.
|
|
52
|
-
*
|
|
53
|
-
*
|
|
52
|
+
* Re-running from `release/{target}` needs neither the flag nor a clean
|
|
53
|
+
* tree — that position, dirty, is the state `guard_release_curation` leaves
|
|
54
|
+
* behind, and `preflightPosition` accepts it (a dirty `main` still refuses).
|
|
55
|
+
* The
|
|
54
56
|
* two entry points guard against colliding with each other via these same
|
|
55
57
|
* probes plus the CI workflow's concurrency group — whichever starts
|
|
56
58
|
* second sees the other's in-progress state and skips or refuses cleanly.
|
|
@@ -124,6 +126,7 @@ import {
|
|
|
124
126
|
derive_category_hits,
|
|
125
127
|
render_derived_head_values,
|
|
126
128
|
} from './_lib/release_highlights.js';
|
|
129
|
+
import { preflightPosition } from './_lib/release_position.js';
|
|
127
130
|
import {
|
|
128
131
|
RELEASE_HEAD_DEFAULT,
|
|
129
132
|
extract_changelog_section,
|
|
@@ -784,17 +787,17 @@ export function assert_scheduled_deprecations_clear(
|
|
|
784
787
|
/**
|
|
785
788
|
* Fail fast on conditions that would break the release mid-flight.
|
|
786
789
|
*
|
|
787
|
-
*
|
|
790
|
+
* The start position — which branch, and whether a dirty tree is tolerated —
|
|
791
|
+
* is `preflightPosition` in `_lib/release_position.ts`, and it is NO LONGER
|
|
792
|
+
* gated on `--resume`:
|
|
793
|
+
* `release/{target}` is where `guard_release_curation` leaves the operator, so
|
|
794
|
+
* refusing it there made the guard's own remedy unreachable. Read that
|
|
795
|
+
* function's header for the measurement.
|
|
788
796
|
*
|
|
789
|
-
*
|
|
790
|
-
*
|
|
791
|
-
* you on the release branch).
|
|
792
|
-
* - The target-tag-exists check is dropped — execute() probes for existing
|
|
793
|
-
* tags/releases and skips them.
|
|
797
|
+
* `--resume` still relaxes ONE invariant here: the target-tag-exists check is
|
|
798
|
+
* dropped, because execute() probes for existing tags/releases and skips them.
|
|
794
799
|
*
|
|
795
|
-
*
|
|
796
|
-
* enforced, so resuming has the same starting posture as a fresh run; only
|
|
797
|
-
* step-level outcomes differ.
|
|
800
|
+
* gh auth and `main` in-sync with origin are enforced either way.
|
|
798
801
|
*
|
|
799
802
|
* `opts.ci` swaps the gh-auth probe (see below) for the CI-mode variant —
|
|
800
803
|
* everything else is identical between the two entry points.
|
|
@@ -832,20 +835,17 @@ function preflight(target: string, opts: { resume?: boolean; ci?: boolean } = {}
|
|
|
832
835
|
|
|
833
836
|
const branch = git(['rev-parse', '--abbrev-ref', 'HEAD'], { capture: true });
|
|
834
837
|
const release_branch = `release/${target}`;
|
|
835
|
-
const
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
}
|
|
843
|
-
die(`release must run from '${MAIN_BRANCH}', currently on '${branch}'`);
|
|
838
|
+
const position = preflightPosition({
|
|
839
|
+
branch,
|
|
840
|
+
mainBranch: MAIN_BRANCH,
|
|
841
|
+
releaseBranch: release_branch,
|
|
842
|
+
porcelain: git(['status', '--porcelain'], { capture: true }),
|
|
843
|
+
});
|
|
844
|
+
if (!position.proceed) {
|
|
845
|
+
die(position.message ?? `release cannot start from '${branch}'`);
|
|
844
846
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
if (porcelain) {
|
|
848
|
-
die('working tree is not clean; commit or stash first');
|
|
847
|
+
if (position.notice) {
|
|
848
|
+
process.stdout.write(`\u26a0\ufe0f ${position.notice}\n`);
|
|
849
849
|
}
|
|
850
850
|
|
|
851
851
|
// --force lets the remote's tag positions win over stale local tags.
|
|
@@ -731,8 +731,12 @@ export function guard_release_curation(version: string, prMerged = false): void
|
|
|
731
731
|
marked.join('\n')
|
|
732
732
|
: '') +
|
|
733
733
|
'\n Stopped BEFORE committing — no release commit, no branch on ' +
|
|
734
|
-
`${REMOTE}, no pull request, no tag.
|
|
735
|
-
|
|
734
|
+
`${REMOTE}, no pull request, no tag. HEAD is on the LOCAL ` +
|
|
735
|
+
`\`release/${version}\` branch and the generated section is in the working ` +
|
|
736
|
+
'tree: curate the `### Release highlights` head in `CHANGELOG.md` there, then ' +
|
|
737
|
+
're-run `task release`. That re-run works from this position — `preflightPosition` ' +
|
|
738
|
+
'accepts the release branch with the uncommitted step-2 output, which it did not ' +
|
|
739
|
+
'until 2026-09-07 (both spellings of the re-run were refused before step 1).',
|
|
736
740
|
);
|
|
737
741
|
}
|
|
738
742
|
|