@dzhechkov/harness-core 0.7.4 → 0.7.6

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 (82) hide show
  1. package/.dz-manifest.json +141 -61
  2. package/README.md +38 -1
  3. package/dist/agentdb-index.d.ts.map +1 -1
  4. package/dist/agentdb-index.js +26 -2
  5. package/dist/agentdb-index.js.map +1 -1
  6. package/dist/amendment-trace.d.ts.map +1 -1
  7. package/dist/amendment-trace.js +6 -1
  8. package/dist/amendment-trace.js.map +1 -1
  9. package/dist/cadence.d.ts +66 -0
  10. package/dist/cadence.d.ts.map +1 -0
  11. package/dist/cadence.js +222 -0
  12. package/dist/cadence.js.map +1 -0
  13. package/dist/feature-adr-routing.d.ts.map +1 -1
  14. package/dist/feature-adr-routing.js +7 -2
  15. package/dist/feature-adr-routing.js.map +1 -1
  16. package/dist/index.d.ts +8 -2
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +6 -2
  19. package/dist/index.js.map +1 -1
  20. package/dist/loop-blobs.generated.js +2 -2
  21. package/dist/loop-blobs.generated.js.map +1 -1
  22. package/dist/operations.d.ts.map +1 -1
  23. package/dist/operations.js +53 -18
  24. package/dist/operations.js.map +1 -1
  25. package/dist/provenance.d.ts +6 -0
  26. package/dist/provenance.d.ts.map +1 -1
  27. package/dist/provenance.js +22 -1
  28. package/dist/provenance.js.map +1 -1
  29. package/dist/publish.d.ts +31 -0
  30. package/dist/publish.d.ts.map +1 -1
  31. package/dist/publish.js +78 -0
  32. package/dist/publish.js.map +1 -1
  33. package/dist/recall-hook-policy.d.ts +3 -1
  34. package/dist/recall-hook-policy.d.ts.map +1 -1
  35. package/dist/recall-hook-policy.js +15 -2
  36. package/dist/recall-hook-policy.js.map +1 -1
  37. package/dist/recall-usage.d.ts +15 -0
  38. package/dist/recall-usage.d.ts.map +1 -1
  39. package/dist/recall-usage.js +51 -1
  40. package/dist/recall-usage.js.map +1 -1
  41. package/dist/score.d.ts.map +1 -1
  42. package/dist/score.js +38 -4
  43. package/dist/score.js.map +1 -1
  44. package/dist/skill-drift.d.ts +8 -2
  45. package/dist/skill-drift.d.ts.map +1 -1
  46. package/dist/skill-drift.js +60 -11
  47. package/dist/skill-drift.js.map +1 -1
  48. package/dist/skill-install-roots.d.ts +100 -0
  49. package/dist/skill-install-roots.d.ts.map +1 -0
  50. package/dist/skill-install-roots.js +116 -0
  51. package/dist/skill-install-roots.js.map +1 -0
  52. package/dist/tg-post.d.ts +76 -0
  53. package/dist/tg-post.d.ts.map +1 -0
  54. package/dist/tg-post.js +158 -0
  55. package/dist/tg-post.js.map +1 -0
  56. package/dist/usage.d.ts +31 -0
  57. package/dist/usage.d.ts.map +1 -1
  58. package/dist/usage.js +108 -21
  59. package/dist/usage.js.map +1 -1
  60. package/dist/writer-quiescence.d.ts +42 -0
  61. package/dist/writer-quiescence.d.ts.map +1 -0
  62. package/dist/writer-quiescence.js +82 -0
  63. package/dist/writer-quiescence.js.map +1 -0
  64. package/package.json +13 -13
  65. package/sbom.json +260 -60
  66. package/src/agentdb-index.ts +26 -2
  67. package/src/amendment-trace.ts +6 -1
  68. package/src/cadence.ts +227 -0
  69. package/src/feature-adr-routing.ts +7 -2
  70. package/src/index.ts +8 -1
  71. package/src/loop-blobs.generated.ts +2 -2
  72. package/src/operations.ts +52 -19
  73. package/src/provenance.ts +23 -1
  74. package/src/publish.ts +98 -0
  75. package/src/recall-hook-policy.ts +15 -2
  76. package/src/recall-usage.ts +44 -1
  77. package/src/score.ts +30 -4
  78. package/src/skill-drift.ts +70 -13
  79. package/src/skill-install-roots.ts +119 -0
  80. package/src/tg-post.ts +192 -0
  81. package/src/usage.ts +132 -17
  82. package/src/writer-quiescence.ts +95 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Writer-quiescence probe for Step 8 — feature qe-writer-quiescence (backlog 700b46a4).
