easy-coding-harness 1.1.0-beta.1 → 1.1.0-beta.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.
@@ -11,14 +11,12 @@ domain:
11
11
  tags:
12
12
  - "{keyword}"
13
13
  related_files:
14
- - "{key file or module}"
15
- commit: none
16
- verification: passed | partial | not_run
14
+ - "{entrypoint or file useful for applying this knowledge}"
17
15
  memory_value: business | technical | both | none
18
16
  target_long: BUSINESS | TECHNICAL | BOTH | NONE
19
17
  ---
20
18
 
21
- # Short Memory Template
19
+ # {Reusable knowledge topic}
22
20
 
23
21
  > This template defines the format for files under `.easy-coding/memory/short/`.
24
22
  > File naming convention: `{memory_id}_{YYYYMMDD}_{smart_name}.md`
@@ -26,57 +24,32 @@ target_long: BUSINESS | TECHNICAL | BOTH | NONE
26
24
  > both the filename prefix and this frontmatter `id`. The UUIDv7 id is safe for concurrent agents.
27
25
  > Keep `smart_name` as the readable summary suffix.
28
26
  > `source_task` must exactly match the current workflow task id from `task.json`.
29
- > Short memories are immutable after creation they serve as a sliding window of recent
30
- > details and a buffer for long-term distillation candidates.
31
- > When short memories reach the threshold (default 10), the newest 5 are kept as recent
27
+ > Short memories are immutable and directly useful for later development before distillation.
28
+ > When short memories exceed the threshold (default 10), the newest 5 are kept as recent
32
29
  > context; older entries are distillation candidates for long-term memory.
33
30
  > Sorting: by frontmatter `date` ascending, then by frontmatter `id`, then by filename. Legacy
34
31
  > `SM-YYYYMMDD-NNN` ids sort before UUIDv7 ids on the same date for upgrade compatibility.
35
32
 
36
- ## Task Summary
33
+ ## Knowledge Summary
37
34
 
38
- - Goal: {the actual problem solved}
39
- - Scope: {modules, pages, interfaces, or files involved}
40
- - Result: {completed / partially completed / not completed, with reasons}
41
- - Key Constraints: {encoding, compatibility, interface, spec, or user-specified constraints; "none" if none}
42
- - Workflow Mode: {frozen mode and why it was selected or escalated}
35
+ {When this knowledge is useful and the main conclusion a future developer should find.}
43
36
 
44
- ## Execution Evidence
37
+ ## Reusable Knowledge
45
38
 
46
- | Type | Content |
47
- |---|---|
48
- | Key Files | {file or module list; "none" if none} |
49
- | Verification Commands | {test / build / lint commands and results; explain if not run} |
50
- | Manual Acceptance | {key behaviors checked; "none" if none} |
51
- | Commit Info | {commit hash; "none" if not committed} |
39
+ {Write only confirmed facts with future reuse value. Use natural paragraphs or bullets; omit
40
+ inapplicable categories rather than filling a checklist. Useful material includes business rules,
41
+ design reasons, change entrypoints, compatibility boundaries, and failure causes with their fixes.
42
+ Add applicable conditions, necessary reasons and exact symbols where they guide the next change.
43
+ Do not promote a task-specific restriction into a permanent project rule.}
52
44
 
53
- ## Business Memory Candidates
45
+ ## Sources
54
46
 
55
- > Only record business facts with future reuse value. Write "none" if none.
47
+ - {Relevant dev-spec section, implementation result or Review finding; reference instead of copying.}
48
+ - {Related memory or existing knowledge topic, only when useful.}
56
49
 
57
- - Concepts / Field Semantics: {concepts, fields, enums, state meanings}
58
- - Workflows / State Transitions: {chain steps, pre/post conditions, exception branches}
59
- - Business Rules / Compatibility: {admission criteria, decision basis, grayscale or legacy reasons}
60
- - Upstream/Downstream Contracts: {producers, consumers, interface or message fields}
61
- - Business Troubleshooting: {common misdiagnosis, priority check paths}
62
-
63
- ## Technical Memory Candidates
64
-
65
- > Only record engineering facts with future reuse value. Write "none" if none.
66
-
67
- - Architecture / Interface Decisions: {module boundaries, dependency direction, interface contracts}
68
- - Engineering Rules / Workflows: {coding, commit, release, installation, directory boundaries}
69
- - Implementation Patterns / Reusable Approaches: {recommended approaches, fallback strategies, compatibility patterns}
70
- - Pitfalls / Fix Strategies: {root cause, fix approach, verification method}
71
- - Verification Experience: {test commands, environment constraints, acceptance paths}
72
-
73
- ## Non-Distillation Content
74
-
75
- > Content that should NOT enter long-term memory, with reasons — prevents accidental absorption of noise.
76
-
77
- - {routine file lists / temp logs / one-time data / non-reusable implementation details; "none" if none}
78
-
79
- ## Related Memories
80
-
81
- - Predecessor: {related short memory id, long-term topic, or "none"}
82
- - Successor: {follow-up task; "none" if none}
50
+ > Authoring guidance, not memory content: remove these instructions and unused placeholders.
51
+ > If nothing new is reusable, set `memory_value: none` and `target_long: NONE`, give a brief reason
52
+ > in Knowledge Summary and retain Sources; omit Reusable Knowledge rather than inventing lessons.
53
+ > Leave task status, approvals, fingerprints, test statistics and temporary logs in task records.
54
+ > Keep a verification command only when it teaches a reusable method or environment requirement.
55
+ > Do not include an acceptance report or a list of excluded noise.
@@ -40,6 +40,24 @@ def memo(key, compute):
40
40
  return cache[key]
41
41
 
42
42
 
43
+ def invalidate_memo(key):
44
+ cache = _operation.get()
45
+ if cache is not None:
46
+ cache.pop(key, None)
47
+
48
+
49
+ def cached_memo(key):
50
+ cache = _operation.get()
51
+ return cache.get(key) if cache is not None else None
52
+
53
+
54
+ def command_identity(command):
55
+ # Shell 展开和重定向受引号影响;只归一化普通 argv 命令,避免错误复用。
56
+ if re.search(r"[\$`\\\n;|&<>*?\[\]{}~#]", command):
57
+ return command
58
+ return tuple(shlex.split(command))
59
+
60
+
43
61
  def digest(value):
44
62
  return hashlib.sha256(json.dumps(value, sort_keys=True, ensure_ascii=False,
45
63
  separators=(",", ":")).encode()).hexdigest()