@sentropic/harness 0.1.1 → 0.2.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.
Files changed (45) hide show
  1. package/README.md +32 -11
  2. package/dist/artifacts/work-event.d.ts +28 -0
  3. package/dist/artifacts/work-event.d.ts.map +1 -0
  4. package/dist/artifacts/work-event.js +9 -0
  5. package/dist/artifacts/work-event.js.map +1 -0
  6. package/dist/cli/args.d.ts +10 -0
  7. package/dist/cli/args.d.ts.map +1 -0
  8. package/dist/cli/args.js +32 -0
  9. package/dist/cli/args.js.map +1 -0
  10. package/dist/cli/mechanical-verbs.d.ts +9 -0
  11. package/dist/cli/mechanical-verbs.d.ts.map +1 -0
  12. package/dist/cli/mechanical-verbs.js +124 -0
  13. package/dist/cli/mechanical-verbs.js.map +1 -0
  14. package/dist/cli/method-verbs.d.ts +14 -0
  15. package/dist/cli/method-verbs.d.ts.map +1 -0
  16. package/dist/cli/method-verbs.js +170 -0
  17. package/dist/cli/method-verbs.js.map +1 -0
  18. package/dist/cli/run.d.ts +4 -3
  19. package/dist/cli/run.d.ts.map +1 -1
  20. package/dist/cli/run.js +51 -66
  21. package/dist/cli/run.js.map +1 -1
  22. package/dist/cli/scope.d.ts +12 -0
  23. package/dist/cli/scope.d.ts.map +1 -0
  24. package/dist/cli/scope.js +31 -0
  25. package/dist/cli/scope.js.map +1 -0
  26. package/dist/index.d.ts +5 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +3 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/run/work-event.d.ts +25 -0
  31. package/dist/run/work-event.d.ts.map +1 -0
  32. package/dist/run/work-event.js +27 -0
  33. package/dist/run/work-event.js.map +1 -0
  34. package/dist/skills/manifest.d.ts +14 -0
  35. package/dist/skills/manifest.d.ts.map +1 -0
  36. package/dist/skills/manifest.js +25 -0
  37. package/dist/skills/manifest.js.map +1 -0
  38. package/package.json +4 -3
  39. package/skills/adopt/SKILL.md +32 -0
  40. package/skills/brainstorm/SKILL.md +39 -0
  41. package/skills/debug/SKILL.md +33 -0
  42. package/skills/plan/SKILL.md +35 -0
  43. package/skills/review/SKILL.md +33 -0
  44. package/skills/test/SKILL.md +44 -0
  45. package/skills/using-harness/SKILL.md +46 -0
package/dist/cli/run.js CHANGED
@@ -1,55 +1,32 @@
1
- import { readFileSync } from 'node:fs';
2
- import { parseBranchMd } from '../branch-md/parse.js';
3
- import { checkScope } from '../checks/scope-check.js';
4
1
  import { checkBranch } from '../checks/branch-check.js';
5
2
  import { toVerificationRun } from '../run/emit.js';
6
3
  import { sentropicProfile } from '../profile/sentropic.js';
7
4
  import { stubProfile } from '../profile/stub.js';