3
+ *
4
+ * MEASURED (crossrt-1, 2026-08-18): Step-8 graded a MOVING tree — a background worker wrote at
5
+ * 19:25, 19:32 and 19:46, AFTER the verdict, its last write clobbering a file the same round had
6
+ * just written. The reviewer hand-waited six consecutive 30-second zero-write windows and
7
+ * re-measured everything. This module is that wait, as a machine: the same idea the publish gate
8
+ * already enforces («не публикуй, пока рой жив»), applied to grading.
9
+ *
10
+ * A BELT, not the root: mutual exclusion of writers (worktree isolation) is item 9520e506. The
11
+ * probe therefore NEVER blocks a run — a moving tree downgrades the verdict's standing loudly
12
+ * instead of stopping the pipeline.
13
+ *
14
+ * PURE: the shell script is GENERATED here and executed by a workflow agent (the workflow sandbox
15
+ * has no child_process — the agent is the shell, same as the landing barrier); the answer is
16
+ * PARSED here, parse-never-synthesize: an empty or malformed probe is 'inconclusive', never
17
+ * 'quiet'.
18
+ */
19
+ export const WQ_WINDOW_SECONDS = 20;
20
+ export const WQ_MAX_WINDOWS = 9;
21
+ export const WQ_REQUIRED_QUIET = 3;
22
+ /**
23
+ * The probe script a workflow agent runs verbatim. Polls the declared targets PLUS the feature
24
+ * dir (FR-4: the feature's own artifacts are exactly the surface crossrt-1 saw clobbered) in
25
+ * fixed windows; prints one `WQ-WINDOW <n> changed=<count>` line per window and exits early after
26
+ * `requiredQuiet` consecutive zeros. `find -newermt '-<w+5> seconds'` widens the lookback slightly
27
+ * past the sleep so a write on the window boundary cannot fall between two polls.
28
+ */
29
+ export function quiescenceProbeScript(paths, opts) {
30
+ const w = opts?.windowSeconds ?? WQ_WINDOW_SECONDS;
31
+ const max = opts?.maxWindows ?? WQ_MAX_WINDOWS;
32
+ const need = opts?.requiredQuiet ?? WQ_REQUIRED_QUIET;
33
+ const targets = paths
34
+ .map((p) => String(p).trim())
35
+ .filter((p) => p !== '' && !p.startsWith('-') && !p.includes("'"))
36
+ .map((p) => `'${p.replace(/'/g, '')}'`)
37
+ .join(' ');
38
+ const lookback = w + 5;
39
+ // Cross-family review (round 1, D): find errors — a missing/typo'd target, a permission failure —
40
+ // used to feed ZERO to `wc -l`, so a probe that could not look reported quiet. Errors now print
41
+ // `changed=ERR` and the parser refuses to let an ERR window feed a quiet streak.
42
+ return (`quiet=0; n=0; while [ $n -lt ${max} ]; do n=$((n+1)); sleep ${w}; ` +
43
+ `out=$(find ${targets} -type f -newermt '-${lookback} seconds' 2>&1 >/tmp/wq-list.$$); st=$?; ` +
44
+ `if [ $st -ne 0 ] || [ -n "$out" ]; then c=ERR; else c=$(wc -l < /tmp/wq-list.$$); fi; rm -f /tmp/wq-list.$$; ` +
45
+ `echo "WQ-WINDOW $n changed=$c"; ` +
46
+ `if [ "$c" = "0" ]; then quiet=$((quiet+1)); if [ $quiet -ge ${need} ]; then echo "WQ-DONE quiet"; exit 0; fi; else quiet=0; fi; ` +
47
+ `done; echo "WQ-DONE budget"`);
48
+ }
49
+ /** Parse the probe transcript into a verdict. Empty/malformed ⇒ inconclusive, never quiet. */
50
+ export function decideWriterQuiescence(probeText, requiredQuiet = WQ_REQUIRED_QUIET) {
51
+ const text = probeText === null || probeText === undefined ? '' : String(probeText);
52
+ // -1 encodes an ERR window (find could not look): it can never join a quiet streak, and its
53
+ // presence degrades a no-streak outcome to 'inconclusive' — an instrument that failed to observe
54
+ // must not testify to movement either.
55
+ const windows = [];
56
+ for (const line of text.split(/\r?\n/)) {
57
+ const m = /WQ-WINDOW\s+\d+\s+changed=(\d+|ERR)/.exec(line);
58
+ if (m)
59
+ windows.push(m[1] === 'ERR' ? -1 : Number(m[1]));
60
+ }
61
+ if (windows.length === 0) {
62
+ return { verdict: 'inconclusive', windows, note: 'quiescence probe returned no windows — grading standing NOT established (probe failure is never quiet)' };
63
+ }
64
+ let streak = 0;
65
+ for (const c of windows) {
66
+ streak = c === 0 ? streak + 1 : 0;
67
+ if (streak >= requiredQuiet) {
68
+ // The claim is exactly what was measured (cross-family review): mtime evidence of no recent
69
+ // writes — never a writer-lifecycle guarantee. The root guarantee is worktree isolation.
70
+ return { verdict: 'quiet', windows, note: `no observed writes in ${requiredQuiet} consecutive windows (mtime evidence only — not a writer-lifecycle guarantee)` };
71
+ }
72
+ }
73
+ if (windows.some((c) => c < 0)) {
74
+ return { verdict: 'inconclusive', windows, note: 'quiescence probe could not observe every window (find errored) — grading standing NOT established' };
75
+ }
76
+ return {
77
+ verdict: 'moving',
78
+ windows,
79
+ note: `tree is MOVING: no ${requiredQuiet} consecutive quiet windows within budget (per-window changed counts: ${windows.join(',')}) — the verdict below was graded on a moving tree and must say so`,
80
+ };
81
+ }
82
+ //# sourceMappingURL=writer-quiescence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer-quiescence.js","sourceRoot":"","sources":["../src/writer-quiescence.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/harness-core",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Shared harness logic - skill loading, additive apply, and the init/sync/verify/doctor operations.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,20 +27,20 @@
27
27
  "sbom.json"
