rhachet-roles-ehmpathy 1.15.14 → 1.15.16

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.
Files changed (89) hide show
  1. package/dist/domain.roles/mechanic/briefs/practices/code.prod/pitofsuccess.typedefs/rule.forbid.as-cast.md +65 -0
  2. package/dist/domain.roles/mechanic/briefs/practices/code.prod/pitofsuccess.typedefs/rule.require.shapefit.md +41 -0
  3. package/dist/domain.roles/mechanic/briefs/{criteria.practices/prefer.emojis.chill_nature.md → practices/lang.tones/rule.prefer.chill-nature-emojis.md} +0 -1
  4. package/dist/domain.roles/mechanic/inits/init.claude.permissions.jsonc +16 -5
  5. package/dist/domain.roles/mechanic/skills/claude.tools/mvsafe.sh +103 -0
  6. package/dist/domain.roles/mechanic/skills/claude.tools/rmsafe.sh +97 -0
  7. package/package.json +1 -1
  8. package/dist/domain.roles/mechanic/briefs/architecture/ubiqlang.md +0 -37
  9. package/dist/domain.roles/mechanic/briefs/patterns/lang.tones/prefer.chill-nature.md +0 -0
  10. package/dist/domain.roles/mechanic/briefs/patterns/lang.tones/prefer.lowercase.md +0 -0
  11. /package/dist/domain.roles/mechanic/briefs/{codestyle → .archive}/_mech.compressed.md +0 -0
  12. /package/dist/domain.roles/mechanic/briefs/{codestyle → .archive}/_mech.compressed.prompt.md +0 -0
  13. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.declarative/.readme.md → .archive/code.prod.declarative.readme.md} +0 -0
  14. /package/dist/domain.roles/mechanic/briefs/{architecture/directional-dependencies.md → .archive/patterns.directional-dependencies.md} +0 -0
  15. /package/dist/domain.roles/mechanic/briefs/{style.compressed.md → .archive/style.compressed.md} +0 -0
  16. /package/dist/domain.roles/mechanic/briefs/{style.compressed.prompt.md → .archive/style.compressed.prompt.md} +0 -0
  17. /package/dist/domain.roles/mechanic/briefs/{criteria.practices/require.dependency.pinned_versions.md → practices/code.prod/consistent.artifacts/rule.require.pinned-versions.md} +0 -0
  18. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.typescript.utils/best-practice/ref.package.as-command.[tips].md → practices/code.prod/consistent.contracts/ref.package.as-command.[ref].md} +0 -0
  19. /package/dist/domain.roles/mechanic/briefs/{architecture/bounded-contexts.md → practices/code.prod/evolvable.architecture/rule.require.bounded-contexts.md} +0 -0
  20. /package/dist/domain.roles/mechanic/briefs/{architecture/domain-driven-design.md → practices/code.prod/evolvable.architecture/rule.require.domain-driven-design.md} +0 -0
  21. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.domain.objects/best-practice/ref.package.domain-objects.[readme].md → practices/code.prod/evolvable.domain.objects/ref.package.domain-objects.[ref].md} +0 -0
  22. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.domain.objects/bad-practices/blocker.has.attributes.nullable.md → practices/code.prod/evolvable.domain.objects/rule.forbid.nullable-without-reason.md} +0 -0
  23. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.domain.objects/bad-practices/blocker.has.attributes.undefined.md → practices/code.prod/evolvable.domain.objects/rule.forbid.undefined-attributes.md} +0 -0
  24. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.domain.objects/bad-practices/blocker.refs.immuatble.md → practices/code.prod/evolvable.domain.objects/rule.require.immutable-refs.md} +0 -0
  25. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.domain.operations/best-practice/require.sync.names.md → practices/code.prod/evolvable.domain.operations/rule.require.sync-filename-opname.md} +0 -0
  26. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.contract.inputs.nameargs/bad-practice/forbid.positional-args.md → practices/code.prod/evolvable.procedures/rule.forbid.positional-args.md.pt1.md} +0 -0
  27. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.domain.operations/bad-practices/forbid.ordered-args.md → practices/code.prod/evolvable.procedures/rule.forbid.positional-args.md.pt2.md} +0 -0
  28. /package/dist/domain.roles/mechanic/briefs/{codestyle/mech.arrowonly.md → practices/code.prod/evolvable.procedures/rule.require.arrow-only.md} +0 -0
  29. /package/dist/domain.roles/mechanic/briefs/{codestyle/mech.clear-contracts.md → practices/code.prod/evolvable.procedures/rule.require.clear-contracts.md} +0 -0
  30. /package/dist/domain.roles/mechanic/briefs/{engineer/dependency-injection.md → practices/code.prod/evolvable.procedures/rule.require.dependency-injection.md.pt1.md} +0 -0
  31. /package/dist/domain.roles/mechanic/briefs/{engineer/dependency-injection.stub.md → practices/code.prod/evolvable.procedures/rule.require.dependency-injection.md.pt2.md} +0 -0
  32. /package/dist/domain.roles/mechanic/briefs/{codestyle/mech.args.input-context.md → practices/code.prod/evolvable.procedures/rule.require.input-context-pattern.md.pt1.md} +0 -0
  33. /package/dist/domain.roles/mechanic/briefs/{codestyle/mech.args.input-inline.md → practices/code.prod/evolvable.procedures/rule.require.input-context-pattern.md.pt2.md} +0 -0
  34. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.contract.inputs.nameargs/best-practice/require.namedargs.md → practices/code.prod/evolvable.procedures/rule.require.named-args.md} +0 -0
  35. /package/dist/domain.roles/mechanic/briefs/{codestyle/flow.single-responsibility.md → practices/code.prod/evolvable.procedures/rule.require.single-responsibility.md} +0 -0
  36. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.repo.structure/bad-practices/forbid.barrel.exports.ts.md → practices/code.prod/evolvable.repo.structure/rule.forbid.barrel-exports.md} +0 -0
  37. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.repo.structure/bad-practices/forbid.index.ts.md → practices/code.prod/evolvable.repo.structure/rule.forbid.index-ts.md} +0 -0
  38. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.repo.structure/best-practice/dot-test-and-dot-temp.md → practices/code.prod/evolvable.repo.structure/rule.prefer.dot-dirs.md} +0 -0
  39. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.repo.structure/best-practice/directional-dependencies.md → practices/code.prod/evolvable.repo.structure/rule.require.directional-deps.md} +0 -0
  40. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.errors.failfast/bad-practices/forbid.failhide.md → practices/code.prod/pitofsuccess.errors/rule.forbid.error-hiding.md.pt1.md} +0 -0
  41. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.errors.failfast/bad-practices/forbid.hide_errors.md → practices/code.prod/pitofsuccess.errors/rule.forbid.error-hiding.md.pt2.md} +0 -0
  42. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.errors.failfast/best-practice/prefer.HelpfulError.wrap.md → practices/code.prod/pitofsuccess.errors/rule.prefer.helpful-error-wrap.md} +0 -0
  43. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.errors.failfast/best-practice/require.fail_fast.[demo].shell.md → practices/code.prod/pitofsuccess.errors/rule.require.fail-fast.[demo].shell.md} +0 -0
  44. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.errors.failfast/best-practice/require.fail_fast.md → practices/code.prod/pitofsuccess.errors/rule.require.fail-fast.[seed].md} +0 -0
  45. /package/dist/domain.roles/mechanic/briefs/{codestyle/flow.failfast.md → practices/code.prod/pitofsuccess.errors/rule.require.fail-fast.md} +0 -0
  46. /package/dist/domain.roles/mechanic/briefs/{criteria.practices/require.idempotency.md → practices/code.prod/pitofsuccess.procedures/rule.require.idempotency.[seed].md} +0 -0
  47. /package/dist/domain.roles/mechanic/briefs/{codestyle/flow.idempotency.md → practices/code.prod/pitofsuccess.procedures/rule.require.idempotent-procedures.md} +0 -0
  48. /package/dist/domain.roles/mechanic/briefs/{codestyle/flow.immutability.md → practices/code.prod/pitofsuccess.procedures/rule.require.immutable-vars.md} +0 -0
  49. /package/dist/domain.roles/mechanic/briefs/{codestyle/pit-of-success.via.minimize-surface-area.md → practices/code.prod/pitofsuccess.procedures/rule.require.pitofsuccess.md} +0 -0
  50. /package/dist/domain.roles/mechanic/briefs/{lessons/code.prod.typescript.types/bivariance_vs_contravariance.[lesson].md → practices/code.prod/pitofsuccess.typedefs/define.bivariance-for-generics.[lesson].md} +0 -0
  51. /package/dist/domain.roles/mechanic/briefs/{codestyle/mech.what-why.v2.md → practices/code.prod/readable.comments/rule.require.what-why-headers.md} +0 -0
  52. /package/dist/domain.roles/mechanic/briefs/{codestyle/mech.what-why.md → practices/code.prod/readable.comments/rule.require.what-why-headers.v1.md} +0 -0
  53. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.narrative/bad-practices/avoid.ifs.md → practices/code.prod/readable.narrative/rule.avoid.unnecessary-ifs.md} +0 -0
  54. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.narrative/bad-practices/forbid.else.md → practices/code.prod/readable.narrative/rule.forbid.else-branches.[demo].md} +0 -0
  55. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.narrative/bad-practices/forbid.else.v2.md → practices/code.prod/readable.narrative/rule.forbid.else-branches.md} +0 -0
  56. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.narrative/best-practice/early-returns.named-checks.[demo].md → practices/code.prod/readable.narrative/rule.prefer.early-returns.[demo].md} +0 -0
  57. /package/dist/domain.roles/mechanic/briefs/{codestyle/flow.transformers_over_conditionals.[lesson].md → practices/code.prod/readable.narrative/rule.prefer.transformers-over-conditionals.[lesson].md} +0 -0
  58. /package/dist/domain.roles/mechanic/briefs/{codestyle/flow.narratives.md → practices/code.prod/readable.narrative/rule.require.narrative-flow.md} +0 -0
  59. /package/dist/domain.roles/mechanic/briefs/{patterns/code.prod.declarative/best-practice/declastruct.[demo].md → practices/code.prod/readable.persistence/rule.prefer.declastruct.[demo].md} +0 -0
  60. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice/ref.test-fns.[readme].md → practices/code.test/consistent.contracts/ref.package.test-fns.[ref].md} +0 -0
  61. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice/howto.write.bdd.[lesson].md → practices/code.test/frames.behavior/howto.write-bdd.[lesson].md} +0 -0
  62. /package/dist/domain.roles/mechanic/briefs/{codestyle/mech.tests.given-when-then.md → practices/code.test/frames.behavior/rule.require.given-when-then.md} +0 -0
  63. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice/prefer.datadriven.md → practices/code.test/frames.caselist/rule.prefer.data-driven.md} +0 -0
  64. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice → practices/code.test/lessons.howto}/howto.diagnose.[lesson].md +0 -0
  65. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice → practices/code.test/lessons.howto}/howto.run.[lesson].md +0 -0
  66. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice → practices/code.test/lessons.howto}/howto.use.[lesson].md +0 -0
  67. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice/howto.write.[lesson].md → practices/code.test/lessons.howto/howto.write.[lesson].md.pt1.md} +0 -0
  68. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice/howto.write.[lesson].on_scope.for_integ.md → practices/code.test/lessons.howto/howto.write.[lesson].md.pt2.md} +0 -0
  69. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice/howto.write.[lesson].on_scope.for_units.md → practices/code.test/lessons.howto/howto.write.[lesson].md.pt3.md} +0 -0
  70. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.howto/best-practice/whento.snapshots.[lesson].md → practices/code.test/lessons.howto/rule.require.snapshots.[lesson].md} +0 -0
  71. /package/dist/domain.roles/mechanic/briefs/{patterns/code.test.acceptance/best-practice/blackbox.md → practices/code.test/scope.acceptance/rule.require.blackbox.md} +0 -0
  72. /package/dist/domain.roles/mechanic/briefs/{patterns → practices}/lang.terms/.readme.md +0 -0
  73. /package/dist/domain.roles/mechanic/briefs/{patterns/lang.terms/domain=practices.terms=forbid_prefer_desire_require.md → practices/lang.terms/define.directives.terms=forbid_avoid_prefer_require.md} +0 -0
  74. /package/dist/domain.roles/mechanic/briefs/{terms/plan.exec_vs_apply.md → practices/lang.terms/define.exec-vs-apply.md} +0 -0
  75. /package/dist/domain.roles/mechanic/briefs/{patterns/lang.terms/domain=software.terms=prodcode_vs_testcode.md → practices/lang.terms/define.prodcode-testcode.terms=prodcode_vs_testcode.md} +0 -0
  76. /package/dist/domain.roles/mechanic/briefs/{criteria.practices/never.term.script.md → practices/lang.terms/rule.forbid.term-script.md.pt1.md} +0 -0
  77. /package/dist/domain.roles/mechanic/briefs/{terms/badpractice/script.md → practices/lang.terms/rule.forbid.term-script.md.pt2.md} +0 -0
  78. /package/dist/domain.roles/mechanic/briefs/{patterns/lang.terms/bad-practices/forbid.term=existing.md → practices/lang.terms/rule.forbid.term=existing.md} +0 -0
  79. /package/dist/domain.roles/mechanic/briefs/{patterns/lang.terms/best-practice/require.order.noun_adj.md → practices/lang.terms/rule.require.order.noun_adj.md} +0 -0
  80. /package/dist/domain.roles/mechanic/briefs/{style.names.treestruct.md → practices/lang.terms/rule.require.treestruct.md} +0 -0
  81. /package/dist/domain.roles/mechanic/briefs/{style.names.ubiqlang.md → practices/lang.terms/rule.require.ubiqlang.md} +0 -0
  82. /package/dist/domain.roles/mechanic/briefs/{patterns → practices}/lang.tones/.readme.md +0 -0
  83. /package/dist/domain.roles/mechanic/briefs/{style.words.lowercase.md → practices/lang.tones/rule.prefer.lowercase.md} +0 -0
  84. /package/dist/domain.roles/mechanic/briefs/{patterns/flow.debug.diagnostics/bad-practices/forbid.trust_vscode.md → practices/work.flow/diagnose/rule.forbid.trust-vscode-diagnostics.md} +0 -0
  85. /package/dist/domain.roles/mechanic/briefs/{patterns/flow.refact.questions/best-practice/require.testchange.review.md → practices/work.flow/refactor/rule.require.review-test-changes.md} +0 -0
  86. /package/dist/domain.roles/mechanic/briefs/{criteria.practices/prefer.jq.over_alt.[demo].md → practices/work.flow/tools/rule.prefer.jq.[demo].md} +0 -0
  87. /package/dist/domain.roles/mechanic/briefs/{criteria.practices/prefer.terraform.[criteria].md → practices/work.flow/tools/rule.prefer.terraform.md.pt1.md} +0 -0
  88. /package/dist/domain.roles/mechanic/briefs/{criteria.practices/prefer.terraform.[seed].md → practices/work.flow/tools/rule.prefer.terraform.md.pt2.md} +0 -0
  89. /package/dist/domain.roles/mechanic/briefs/{criteria.practices/require.knowledge.externalized.md → practices/work.flow/tools/rule.require.externalized-knowledge.md} +0 -0