8
- function parseFlags(args) {
9
- const positionals = [];
10
- const flags = {};
11
- for (let i = 0; i < args.length; i++) {
12
- const a = args[i];
13
- if (a.startsWith('--')) {
14
- const key = a.slice(2);
15
- const next = args[i + 1];
16
- if (next === undefined || next.startsWith('--')) {
17
- flags[key] = true;
18
- }
19
- else {
20
- flags[key] = next;
21
- i++;
22
- }
23
- }
24
- else {
25
- positionals.push(a);
26
- }
27
- }
28
- return { positionals, flags };
29
- }
30
- function str(v) {
31
- return typeof v === 'string' ? v : undefined;
32
- }
33
- function list(v) {
34
- const s = str(v);
35
- return s ? s.split(/[\s,]+/).filter(Boolean) : [];
36
- }
37
- const USAGE = 'usage: harness check <scope|branch> [--current-branch <b>] [--expected-branch <b>] ' +
38
- '[--staged-files <list>] [--branch-md <path>] [--profile sentropic|stub] [--json]';
39
- /**
40
- * Pure, arg-based CLI driver — reads everything from `argv`, writes via `out`, returns an exit code.
41
- * No internal git calls (the caller supplies branch + staged files), no `process.exit`.
42
- * Advisory (D5 Layer A): a failing check returns 0; only a usage error returns non-zero.
43
- * Acquiring git state under Docker-first (the `make scope-check` passthrough) is a separate,
44
- * to-be-double-reviewed concern.
45
- */
46
- export function runHarnessCli(argv, out) {
47
- const { positionals, flags } = parseFlags(argv);
48
- const command = positionals[0];
5
+ import { parseFlags, str } from './args.js';
6
+ import { scopeFromFlags } from './scope.js';
7
+ import { handleMethodVerb } from './method-verbs.js';
8
+ import { handleMechanicalVerb } from './mechanical-verbs.js';
9
+ const USAGE = [
10
+ 'usage: harness check <scope|branch> [--current-branch <b>] [--expected-branch <b>] ' +
11
+ '[--staged-files <list>] [--branch-md <path>] [--profile sentropic|stub] [--json]',
12
+ ' harness verify [--category static|unit|integration|e2e|ci|uat] [--staged-files <list>] ' +
13
+ '[--current-branch <b>] [--expected-branch <b>] [--branch-md <path>] [--profile sentropic|stub] [--json]',
14
+ ' harness init [--profile sentropic|stub] [--json]',
15
+ ' harness audit [--staged-files <list>] [--branch-md <path>] [--profile sentropic|stub] [--json]',
16
+ ' harness brainstorm [<topic>] [--peers <n>] [--ladder study|vol|evol] [--json]',
17
+ ' harness test [<scope>] [--category unit|integration|e2e] [--watch] [--json]',
18
+ ' harness debug [<symptom>] [--json]',
19
+ ' harness review [<target>] [--consensus] [--peers <n>] [--json]',
20
+ ' harness plan [<spec>] [--lots <n>] [--json]',
21
+ ' harness branch <init|close> [<slug>] [--json]',
22
+ ' harness skills install --host <claude|codex|gemini> [--json]',
23
+ ].join('\n');
24
+ /** The `check scope|branch` static checks (C2/C1) — emit a neutral VerificationRun. */
25
+ function handleCheck(positionals, flags, out) {
49
26
  const sub = positionals[1];
50
- if (command !== 'check' || (sub !== 'scope' && sub !== 'branch')) {
27
+ if (sub !== 'scope' && sub !== 'branch') {
51
28
  out(USAGE);
52
- return command === undefined ? 0 : 2;
29
+ return 2;
53
30
  }
54
31
  const profile = str(flags.profile) === 'stub' ? stubProfile : sentropicProfile;
55
32
  const category = 'static';
@@ -59,27 +36,12 @@ export function runHarnessCli(argv, out) {
59
36
  if (sub === 'scope') {
60
37
  code = 'C2';
61
38
  commandLabel = 'harness check scope';
62
- const branchMdPath = str(flags['branch-md']);
63
- let parsed;
64
- if (branchMdPath) {
65
- try {
66
- parsed = parseBranchMd(readFileSync(branchMdPath, 'utf8'));
67
- }
68
- catch {
69
- out(`harness: cannot read plan file: ${branchMdPath}`);
70
- return 2;
71
- }
39
+ const outcome = scopeFromFlags(flags, profile);
40
+ if (outcome.unreadable !== undefined) {
41
+ out(`harness: cannot read plan file: ${outcome.unreadable}`);
42
+ return 2;
72
43
  }
73
- result = checkScope({
74
- stagedFiles: list(flags['staged-files']),
75
- boundary: {
76
- allowed: parsed?.allowedPaths ?? [],
77
- forbidden: parsed?.forbiddenPaths ?? [],
78
- conditional: parsed?.conditionalPaths ?? [],
79
- },
80
- profile,
81
- declaredExceptions: parsed?.exceptions ?? [],
82
- });
44
+ result = outcome.result;
83
45
  }
84
46
  else {
85
47
  code = 'C1';
@@ -113,4 +75,27 @@ export function runHarnessCli(argv, out) {
113
75
  }
114
76
  return 0;
115
77
  }
78
+ /**
79
+ * Pure, arg-based CLI driver — reads everything from `argv`, writes via `out`, returns an exit code.
80
+ * No internal git calls (the caller supplies branch + staged files), no `process.exit`, no fs writes.
81
+ * Advisory (D5 Layer A): a failing check returns 0; only a usage error returns non-zero.
82
+ *
83
+ * Verb families: `check` (C1/C2 → VerificationRun); method/recorder verbs (brainstorm/test/debug/
84
+ * review/plan/branch/skills → WorkEvent + skill pointer, see `method-verbs.ts`).
85
+ */
86
+ export function runHarnessCli(argv, out) {
87
+ const { positionals, flags } = parseFlags(argv);
88
+ const command = positionals[0];
89
+ if (command === 'check') {
90
+ return handleCheck(positionals, flags, out);
91
+ }
92
+ const mechanicalCode = handleMechanicalVerb(positionals, flags, out);
93
+ if (mechanicalCode !== null)
94
+ return mechanicalCode;
95
+ const methodCode = handleMethodVerb(positionals, flags, out);
96
+ if (methodCode !== null)
97
+ return methodCode;
98
+ out(USAGE);
99
+ return command === undefined ? 0 : 2;
100
+ }
116
101
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { CheckResult } from '../artifacts/verification-run.js';
2
+ import type { HarnessProfile } from '../profile/profile.js';
3
+ import { type FlagValue } from './args.js';
4
+ export interface ScopeOutcome {
5
+ /** The scope CheckResult, when inputs resolved. */
6
+ result?: CheckResult;
7
+ /** The unreadable plan-file path, when `--branch-md` could not be read. */
8
+ unreadable?: string;
9
+ }
10
+ /** Resolve `--branch-md` + `--staged-files` into a C2 scope CheckResult (pure but for the file read). */
11
+ export declare function scopeFromFlags(flags: Record<string, FlagValue>, profile: HarnessProfile): ScopeOutcome;
12
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/cli/scope.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,yGAAyG;AACzG,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,YAAY,CAqBtG"}
@@ -0,0 +1,31 @@
1
+ // Shared scope-check input resolution — used by `check scope`, `verify`, and `audit` so the
2
+ // BRANCH.md parsing + boundary wiring lives in ONE place (no duplicated file IO).
3
+ import { readFileSync } from 'node:fs';
4
+ import { parseBranchMd } from '../branch-md/parse.js';
5
+ import { checkScope } from '../checks/scope-check.js';
6
+ import { list, str } from './args.js';
7
+ /** Resolve `--branch-md` + `--staged-files` into a C2 scope CheckResult (pure but for the file read). */
8
+ export function scopeFromFlags(flags, profile) {
9
+ const branchMdPath = str(flags['branch-md']);
10
+ let parsed;
11
+ if (branchMdPath) {
12
+ try {
13
+ parsed = parseBranchMd(readFileSync(branchMdPath, 'utf8'));
14
+ }
15
+ catch {
16
+ return { unreadable: branchMdPath };
17
+ }
18
+ }
19
+ const result = checkScope({
20
+ stagedFiles: list(flags['staged-files']),
21
+ boundary: {
22
+ allowed: parsed?.allowedPaths ?? [],
23
+ forbidden: parsed?.forbiddenPaths ?? [],
24
+ conditional: parsed?.conditionalPaths ?? [],
25
+ },
26
+ profile,
27
+ declaredExceptions: parsed?.exceptions ?? [],
28
+ });
29
+ return { result };
30
+ }
31
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/cli/scope.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,kFAAkF;AAElF,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAGtD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkB,MAAM,WAAW,CAAC;AAStD,yGAAyG;AACzG,MAAM,UAAU,cAAc,CAAC,KAAgC,EAAE,OAAuB;IACtF,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7C,IAAI,MAAoD,CAAC;IACzD,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC;QACtC,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACxC,QAAQ,EAAE;YACR,OAAO,EAAE,MAAM,EAAE,YAAY,IAAI,EAAE;YACnC,SAAS,EAAE,MAAM,EAAE,cAAc,IAAI,EAAE;YACvC,WAAW,EAAE,MAAM,EAAE,gBAAgB,IAAI,EAAE;SAC5C;QACD,OAAO;QACP,kBAAkB,EAAE,MAAM,EAAE,UAAU,IAAI,EAAE;KAC7C,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  export declare const HARNESS_PACKAGE: "@sentropic/harness";
2
2
  export type { VerificationRun, VerificationCheck, VerificationCategory, Violation, ViolationSeverity, CheckResult, } from './artifacts/verification-run.js';
3
+ export type { WorkEvent, WorkEventVerb, WorkEventStatus, WorkEventValue, } from './artifacts/work-event.js';
4
+ export { toWorkEvent } from './run/work-event.js';
5
+ export type { WorkEventInput, WorkEventContext } from './run/work-event.js';
3
6
  export type { HarnessProfile } from './profile/profile.js';
4
7
  export { sentropicProfile } from './profile/sentropic.js';
5
8
  export { stubProfile } from './profile/stub.js';
@@ -13,5 +16,7 @@ export { checkScope } from './checks/scope-check.js';
13
16
  export type { ScopeCheckInput } from './checks/scope-check.js';
14
17
  export { toVerificationRun } from './run/emit.js';
15
18
  export type { NamedCheck, VerificationContext } from './run/emit.js';
19
+ export { HARNESS_SKILLS, HOST_SKILL_DIR, isHostId } from './skills/manifest.js';
20
+ export type { SkillEntry, HostId } from './skills/manifest.js';
16
21
  export { runHarnessCli } from './cli/run.js';
17
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe,sBAAgC,CAAC;AAG7D,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,iCAAiC,CAAC;AAGzC,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAClF,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAG1E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe,sBAAgC,CAAC;AAG7D,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,iBAAiB,EACjB,WAAW,GACZ,MAAM,iCAAiC,CAAC;AAGzC,YAAY,EACV,SAAS,EACT,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAClF,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAG1E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChF,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  // Tooling-only: no product-runtime imports (no Drizzle/Hono/Svelte/Mistral), no
4
4
  // `@sentropic/*` deps, and NO track import — harness only EMITS neutral artifacts.
5
5
  export const HARNESS_PACKAGE = '@sentropic/harness';
6
+ export { toWorkEvent } from './run/work-event.js';
6
7
  export { sentropicProfile } from './profile/sentropic.js';
7
8
  export { stubProfile } from './profile/stub.js';
8
9
  // BRANCH.md parser.
@@ -13,6 +14,8 @@ export { classifyPath, matchGlob, globToRegExp } from './scope/scope-boundary.js
13
14
  export { checkBranch } from './checks/branch-check.js';
14
15
  export { checkScope } from './checks/scope-check.js';
15
16
  export { toVerificationRun } from './run/emit.js';
17
+ // Harness skill-pack inventory — the native superpowers-surface replacement.
18
+ export { HARNESS_SKILLS, HOST_SKILL_DIR, isHostId } from './skills/manifest.js';
16
19
  // Pure, arg-based CLI driver (the `harness` bin is a thin wrapper over this).
17
20
  export { runHarnessCli } from './cli/run.js';
18
21
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,gFAAgF;AAChF,mFAAmF;AAEnF,MAAM,CAAC,MAAM,eAAe,GAAG,oBAA6B,CAAC;AAc7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,wBAAwB;AACxB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGlF,uDAAuD;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,8EAA8E;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,gFAAgF;AAChF,mFAAmF;AAEnF,MAAM,CAAC,MAAM,eAAe,GAAG,oBAA6B,CAAC;AAmB7D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,wBAAwB;AACxB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGlF,uDAAuD;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,6EAA6E;AAC7E,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhF,8EAA8E;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { WorkEvent, WorkEventStatus, WorkEventValue, WorkEventVerb } from '../artifacts/work-event.js';
2
+ export interface WorkEventInput {
3
+ verb: WorkEventVerb;
4
+ status: WorkEventStatus;
5
+ subject?: string;
6
+ skill?: string;
7
+ refs?: Record<string, string>;
8
+ detail?: Record<string, WorkEventValue>;
9
+ }
10
+ export interface WorkEventContext {
11
+ runId: string;
12
+ commit: string;
13
+ branch: string;
14
+ env: string;
15
+ runner: string;
16
+ /** ISO-8601 timestamp (injected by the caller — the pure driver passes a placeholder). */
17
+ at: string;
18
+ }
19
+ /**
20
+ * Assemble a NEUTRAL `WorkEvent` from a method/branch act. harness EMITS this artifact and never
21
+ * writes into `@sentropic/track` — a track-side adapter ingests it (no track import here). Pure and
22
+ * deterministic: `subject`/`skill` are dropped when absent so the JSON stays minimal and stable.
23
+ */
24
+ export declare function toWorkEvent(input: WorkEventInput, ctx: WorkEventContext): WorkEvent;
25
+ //# sourceMappingURL=work-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-event.d.ts","sourceRoot":"","sources":["../../src/run/work-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,cAAc,EACd,aAAa,EACd,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,gBAAgB,GAAG,SAAS,CAkBnF"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Assemble a NEUTRAL `WorkEvent` from a method/branch act. harness EMITS this artifact and never
3
+ * writes into `@sentropic/track` — a track-side adapter ingests it (no track import here). Pure and
4
+ * deterministic: `subject`/`skill` are dropped when absent so the JSON stays minimal and stable.
5
+ */
6
+ export function toWorkEvent(input, ctx) {
7
+ const event = {
8
+ schemaVersion: 1,
9
+ kind: 'work-event',
10
+ verb: input.verb,
11
+ status: input.status,
12
+ refs: input.refs ?? {},
13
+ detail: input.detail ?? {},
14
+ runId: ctx.runId,
15
+ commit: ctx.commit,
16
+ branch: ctx.branch,
17
+ env: ctx.env,
18
+ runner: ctx.runner,
19
+ at: ctx.at,
20
+ };
21
+ if (input.subject !== undefined)
22
+ event.subject = input.subject;
23
+ if (input.skill !== undefined)
24
+ event.skill = input.skill;
25
+ return event;
26
+ }
27
+ //# sourceMappingURL=work-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-event.js","sourceRoot":"","sources":["../../src/run/work-event.ts"],"names":[],"mappings":"AA0BA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAqB,EAAE,GAAqB;IACtE,MAAM,KAAK,GAAc;QACvB,aAAa,EAAE,CAAC;QAChB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;QACtB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;QAC1B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,EAAE,EAAE,GAAG,CAAC,EAAE;KACX,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC/D,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACzD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type HostId = 'claude' | 'codex' | 'gemini';
2
+ export interface SkillEntry {
3
+ /** Skill id; loaded by a host under the `harness/<name>` namespace. */
4
+ name: string;
5
+ /** One-line purpose. */
6
+ summary: string;
7
+ /** The superpowers skill this supersedes (drives the supersede directive), if any. */
8
+ supersedes?: string;
9
+ }
10
+ export declare const HARNESS_SKILLS: SkillEntry[];
11
+ /** Host → the skills directory `skills install` copies the pack into. */
12
+ export declare const HOST_SKILL_DIR: Record<HostId, string>;
13
+ export declare function isHostId(s: string | undefined): s is HostId;
14
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/skills/manifest.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,UAAU,EAQtC,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIjD,CAAC;AAEF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,CAAC,IAAI,MAAM,CAE3D"}
@@ -0,0 +1,25 @@
1
+ // Canonical inventory of the harness skill pack — the NATIVE superpowers-surface replacement.
2
+ //
3
+ // `harness skills install --host <h>` reports this plan; the pack ships in the npm tarball under
4
+ // `skills/<name>/SKILL.md` (see `package.json` `files`). The host loads each as `harness/<name>`.
5
+ // `using-harness` MUST be loaded first — it carries the supersede directive that makes `harness/*`
6
+ // take precedence over the superpowers skills it replaces.
7
+ export const HARNESS_SKILLS = [
8
+ { name: 'using-harness', summary: 'index + supersede directive (load FIRST)', supersedes: 'using-superpowers' },
9
+ { name: 'brainstorm', summary: 'spec-ladder STUDY→VOL→EVOL + ≥2-peer review + batched decisions', supersedes: 'brainstorming' },
10
+ { name: 'test', summary: 'test-pyramid + scoped-test loop (not "tdd")', supersedes: 'test-driven-development' },
11
+ { name: 'debug', summary: 'generic root-cause loop', supersedes: 'systematic-debugging' },
12
+ { name: 'review', summary: '≥2-peer consensus review', supersedes: 'requesting-code-review' },
13
+ { name: 'plan', summary: 'spec-ladder + BRANCH.md lots; completes with track', supersedes: 'writing-plans' },
14
+ { name: 'adopt', summary: 'adapt the harness method to ANY repo (profile)' },
15
+ ];
16
+ /** Host → the skills directory `skills install` copies the pack into. */
17
+ export const HOST_SKILL_DIR = {
18
+ claude: '.claude/skills',
19
+ codex: '.codex/skills',
20
+ gemini: '.gemini/skills',
21
+ };
22
+ export function isHostId(s) {
23
+ return s === 'claude' || s === 'codex' || s === 'gemini';
24
+ }
25
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/skills/manifest.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,EAAE;AACF,iGAAiG;AACjG,kGAAkG;AAClG,mGAAmG;AACnG,2DAA2D;AAa3D,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,0CAA0C,EAAE,UAAU,EAAE,mBAAmB,EAAE;IAC/G,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,iEAAiE,EAAE,UAAU,EAAE,eAAe,EAAE;IAC/H,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,6CAA6C,EAAE,UAAU,EAAE,yBAAyB,EAAE;IAC/G,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,UAAU,EAAE,sBAAsB,EAAE;IACzF,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,0BAA0B,EAAE,UAAU,EAAE,wBAAwB,EAAE;IAC7F,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oDAAoD,EAAE,UAAU,EAAE,eAAe,EAAE;IAC5G,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,gDAAgD,EAAE;CAC7E,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAA2B;IACpD,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,gBAAgB;CACzB,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,CAAqB;IAC5C,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,QAAQ,CAAC;AAC3D,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sentropic/harness",
3
- "version": "0.1.1",
4
- "description": "Neutral, host-agnostic code-work / PR-workflow tooling for AI dev: branch/scope/lot/verify discipline. Tooling-only, zero product-runtime deps. (BR-42h)",
3
+ "version": "0.2.0",
4
+ "description": "Neutral, host-agnostic code-work / PR-workflow tooling for AI dev: a homogeneous `harness <verb>` method layer (branch/scope/verify/test/debug/review/brainstorm/plan), the native superpowers replacement. Tooling-only, zero product-runtime deps. (BR-42h)",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -22,6 +22,7 @@
22
22
  },
23
23
  "files": [
24
24
  "dist",
25
+ "skills",
25
26
  "README.md",
26
27
  "LICENSE"
27
28
  ],
@@ -33,6 +34,6 @@
33
34
  "devDependencies": {
34
35
  "@types/node": "^20.12.0",
35
36
  "typescript": "5.4.5",
36
- "vitest": "4.0.18"
37
+ "vitest": "4.1.0"
37
38
  }
38
39
  }
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: adopt
3
+ description: Use when bringing the harness method to a NEW or non-sentropic repo — maps the repo's conventions into a harness profile so the same scope/branch/verify kernel applies anywhere.
4
+ ---
5
+
6
+ # harness/adopt
7
+
8
+ Native repo-onboarding. The harness engine (parser, C1/C2 checks, verify) is generic; all repo-specific
9
+ policy is DATA in a profile. `adopt` maps a foreign repo onto that SPI so the method runs unchanged.
10
+
11
+ ## Steps
12
+
13
+ 1. **Scaffold** — `harness init [--profile sentropic|stub] [--json]` prints a profile descriptor. Save it
14
+ as `harness.profile.json` at the repo root and edit it to fit:
15
+ - `forbiddenPathDefaults` — globs forbidden unless a BRANCH.md explicitly Allows them.
16
+ - `exceptionIdPattern` — the grammar of a valid scope-exception id (e.g. `^BR\d+-EX\d+$`).
17
+ - `conditionalRequiresException` — whether a Conditional path needs a matching declared exception.
18
+ - `branchMatch` — `exact` or `prefix` for the C1 branch check.
19
+ 2. **Map the repo's reality** — translate the repo's conventions, not sentropic's: which paths are
20
+ off-limits, what its BRANCH.md grammar is (or whether one must be introduced), the command runner
21
+ (`make` vs `npm`/`nx`), and the environment data-lifecycle (which envs are disposable vs protected).
22
+ 3. **Audit** — `harness audit --staged-files "<changed files>" --branch-md <path> --json` diffs the repo
23
+ against the active profile and emits a `VerificationRun (static)` listing drift: forbidden touches,
24
+ undeclared (unknown) paths, missing scope declaration.
25
+ 4. **Wire** — add a `scope-check`/`verify` step to the repo's pre-commit or CI using the profile, so the
26
+ method is enforced, not just documented.
27
+
28
+ ## Principle
29
+
30
+ A second `stub` profile diverging from `sentropic` on a checked dimension is the proof-of-genericity:
31
+ the same kernel yields different, correct verdicts per profile. Adoption succeeds when a third repo can
32
+ declare its OWN profile and the unchanged engine governs it.
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: brainstorm
3
+ description: Use before any creative/design work (a feature, a package, an evolution) — explores intent and design via the spec-ladder with multi-peer adversarial review BEFORE implementation.
4
+ ---
5
+
6
+ # harness/brainstorm
7
+
8
+ Native sentropic ideation. Stronger than a single-pass brainstorm: it climbs the **spec-ladder** and
9
+ gates each design step with **≥2 independent adversarial peers** and **batched** owner decisions.
10
+
11
+ Open the act: `harness brainstorm "<topic>" [--peers <n>] [--ladder study|vol|evol]` (records a WorkEvent).
12
+
13
+ ## The spec-ladder
14
+
15
+ Pick the rung that matches the uncertainty, write the artifact under `spec/`:
16
+
17
+ - **STUDY** (`SPEC_STUDY_<TOPIC>.md`) — open question, options, trade-offs. No commitment yet.
18
+ - **VOL** (volition) — the chosen direction + rationale, still reversible.
19
+ - **EVOL** (`SPEC_EVOL_<TOPIC>.md`) — the committed design with numbered decisions (D1…Dn) ready to plan.
20
+
21
+ Don't skip rungs for a genuinely open problem; don't over-ceremony a reversible one.
22
+
23
+ ## Multi-peer adversarial review (the differentiator)
24
+
25
+ Before presenting decisions, get **≥2 independent reviews from distinct angles** (e.g. Opus 4.8 + Codex
26
+ 5.5-xhigh, or distinct lenses: correctness / risk / user-value). Reconcile divergences explicitly — a
27
+ lone reviewer rationalises; a panel surfaces failure modes. Reversible calls: decide solo. Blocking /
28
+ irreversible calls: escalate.
29
+
30
+ ## Batched decisions
31
+
32
+ Present owner decisions as a **clean full dossier (never a delta)**, THEN ask in **lots of ≤4** questions.
33
+ Each question carries its own context inline (source + stakes + consequence) — an id like "D5" alone
34
+ carries no meaning. Once answered, treat all answers final; do re-examination in prose, don't re-poll.
35
+
36
+ ## Done
37
+
38
+ A ladder artifact exists, peers reconciled, decisions captured. Hand off to `harness/plan` to turn the
39
+ EVOL decisions into BRANCH.md lots.
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: debug
3
+ description: Use on any bug, test failure, or unexpected behaviour BEFORE proposing a fix — runs the generic evidence-first root-cause loop.
4
+ ---
5
+
6
+ # harness/debug
7
+
8
+ Native sentropic debugging. Open it with `harness debug "<symptom>"` (records a WorkEvent), then run the
9
+ loop. No fix is proposed before the root cause is proven by evidence.
10
+
11
+ ## The loop
12
+
13
+ 1. **Reproduce** — a deterministic, minimal repro. If you can't reproduce it, you can't fix it.
14
+ 2. **Evidence** — gather facts with the tools, never assume: `make logs-<service>`, `make db-query
15
+ QUERY="…"`, container state (`make ps`), `grep`/`diff`. Read the actual error, the actual state.
16
+ 3. **One hypothesis** — the single most-likely cause that the evidence supports. Write it down.
17
+ 4. **One fix** — the smallest change that addresses THAT cause. No shotgun edits, no "while I'm here".
18
+ 5. **Re-observe** — rerun the repro. Confirm the symptom is gone AND the evidence changed as predicted.
19
+ 6. **Regression test** — promote the repro into a test (`harness/test`) so it can't silently return.
20
+
21
+ ## Rules
22
+
23
+ - No "probably" / "maybe" / "should be" — verify with a tool before asserting. A claim without evidence
24
+ is a guess.
25
+ - Change ONE thing at a time; if the symptom persists, revert it before trying the next.
26
+ - A failing assertion is data, not noise — read the diff, don't loosen the assertion.
27
+ - Live surfaces (UI/stream/API/extension) have a dev-lane bootstrap (Playwright/probe targets); use it to
28
+ observe the real behaviour rather than reasoning in the abstract.
29
+
30
+ ## Done
31
+
32
+ Root cause named + evidenced, minimal fix in place, repro green as a regression test, no collateral
33
+ change. Hand verification to `harness verify`.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: plan
3
+ description: Use when you have a spec/decisions and need an executable plan — writes a lot-based BRANCH.md from the template and completes with track for realization state.
4
+ ---
5
+
6
+ # harness/plan
7
+
8
+ Native sentropic planning. Turns an EVOL spec's decisions into an executable, scoped `BRANCH.md`. Open it
9
+ with `harness plan "<spec>" [--lots <n>]` (records a WorkEvent; harness writes BRANCH.md, then
10
+ `track branch import` indexes it).
11
+
12
+ ## Write BRANCH.md from the template
13
+
14
+ Use `plan/BRANCH_TEMPLATE.md` strictly — checkboxes only, no prose, no `###`. First iteration must be
15
+ detailed:
16
+
17
+ - **Objective** + **Scope / Guardrails**.
18
+ - **Branch Scope Boundaries**: `Allowed` / `Forbidden` / `Conditional` paths (default forbidden: `Makefile`,
19
+ `docker-compose*.yml`, `.cursor/rules/**`). Exceptions via `BRxx-EXn` (reason + impact + rollback).
20
+ - **Lot-based plan**: each lot is one logical change with a file-level test list and a lot gate.
21
+ - **Feedback Loop** for blockers/decisions.
22
+
23
+ ## Lots & commit discipline
24
+
25
+ - One logical change per lot/commit; max ~10–15 files and **under 150 lines** per commit.
26
+ - Selective staging (`git add <files>` — never `git add .`); commit via `make commit MSG="type: …"`.
27
+ - Update `BRANCH.md` checkboxes WITHIN each commit.
28
+ - Multi-need work → multi-branch with a root `PLAN.md` (waves ≤4 orthogonal branches).
29
+
30
+ ## Completes with track
31
+
32
+ harness OWNS the BRANCH.md (the master plan artifact) and EMITS `WorkEvent`s; **track** ingests them and
33
+ owns the realization state — Items, links, Decisions, acceptance, and the AWAITED / DROPPED / DONE / TO-DO
34
+ projections. Don't duplicate status in BRANCH.md prose — let track project it. Execute lots in order
35
+ autonomously; only interrupt for a real fork or blocker.
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: review
3
+ description: Use when completing a feature, a design step, or before merging — runs a ≥2-peer consensus review and reconciles the findings, instead of a single rubber-stamp pass.
4
+ ---
5
+
6
+ # harness/review
7
+
8
+ Native sentropic code/design review. Stronger than a single review: **≥2 independent peers**, distinct
9
+ lenses, reconciled. Open it with `harness review "<target>" --consensus [--peers <n>]` (records a
10
+ WorkEvent).
11
+
12
+ ## Consensus protocol
13
+
14
+ 1. **Dispatch ≥2 independent peers** on the SAME diff/design — ideally different models or angles
15
+ (e.g. Opus 4.8 + Codex 5.5-xhigh), each blind to the others.
16
+ 2. **Distinct lenses** when a finding can fail in more than one way: correctness · security · performance ·
17
+ does-it-actually-reproduce. Diversity catches what redundancy can't.
18
+ 3. **Refute by default** — each peer tries to REFUTE the change / a claimed finding. A finding survives
19
+ only if it withstands the skeptics; a kill needs a majority.
20
+ 4. **Reconcile** — merge findings, surface disagreements explicitly, classify accept / reject / defer with
21
+ a one-line rationale each. Don't average; adjudicate.
22
+
23
+ ## Receiving review (technical rigor, not performative agreement)
24
+
25
+ Before implementing a suggestion, verify it. If feedback is unclear or technically questionable, push back
26
+ with evidence rather than complying blindly. Apply what's correct; refute what's wrong; ask when genuinely
27
+ ambiguous.
28
+
29
+ ## Severity & gate
30
+
31
+ Findings that gate a lot escalate to a `VerificationRun` (`harness verify --category static`). Narrative
32
+ findings stay a `WorkEvent`. Blocking findings must be resolved before merge; non-blocking are logged in
33
+ `BRANCH.md` `## Feedback Loop` with owner + status.
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: test
3
+ description: Use when adding or evolving tests for a feature/bugfix — applies the sentropic test-pyramid, scoped-test loop, environment isolation, and AI-flaky policy.
4
+ ---
5
+
6
+ # harness/test
7
+
8
+ Native sentropic testing discipline (NOT "tdd" ritual — the act is `test`). Open it with
9
+ `harness test [<scope>] [--category unit|integration|e2e] [--watch]` (records a WorkEvent), then follow
10
+ the loop.
11
+
12
+ ## Pyramid
13
+
14
+ 70% unit · 20% integration · 10% e2e. Test behaviour, not implementation — query by user-visible
15
+ elements (text/role/label) over test ids. Names: "should <behaviour> when <condition>".
16
+
17
+ ## Scoped-test loop (while developing)
18
+
19
+ Run ONLY the test under evolution, on a dedicated test ENV — never `dev`:
20
+
21
+ - API: `make test-api-<suite> SCOPE=tests/<file>.spec.ts ENV=test-<slug>`
22
+ - UI: `make test-ui SCOPE=tests/<file>.spec.ts ENV=test-<slug>`
23
+ - E2E: `make test-e2e E2E_SPEC=tests/<file>.spec.ts API_PORT=… UI_PORT=… MAILDEV_UI_PORT=… ENV=e2e-<slug>`
24
+
25
+ Full gates only at end of lot/branch: `make test-api`, `make test-ui`, `make clean test-e2e`.
26
+
27
+ ## Environment isolation (MANDATORY)
28
+
29
+ - NEVER run test campaigns on `ENV=dev` — afterEach hooks purge real data.
30
+ - Branch tests live in the isolated worktree on `ENV=test-<slug>` / `ENV=e2e-<slug>`; `ENV` is the LAST
31
+ make argument.
32
+ - NEVER add timeouts to make a flaky e2e pass — a timeout failure is a real bug (bad selector, race,
33
+ regression). UI waits are <2s except AI generation.
34
+
35
+ ## AI-flaky allowlist (non-blocking)
36
+
37
+ Only accept non-systematic provider/network/model nondeterminism, and only with ≥1 success on the same
38
+ commit + command. Record the exact command + failing file + failure signature in `BRANCH.md` and get
39
+ explicit user sign-off before merge. Everything else is blocking.
40
+
41
+ ## CI is authority
42
+
43
+ CI was green on main → any branch failure IS a branch problem; never claim "pre-existing". Decide:
44
+ evolution (adapt the test) or regression (fix the code). Local-green / CI-red → trust CI.