28
28
  ],
29
29
  "dependencies": {
30
- "@dzhechkov/adapter-claude": "^0.2.0",
31
- "@dzhechkov/adapter-codex": "^0.2.0",
32
- "@dzhechkov/adapter-hermes": "^0.2.0",
33
- "@dzhechkov/adapter-openclaude": "^0.1.0",
34
- "@dzhechkov/adapter-opencode": "^0.2.0",
35
30
  "proper-lockfile": "^4.1.2",
36
31
  "yaml": "^2.0.0",
37
- "@dzhechkov/adapter-agents-md": "0.1.2",
38
- "@dzhechkov/adapter-copilot": "0.1.2",
39
- "@dzhechkov/adapter-gemini": "0.1.2",
40
- "@dzhechkov/adapter-cursor": "0.1.2",
41
- "@dzhechkov/adapter-windsurf": "0.1.2",
42
- "@dzhechkov/core": "0.2.16",
43
- "@dzhechkov/memory": "0.2.14"
32
+ "@dzhechkov/adapter-agents-md": "0.1.3",
33
+ "@dzhechkov/adapter-codex": "^0.2.2",
34
+ "@dzhechkov/adapter-cursor": "0.1.3",
35
+ "@dzhechkov/adapter-copilot": "0.1.3",
36
+ "@dzhechkov/adapter-gemini": "0.1.3",
37
+ "@dzhechkov/adapter-openclaude": "^0.1.2",
38
+ "@dzhechkov/adapter-claude": "^0.2.2",
39
+ "@dzhechkov/adapter-hermes": "^0.2.2",
40
+ "@dzhechkov/adapter-opencode": "^0.2.2",
41
+ "@dzhechkov/core": "0.2.17",
42
+ "@dzhechkov/adapter-windsurf": "0.1.3",
43
+ "@dzhechkov/memory": "0.2.15"
44
44
  },
45
45
  "peerDependenciesMeta": {
46
46
  "@ruvector/rvf": {