@@ -0,0 +1,65 @@
1
+ .tactic = types:forbid-as-cast
2
+
3
+ .what = using `as X` casts is forbidden — it signals a rule.require.shapefit violation
4
+
5
+ .scope:
6
+ - applies to all typescript code in the codebase
7
+ - enforced during code review and lint rules
8
+
9
+ .why:
10
+ - `as` casts bypass typescript's type system
11
+ - they hide legitimate type errors that indicate design flaws
12
+ - they create runtime hazards when the cast is incorrect
13
+ - they make refactoring dangerous by silencing compiler warnings
14
+
15
+ .exception:
16
+ - allowed only at boundaries with external org code that lacks proper typedefs
17
+ - must document via inline comment why this hazard is necessary
18
+ - must include a note about what would need to change to remove the cast
19
+
20
+ .how:
21
+ - when tempted to use `as`, ask: "why doesn't this type fit naturally?"
22
+ - investigate and fix the root cause instead of casting
23
+ - if the source types are wrong, create proper type definitions
24
+ - if runtime validation is needed, use proper type guards
25
+ - if the compiler is wrong about a type, file a typescript issue or use a narrower cast
26
+
27
+ .enforcement:
28
+ - `as` casts in prod code without documented exception = BLOCKER
29
+ - exception comments must explain:
30
+ - why the external code lacks proper types
31
+ - what the correct type should be
32
+ - what would need to change to remove the cast
33
+
34
+ .examples:
35
+
36
+ .positive:
37
+ ```ts
38
+ // refactoring to avoid cast
39
+ const result = processInput(input); // types align naturally
40
+
41
+ // using type guard instead of cast
42
+ if (isValidResponse(response)) {
43
+ // response is properly narrowed here
44
+ }
45
+
46
+ // documented external boundary (allowed exception)
47
+ // NOTE: third-party-sdk lacks proper types for this response
48
+ // TODO: contribute types upstream or create local declaration file
49
+ const data = response.data as ThirdPartyResponse;
50
+ ```
51
+
52
+ .negative:
53
+ ```ts
54
+ // ⛔ undocumented cast
55
+ const user = data as User;
56
+
57
+ // ⛔ cast to silence error
58
+ const result = badFunction() as ExpectedType;
59
+
60
+ // ⛔ any-cast escape hatch
61
+ const x = (y as any) as SomeType;
62
+ ```
63
+
64
+ .links:
65
+ - see also: `rule.require.shapefit`
@@ -0,0 +1,41 @@
1
+ .tactic = types:shapefit
2
+
3
+ .what = types must be well-defined and naturally fit; mismatches signal legitimate defects to resolve
4
+
5
+ .scope:
6
+ - applies to all type definitions, function signatures, and data transformations
7
+ - enforced at compile time via typescript's type system
8
+
9
+ .why:
10
+ - types that don't fit indicate a design flaw or incomplete understanding of the domain
11
+ - forcing types to fit via casts hides bugs and creates runtime hazards
12
+ - well-shaped types enable the compiler to catch errors before runtime
13
+ - creates a pit-of-success where correct code is easier to write than incorrect code
14
+
15
+ .how:
16
+ - if a type doesn't fit, investigate the root cause:
17
+ - is the source data incorrectly shaped?
18
+ - is the target type overly restrictive?
19
+ - is there a missing transformation step?
20
+ - resolve the mismatch by fixing the actual problem, not by casting
21
+ - use discriminated unions and type guards for legitimate polymorphism
22
+ - rely on typescript's inference rather than explicit annotations where possible
23
+
24
+ .enforcement:
25
+ - type errors are blockers, not warnings to suppress
26
+ - `as` casts are forbidden except at documented external boundaries (see rule.forbid.as-cast)
27
+ - `any` types are forbidden except for truly dynamic scenarios with proper runtime validation
28
+
29
+ .examples:
30
+
31
+ .positive:
32
+ - refactoring a function signature to accept the actual input type
33
+ - adding a missing property to a domain object
34
+ - using `satisfies` to check conformance without casting
35
+ - creating proper type guards for narrowing
36
+
37
+ .negative:
38
+ - `const x = y as SomeType` to silence compiler
39
+ - `// @ts-ignore` to skip type checking
40
+ - using `any` to bypass type constraints
41
+ - loosening types to accommodate bad data
@@ -11,7 +11,9 @@
11
11
  "deny": [
12
12
  // git write operations - require explicit user request for audit trail
13
13
  "Bash(git commit:*)",
14
- "Bash(git add:*)",
14
+ "Bash(git add .)",
15
+ "Bash(git add -A:*)",
16
+ "Bash(git add --all:*)",
15
17
  "Bash(git stash:*)",
16
18
  "Bash(git checkout:*)",
17
19
  "Bash(git branch -d:*)",
@@ -24,6 +26,10 @@
24
26
  "Bash(git reflog delete:*)",
25
27
  "Bash(git config:*)",
26
28
 
29
+ // git mv/rm - use mvsafe.sh and rmsafe.sh instead (repo-constrained)
30
+ "Bash(git mv:*)",
31
+ "Bash(git rm:*)",
32
+
27
33
  // "anywrite" commands - CRITICAL SECURITY RISK
28
34
  //
29
35
  // unlike Claude's native Edit/Write tools which are scoped to the repo,
@@ -141,10 +147,6 @@
141
147
  "Bash(mkdir:*)",
142
148
  "Bash(pwd)",
143
149
 
144
- // git mv/rm are safe - constrained to repo, all changes revertable
145
- "Bash(git mv:*)",
146
- "Bash(git rm:*)",
147
-
148
150
  // git read-only - all have no write variants
149
151
  "Bash(git log:*)",
150
152
  "Bash(git status:*)",
@@ -162,6 +164,12 @@
162
164
  // cpsafe - safe file copy within git repo (source must be git-tracked)
163
165
  "Bash(.agent/repo=ehmpathy/role=mechanic/skills/.skills/claude.tools/cpsafe.sh:*)",
164
166
 
167
+ // mvsafe - safe file move within git repo
168
+ "Bash(.agent/repo=ehmpathy/role=mechanic/skills/.skills/claude.tools/mvsafe.sh:*)",
169
+
170
+ // rmsafe - safe file removal within git repo
171
+ "Bash(.agent/repo=ehmpathy/role=mechanic/skills/.skills/claude.tools/rmsafe.sh:*)",
172
+
165
173
  // npm read operations
166
174
  "Bash(npm view:*)",
167
175
  "Bash(npm list:*)",
@@ -209,6 +217,9 @@
209
217
  "Bash(RESNAP=true THOROUGH=true npm run test:integration:*)",
210
218
  "Bash(RESNAP=true THOROUGH=true npm run test:acceptance:*)",
211
219
 
220
+ // test list operation
221
+ "Bash(npx jest --listTests:*)",
222
+
212
223
  // fix operations
213
224
  "Bash(npm run fix:*)",
214
225
  "Bash(npm run fix:format:*)",
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env bash
2
+ ######################################################################
3
+ # .what = safe file move within git repo
4
+ #
5
+ # .why = enables file moving without:
6
+ # - touching files outside the repo
7
+ # - accidental path traversal attacks
8
+ #
9
+ # this is a controlled alternative to raw mv, which is
10
+ # denied in permissions due to security risks.
11
+ #
12
+ # usage:
13
+ # mvsafe.sh --src "path/to/source" --dest "path/to/dest"
14
+ #
15
+ # guarantee:
16
+ # - source must be within repo
17
+ # - dest must be within repo
18
+ # - creates parent directories if needed
19
+ # - fail-fast on errors
20
+ ######################################################################
21
+ set -euo pipefail
22
+
23
+ # parse named arguments
24
+ SRC=""
25
+ DEST=""
26
+
27
+ while [[ $# -gt 0 ]]; do
28
+ case $1 in
29
+ --src)
30
+ SRC="$2"
31
+ shift 2
32
+ ;;
33
+ --dest)
34
+ DEST="$2"
35
+ shift 2
36
+ ;;
37
+ *)
38
+ echo "unknown argument: $1"
39
+ echo "usage: mvsafe.sh --src 'source' --dest 'destination'"
40
+ exit 1
41
+ ;;
42
+ esac
43
+ done
44
+
45
+ # validate required args
46
+ if [[ -z "$SRC" ]]; then
47
+ echo "error: --src is required"
48
+ exit 1
49
+ fi
50
+
51
+ if [[ -z "$DEST" ]]; then
52
+ echo "error: --dest is required"
53
+ exit 1
54
+ fi
55
+
56
+ # ensure we're in a git repo
57
+ if ! git rev-parse --git-dir > /dev/null 2>&1; then
58
+ echo "error: not in a git repository"
59
+ exit 1
60
+ fi
61
+
62
+ # get repo root
63
+ REPO_ROOT=$(git rev-parse --show-toplevel)
64
+
65
+ # resolve absolute paths
66
+ SRC_ABS=$(realpath -m "$SRC")
67
+ DEST_ABS=$(realpath -m "$DEST")
68
+
69
+ # validate source is within repo
70
+ if [[ "$SRC_ABS" != "$REPO_ROOT"* ]]; then
71
+ echo "error: source must be within the git repository"
72
+ echo " repo root: $REPO_ROOT"
73
+ echo " source: $SRC_ABS"
74
+ exit 1
75
+ fi
76
+
77
+ # validate dest is within repo
78
+ if [[ "$DEST_ABS" != "$REPO_ROOT"* ]]; then
79
+ echo "error: destination must be within the git repository"
80
+ echo " repo root: $REPO_ROOT"
81
+ echo " dest: $DEST_ABS"
82
+ exit 1
83
+ fi
84
+
85
+ # validate source exists
86
+ if [[ ! -e "$SRC_ABS" ]]; then
87
+ echo "error: source does not exist: $SRC"
88
+ exit 1
89
+ fi
90
+
91
+ # create parent directories if needed
92
+ DEST_DIR=$(dirname "$DEST_ABS")
93
+ if [[ ! -d "$DEST_DIR" ]]; then
94
+ echo "creating directory: $DEST_DIR"
95
+ mkdir -p "$DEST_DIR"
96
+ fi
97
+
98
+ # perform the move
99
+ mv "$SRC_ABS" "$DEST_ABS"
100
+
101
+ SRC_REL="${SRC_ABS#$REPO_ROOT/}"
102
+ DEST_REL="${DEST_ABS#$REPO_ROOT/}"
103
+ echo "moved: $SRC_REL -> $DEST_REL"
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env bash
2
+ ######################################################################
3
+ # .what = safe file removal within git repo
4
+ #
5
+ # .why = enables file deletion without:
6
+ # - touching files outside the repo
7
+ # - accidental path traversal attacks
8
+ #
9
+ # this is a controlled alternative to raw rm, which is
10
+ # denied in permissions due to security risks.
11
+ #
12
+ # usage:
13
+ # rmsafe.sh --path "path/to/file"
14
+ # rmsafe.sh --path "path/to/dir" --recursive
15
+ #
16
+ # guarantee:
17
+ # - path must be within repo
18
+ # - requires --recursive for directories
19
+ # - fail-fast on errors
20
+ ######################################################################
21
+ set -euo pipefail
22
+
23
+ # parse named arguments
24
+ TARGET=""
25
+ RECURSIVE=false
26
+
27
+ while [[ $# -gt 0 ]]; do
28
+ case $1 in
29
+ --path)
30
+ TARGET="$2"
31
+ shift 2
32
+ ;;
33
+ --recursive|-r)
34
+ RECURSIVE=true
35
+ shift
36
+ ;;
37
+ *)
38
+ echo "unknown argument: $1"
39
+ echo "usage: rmsafe.sh --path 'target' [--recursive]"
40
+ exit 1
41
+ ;;
42
+ esac
43
+ done
44
+
45
+ # validate required args
46
+ if [[ -z "$TARGET" ]]; then
47
+ echo "error: --path is required"
48
+ exit 1
49
+ fi
50
+
51
+ # ensure we're in a git repo
52
+ if ! git rev-parse --git-dir > /dev/null 2>&1; then
53
+ echo "error: not in a git repository"
54
+ exit 1
55
+ fi
56
+
57
+ # get repo root
58
+ REPO_ROOT=$(git rev-parse --show-toplevel)
59
+
60
+ # resolve absolute path
61
+ TARGET_ABS=$(realpath -m "$TARGET")
62
+
63
+ # validate target is within repo
64
+ if [[ "$TARGET_ABS" != "$REPO_ROOT"* ]]; then
65
+ echo "error: path must be within the git repository"
66
+ echo " repo root: $REPO_ROOT"
67
+ echo " path: $TARGET_ABS"
68
+ exit 1
69
+ fi
70
+
71
+ # prevent deleting repo root itself
72
+ if [[ "$TARGET_ABS" == "$REPO_ROOT" ]]; then
73
+ echo "error: cannot delete the repository root"
74
+ exit 1
75
+ fi
76
+
77
+ # validate target exists
78
+ if [[ ! -e "$TARGET_ABS" ]]; then
79
+ echo "error: path does not exist: $TARGET"
80
+ exit 1
81
+ fi
82
+
83
+ # check if directory and require --recursive
84
+ if [[ -d "$TARGET_ABS" ]] && [[ "$RECURSIVE" != true ]]; then
85
+ echo "error: target is a directory, use --recursive to delete"
86
+ exit 1
87
+ fi
88
+
89
+ # perform the removal
90
+ if [[ "$RECURSIVE" == true ]]; then
91
+ rm -rf "$TARGET_ABS"
92
+ else
93
+ rm "$TARGET_ABS"
94
+ fi
95
+
96
+ TARGET_REL="${TARGET_ABS#$REPO_ROOT/}"
97
+ echo "removed: $TARGET_REL"
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "rhachet-roles-ehmpathy",
3
3
  "author": "ehmpathy",
