dotnet-production-agent-skills 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -293,6 +293,20 @@ The CLI installs and manages guidance; it does not route prompts or load every s
293
293
 
294
294
  The initial policy blocks force-push, destructive Git reset/clean/branch deletion, broad recursive deletion, and direct access to common credential-bearing files. Safe commands continue normally. Host configuration is written to `.codex/hooks.json`, `.github/hooks/dotnet-production-agent-skills.json`, `.claude/settings.json`, `.cursor/hooks.json`, or `.agents/hooks.json` for Antigravity.
295
295
 
296
+ ### Reject co-author trailers with Git
297
+
298
+ After v0.3.3 is published, opt in from each repository:
299
+
300
+ ```sh
301
+ npx dotnet-production-agent-skills@0.3.3 git-hook
302
+ # Preview, or select another repository
303
+ npx dotnet-production-agent-skills@0.3.3 git-hook --project <path> --dry-run
304
+ ```
305
+
306
+ This installs an executable Git `commit-msg` hook that rejects case-insensitive `Co-authored-by:` lines in the final commit message, including `-m`, `-F`, template, and `--trailer` input. It rejects the commit without editing the message. Node.js must be available when Git runs. The installer respects Git's configured `core.hooksPath`, does not change Git configuration, and refuses to overwrite existing or modified hooks even with `--force`. For an existing hook manager, integrate the packaged `hooks/commit-msg` check manually. Skill install/update/uninstall does not manage this separately opted-in Git hook.
307
+
308
+ This local hook covers Git CLI commits from any agent or developer. It does not validate PR descriptions or GitHub/API-created commits, and `--no-verify` or disabling hooks can bypass it. Use a required server-side PR check to enforce the policy before merging API-created or bypassed commits. See [Git hook documentation](https://git-scm.com/docs/githooks#_commit_msg).
309
+
296
310
  Terminal recovery guidance keeps commands anchored to the intended repository, separates executable lookup from repository selection, and forbids moving into Git/tool installation directories as a workaround. Copilot project instructions include the critical rules so they are available even before the focused `safe-terminal` skill is selected. Skills and instructions guide the model; the existing hooks do not enforce these directory/recovery rules. See the skill's [shell recovery examples](skills/safe-terminal/references/shell-recovery.md) for diagnostics and primary sources.
297
311
 
298
312
  Copilot project installs manage only the text between `<!-- dotnet-production-agent-skills:start -->` and `<!-- dotnet-production-agent-skills:end -->`. Existing team instructions outside those markers remain intact. Uninstall removes only the managed section. User-scope Copilot installs install skills into `~/.copilot/skills`; repository instructions apply only to project scope.
@@ -318,6 +332,7 @@ Commands:
318
332
  list Display available skills and current installation status
319
333
  doctor Validate skill metadata and report host installation health
320
334
  uninstall Safely remove only skills tracked by this package
335
+ git-hook Opt in to a Git commit-msg hook in the current/--project repository
321
336
  ```
322
337
 
323
338
  ### Options & Flags
package/RELEASE_NOTES.md CHANGED
@@ -1,8 +1,30 @@
1
1
  # Release notes
2
2
 
3
+ ## v0.3.3 — Strict coding-agent authorship rules
4
+
5
+ Prepared for release after PR #13 is merged; not yet published to npm.
6
+
7
+ ### Improved
8
+
9
+ - Add an opt-in `git-hook` CLI command that installs a Git `commit-msg` hook rejecting case-insensitive `Co-authored-by:` lines in final commit messages. Respect `core.hooksPath`, support dry-run and explicit project paths, and preserve existing hooks without changing Git configuration.
10
+ - Strengthen the `git-workflow` skill, managed Copilot project instructions, and global engineering guardrails to prohibit `Co-authored-by:` trailers, equivalent co-author metadata, AI/agent signatures, and generated-by footers in commits and pull requests.
11
+ - Cover indirect attribution through commit trailers, templates, API fields, and Git author/committer identity overrides.
12
+ - Require inspection of complete proposed commit/PR messages before creation and new commits before pushing. If tooling inserts attribution, stop before publishing and report the blocker without bypassing hooks or rewriting existing commits.
13
+
14
+ ### Compatibility and upgrade
15
+
16
+ - Existing CLI targets, scopes, flags, and copy/link modes are unchanged. Git hook installation is separate from skill installation and updates.
17
+ - After publication, run `npx dotnet-production-agent-skills@0.3.3 git-hook` inside each repository to opt in. Node.js must be available when Git runs. Existing hook managers require manual integration.
18
+ - The Git hook rejects co-author trailers locally; AI footers and PR text remain covered by agent instructions. API-created commits and hook bypasses require a server-side required check for merge enforcement.
19
+ - After publication, update installed skills with `npx dotnet-production-agent-skills@0.3.3 update --target all`. Add `--scope project` to refresh that project's managed Copilot instructions and installed skills. Review local edits before updating.
20
+
21
+ ### Validation
22
+
23
+ `npm run validate` passed: all 31 skills validated, the TypeScript build passed, and all 23 tests passed. Git hook tests cover real commits with inline, file-based, and trailer-based messages, installer idempotency, conflict preservation, custom hook paths, and dry-run behavior. Whitespace checks passed.
24
+
3
25
  ## v0.3.2 — Repository-safe terminal recovery
4
26
 
5
- Prepared for publication; this version has not yet been published to npm.
27
+ Released in [`dotnet-production-agent-skills@0.3.2`](https://www.npmjs.com/package/dotnet-production-agent-skills/v/0.3.2).
6
28
 
7
29
  ### Improved
8
30
 
@@ -21,7 +43,7 @@ Prepared for publication; this version has not yet been published to npm.
21
43
 
22
44
  - CLI targets, scopes, flags, and copy/link modes are unchanged.
23
45
  - These changes strengthen agent guidance; existing hooks do not enforce the new repository-directory recovery rules.
24
- - After publication, update installed skills with `npx dotnet-production-agent-skills@0.3.2 update --target all`. Run the update in project scope (`--scope project`) to refresh that project's managed Copilot instructions and installed skills. Review local edits before updating.
46
+ - Update installed skills with `npx dotnet-production-agent-skills@0.3.2 update --target all`. Run the update in project scope (`--scope project`) to refresh that project's managed Copilot instructions and installed skills. Review local edits before updating.
25
47
 
26
48
  ### Validation
27
49
 
@@ -7,4 +7,6 @@ Do not introduce retries automatically. Add them only when requested or required
7
7
  When behavior changes, check whether existing tests need updating. Avoid redundant tests that slow CI.
8
8
  Run the smallest appropriate validation, build, or test command after changing code.
9
9
 
10
+ Strict authorship rule for every coding agent: never add `Co-authored-by:` trailers (case-insensitive), co-author metadata, AI/agent signatures, credits, or generated-by footers to commits or pull request titles/descriptions. Do not inject attribution through `--trailer`, templates, API fields, or author/committer identity overrides. Inspect the complete proposed commit/PR text and remove automatically suggested attribution before creation; inspect the new commits' full messages before pushing. If a hook, tool, or host adds attribution, stop before publishing and report the blocker. Do not bypass hooks, change configuration, amend existing commits, or rewrite published history without explicit authorization. Apply the git-workflow skill for the full procedure.
11
+
10
12
  Before terminal commands, apply the safe-terminal skill and verify the actual shell and project working directory. After a failure, inspect the submitted/executed command and first actionable error before choosing a correction. Never add terminal control sequences or move into Git/tool installation folders as a workaround. Executable location and repository location are separate: keep commands in the project, verify Git's intended repository with `git -C "<project-path>" rev-parse --show-toplevel`, and use same-session executable lookup only for a genuine command-not-found error. Do not guess binary paths, switch shells, edit PATH/profiles/configuration, or reinstall tools to escape an unexplained failure. Retry only after an evidence-based correction; stop after at most three distinct corrections.
package/dist/src/cli.js CHANGED
@@ -9,6 +9,7 @@ import { createInterface } from "node:readline/promises";
9
9
  import { changeInstructions, inspectInstructions } from "./copilot/instructions.js";
10
10
  import { changeHooks, hookTargets, inspectHooks, removeSharedHookScript } from "./hooks.js";
11
11
  import { validateSkills } from "./skills/validation.js";
12
+ import { installGitHook } from "./git-hook.js";
12
13
  const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
13
14
  const SKILLS_ROOT = path.join(PACKAGE_ROOT, "skills");
14
15
  const MANIFEST_NAME = ".dotnet-agent-skills.json";
@@ -22,6 +23,7 @@ Commands:
22
23
  list List packaged skills and installation state
23
24
  doctor Validate packaged skills and inspect installation health
24
25
  uninstall Remove only skills tracked by this package
26
+ git-hook Opt in to a Git commit-msg hook in the current/--project repository
25
27
 
26
28
  Options:
27
29
  --target <all|shared|codex|copilot|claude|cursor|antigravity>
@@ -459,11 +461,13 @@ async function main() {
459
461
  console.log(usage());
460
462
  return;
461
463
  }
462
- const commands = new Set(["install", "update", "list", "doctor", "uninstall"]);
464
+ const commands = new Set(["install", "update", "list", "doctor", "uninstall", "git-hook"]);
463
465
  if (!commands.has(parsed.command))
464
466
  throw new Error(`unknown command: ${parsed.command}`);
465
467
  const command = parsed.command;
466
- if (command === "install" || command === "update")
468
+ if (command === "git-hook")
469
+ console.log(await installGitHook(parsed.options.project, PACKAGE_ROOT, parsed.options.dryRun));
470
+ else if (command === "install" || command === "update")
467
471
  await installOrUpdate(parsed.options, command);
468
472
  else if (command === "uninstall")
469
473
  await uninstall(parsed.options);
@@ -0,0 +1,32 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { chmod, lstat, mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ export async function installGitHook(project, packageRoot, dryRun) {
5
+ const result = spawnSync("git", ["rev-parse", "--git-path", "hooks/commit-msg"], { cwd: project, encoding: "utf8" });
6
+ if (result.error)
7
+ throw result.error;
8
+ if (result.status !== 0)
9
+ throw new Error(result.stderr.trim() || "Git repository required for git-hook.");
10
+ const destination = path.resolve(project, result.stdout.trim());
11
+ const source = await readFile(path.join(packageRoot, "hooks", "commit-msg"), "utf8");
12
+ let exists = false;
13
+ try {
14
+ const entry = await lstat(destination);
15
+ exists = true;
16
+ if (!entry.isFile() || await readFile(destination, "utf8") !== source) {
17
+ throw new Error(`Existing commit-msg hook preserved at ${destination}. Integrate the packaged hooks/commit-msg check into your hook manager manually.`);
18
+ }
19
+ }
20
+ catch (error) {
21
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
22
+ throw error;
23
+ }
24
+ if (dryRun)
25
+ return `would ${exists ? "verify" : "install"} commit-msg hook: ${destination}`;
26
+ if (!exists) {
27
+ await mkdir(path.dirname(destination), { recursive: true });
28
+ await writeFile(destination, source, { flag: "wx", mode: 0o755 });
29
+ }
30
+ await chmod(destination, 0o755);
31
+ return `${exists ? "verified" : "installed"} commit-msg hook: ${destination}`;
32
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+
3
+ // dotnet-production-agent-skills: reject co-author attribution in the final message.
4
+ (async () => {
5
+ const { readFile } = await import("node:fs/promises");
6
+ const file = process.argv[2];
7
+ if (!file) throw new Error("Expected the commit message file path.");
8
+ const message = await readFile(file, "utf8");
9
+ if (/^\s*co-authored-by\s*:/im.test(message)) {
10
+ process.stderr.write("Commit rejected: Co-authored-by trailers are forbidden. Remove the attribution and retry; do not bypass the hook.\n");
11
+ process.exitCode = 1;
12
+ }
13
+ })().catch((error) => {
14
+ process.stderr.write(`Commit message validation failed: ${error.message}\n`);
15
+ process.exitCode = 1;
16
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotnet-production-agent-skills",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Portable production .NET engineering skills for coding agents",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -20,7 +20,15 @@ Branch names:
20
20
 
21
21
  Reuse a Jira ID from the current branch or user input. Never invent one; ask if the requested operation requires an unavailable ID.
22
22
 
23
- Commit messages begin with the Jira ID, for example `XDCI-12345 Add order webhook retry handling`. Do not add co-author, AI, or agent attribution.
23
+ Commit messages begin with the Jira ID, for example `XDCI-12345 Add order webhook retry handling`.
24
+
25
+ ## Strict authorship policy
26
+
27
+ - Never add `Co-authored-by:` trailers (case-insensitive), co-author metadata, or equivalent attribution to commits or pull requests. This applies to every coding agent, including GitHub Copilot, Codex, Claude, and Cursor.
28
+ - Never append AI/agent signatures, credits, or footers such as "Generated with Copilot" or "Assisted by Claude" to commit messages or pull request titles/descriptions.
29
+ - Do not supply attribution through `git commit --trailer`, commit-message templates, API fields, or another indirect mechanism. Do not change the configured Git author/committer identity or use `--author` to credit an agent.
30
+ - Before creating a commit or pull request, inspect the complete proposed message, including its body and trailers, and remove any automatically suggested attribution. Before pushing, inspect the new commits' complete messages with `git log <base>..HEAD --format=full` and verify the same policy.
31
+ - If a hook, tool, or host adds forbidden attribution, stop before publishing and report the blocker. Do not bypass hooks, change tool configuration, amend existing commits, or rewrite published history without explicit authorization.
24
32
 
25
33
  Before committing, confirm required validation and scan the intended changes for secrets/artifacts. Do not include unrelated changes. Do not change Git identity, credentials, credential helpers, or authentication configuration.
26
34