4
4
  "description": "empathetic software construction roles and skills, via rhachet",
5
- "version": "1.15.14",
5
+ "version": "1.15.16",
6
6
  "repository": "ehmpathy/rhachet-roles-ehmpathy",
7
7
  "homepage": "https://github.com/ehmpathy/rhachet-roles-ehmpathy",
8
8
  "keywords": [
@@ -1,37 +0,0 @@
1
- .tactic = name:ubiqlang
2
-
3
- .what = enforce a rigorous, domain-driven naming system rooted in ubiquitous language
4
- .where:
5
- - ubiquitous language = the shared, unambiguous vocabulary used by both domain experts and developers
6
- - this tactic applies to all names: types, variables, functions, slugs, and folders
7
-
8
- .why:
9
- - eliminates ambiguity and cognitive friction
10
- - ensures that everyone speaks the same language — in code, UI, tests, and docs
11
- - prevents synonym drift (e.g., "client" vs "customer") and overload traps (e.g., "update" meaning 3 things)
12
-
13
- .how:
14
- - eliminate synonyms
15
- - choose one canonical word per concept (e.g., always use `customer`, never `client`, `user`, or `account`)
16
- - eliminate overloads
17
- - each term must refer to one concept only (e.g., avoid using `update` for both "save data" and "fetch latest")
18
- - use consistent noun-verb stacking that mirrors domain intent (e.g., `customerPhoneUpdate`, not `editPhoneNumber`)
19
- - whenever a new term is introduced:
20
- - define its interface, expected shape, and role
21
- - document its meaning clearly and visibly (ideally in context or hover docs)
22
- - ensure its usage is verified across type definitions, business rules, and communication flows
23
-
24
- .examples:
25
- .positive:
26
- - `customer` instead of `client`, `user`, or `buyer`
27
- - `jobQuote` as the single term for estimates/proposals
28
- - `leadCapture` as the canonical action for inbound lead collection
29
- - `customerPhoneUpdate` for updating a phone number
30
- - `invoiceDraft` and `invoiceFinal` for two distinct invoice states
31
-
32
- .negative:
33
- - `client`, `user`, `account`, `buyer` all referring to the same actor
34
- - `editCustomerPhone`, `changePhone`, `updateNumber` used interchangeably
35
- - `job` used for both a requested service and a completed one
36
- - `update()` overloaded to mean save, patch, sync, or refresh
37
- - `quote`, `estimate`, `proposal`, and `bid` all floating without clear hierarchy