@antoneeo/agentic-sdlc-skill 1.51.0 → 1.52.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.
- package/CHANGELOG.md +28 -0
- package/README.md +7 -15
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/skills/agentic-sdlc-skill/ENFORCEMENT.md +10 -0
- package/skills/agentic-sdlc-skill/SKILL.md +2 -2
- package/skills/agentic-sdlc-skill/coordination.md +68 -9
- package/skills/agentic-sdlc-skill/scripts/sdlc_core.py +60 -3
- package/skills/agentic-sdlc-skill/templates.md +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
Tutte le modifiche significative a questa skill saranno documentate in questo file.
|
|
4
4
|
|
|
5
|
+
## [1.52.0] - 2026-11-01
|
|
6
|
+
|
|
7
|
+
### What's new
|
|
8
|
+
|
|
9
|
+
**A session that writes only documents no longer costs you a branch.** When you run several sessions with a coordinator, a session working only on design documents can work in the folder the others already use, instead of a worktree of its own. It writes only its own unit's files, runs no git command that changes the folder, and leaves index regeneration and its closure steps to the coordinator, so you no longer merge one branch per documents-only unit. A session that writes code still holds the code lease, or works in its own worktree.
|
|
10
|
+
|
|
11
|
+
**Every file several sessions touch has one writer.** Each session adds only its own rows to the review log. Translation catalogs count as code, so in the shared folder only the session holding the code lease writes them. devPNT's store goes in the Shared section of a commit map.
|
|
12
|
+
|
|
13
|
+
**The coordinator survives compaction and changes only when you say so.** After its context is compacted, the coordinator rereads the leases and the shared request record before acting, instead of trusting its summary. A session it starts does not become coordinator. To change coordinator, name the new session: it records your words, tells the previous coordinator, which stops, and sends you anything written in between.
|
|
14
|
+
|
|
15
|
+
**Branches that add review rows merge without a conflict.** When two branches both add rows to the review log and your project has no merge rule for that file, merging them stops on a conflict you resolve by hand. The check the agent runs when it closes a piece of work now notices the missing rule and prints the exact line to add to `.gitattributes`, so the agent sees what to fix while it works, without anyone reading release notes. Nothing changes at session start, and the note never makes a check fail.
|
|
16
|
+
|
|
17
|
+
#### What to do
|
|
18
|
+
|
|
19
|
+
**1. Update (everyone).** The changes arrive only with the update.
|
|
20
|
+
1. Run `npm install -g @antoneeo/agentic-sdlc-skill@latest`, then `agentic-sdlc-install-skill`.
|
|
21
|
+
2. Close and reopen your agent sessions: the new version loads only at startup.
|
|
22
|
+
|
|
23
|
+
To check: `npm ls -g @antoneeo/agentic-sdlc-skill` shows 1.52.0.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- `coordination.md` (F-089): the checkout a runtime mounts is the one exception to «own worktree» under coordination — the code-writer lease holder, a documents-only part (its own unit's files under the docs root and its own review-log rows; no git command that changes the checkout, no `index` or `mark`) and the coordinator, which alone runs `index`, `review-map` and `mark` there; the switch/stash/reset bans hold. «Code» defined (translation catalogs included). §1 retitled «Shared files: one writer each»: review log, translation catalogs, an external tool's store tracked in git. Who coordinates: the named conversation keeps the role across compaction and rereads `leases.md` and the shared record; a session another starts never inherits it; a new owner entry changes it, with a handover window up to the previous coordinator's answer. `leases.md` opens with a `coordinator` line. Ruling r42.
|
|
27
|
+
- `SKILL.md` Phase 4: the shared checkout, not the code-writer lease alone, is the exception to the own worktree; the bans hold there and only its coordinator runs `index`.
|
|
28
|
+
- `templates.md`: `leases.md` opening line; a commit-map Shared example for devPNT's store.
|
|
29
|
+
- The shared validator (F-090): `check` prints a `[note]` when the review log (`<docs>/audit/reviews/REVIEW_LOG.md`) has no `merge` attribute, naming the line to add to `.gitattributes` at the repository root (`git check-attr`, with personal and system attribute files ignored; a per-clone `.git/info/attributes` still counts). A deliberate non-union driver is respected. The exit code is unchanged, and session orientation still runs no git.
|
|
30
|
+
- `ENFORCEMENT.md`: «A review log git would not merge cleanly -- `check` names it» (F-090).
|
|
31
|
+
- `templates.md`: the `.gitattributes` stanza's note says `check` names a missing stanza; `coordination.md` §1: the coordinator adds it (F-090).
|
|
32
|
+
|
|
5
33
|
## [1.51.0] - 2026-10-31
|
|
6
34
|
|
|
7
35
|
### What's new
|
package/README.md
CHANGED
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
<!-- whats-new:begin -->
|
|
6
6
|
<!-- generated by scripts/whats_new.js from CHANGELOG.md: edit the CHANGELOG, then run node scripts/whats_new.js --write -->
|
|
7
|
-
## What's new in 1.
|
|
7
|
+
## What's new in 1.52.0
|
|
8
8
|
|
|
9
|
-
**
|
|
9
|
+
**A session that writes only documents no longer costs you a branch.** When you run several sessions with a coordinator, a session working only on design documents can work in the folder the others already use, instead of a worktree of its own. It writes only its own unit's files, runs no git command that changes the folder, and leaves index regeneration and its closure steps to the coordinator, so you no longer merge one branch per documents-only unit. A session that writes code still holds the code lease, or works in its own worktree.
|
|
10
10
|
|
|
11
|
-
**
|
|
11
|
+
**Every file several sessions touch has one writer.** Each session adds only its own rows to the review log. Translation catalogs count as code, so in the shared folder only the session holding the code lease writes them. devPNT's store goes in the Shared section of a commit map.
|
|
12
12
|
|
|
13
|
-
**The
|
|
13
|
+
**The coordinator survives compaction and changes only when you say so.** After its context is compacted, the coordinator rereads the leases and the shared request record before acting, instead of trusting its summary. A session it starts does not become coordinator. To change coordinator, name the new session: it records your words, tells the previous coordinator, which stops, and sends you anything written in between.
|
|
14
|
+
|
|
15
|
+
**Branches that add review rows merge without a conflict.** When two branches both add rows to the review log and your project has no merge rule for that file, merging them stops on a conflict you resolve by hand. The check the agent runs when it closes a piece of work now notices the missing rule and prints the exact line to add to `.gitattributes`, so the agent sees what to fix while it works, without anyone reading release notes. Nothing changes at session start, and the note never makes a check fail.
|
|
14
16
|
|
|
15
17
|
#### What to do
|
|
16
18
|
|
|
@@ -18,17 +20,7 @@
|
|
|
18
20
|
1. Run `npm install -g @antoneeo/agentic-sdlc-skill@latest`, then `agentic-sdlc-install-skill`.
|
|
19
21
|
2. Close and reopen your agent sessions: the new version loads only at startup.
|
|
20
22
|
|
|
21
|
-
To check: `npm ls -g @antoneeo/agentic-sdlc-skill` shows 1.
|
|
22
|
-
|
|
23
|
-
**2. Coordinating several sessions (only if you run them in parallel).**
|
|
24
|
-
- **This concerns you if** you run more than one agent session on the same repository at the same time.
|
|
25
|
-
- **Why:** without a coordinator, sessions can write the same record at once, restart a container another session is using, or leave one commit nobody can split by unit.
|
|
26
|
-
- **Steps:** tell the session you want as coordinator, in your own words, that it coordinates the others; it records your words, and the rules apply from then on. Each other session asks it before using a shared resource. Before committing several sessions' work together, it writes the commit map and runs `sdlc_check.py commit-map <map file>`.
|
|
27
|
-
- **To check:** when a session takes a shared resource, `ai_docs/audit/leases.md` gains a `take` line naming it.
|
|
28
|
-
|
|
29
|
-
| New file | Skill | Who reads it |
|
|
30
|
-
|---|---|---|
|
|
31
|
-
| `coordination.md` | agentic-sdlc | the agent, only while several sessions share a repository |
|
|
23
|
+
To check: `npm ls -g @antoneeo/agentic-sdlc-skill` shows 1.52.0.
|
|
32
24
|
|
|
33
25
|
Full history: [CHANGELOG](https://github.com/Antoneeo/agentic-sdlc-skill/blob/main/CHANGELOG.md)
|
|
34
26
|
<!-- whats-new:end -->
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antoneeo/agentic-sdlc-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.52.0",
|
|
4
4
|
"description": "Documentation-First SDLC protocol for Claude Code, Gemini CLI, Google Antigravity and Codex with risk triage, Vision governance, installed support files and optional devPNT integration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -183,6 +183,16 @@ not see them, because the wired hook legitimately lives in the git-ignored
|
|
|
183
183
|
mechanism (Gemini today) keeps the note -- read it as the manual-reads reminder; a
|
|
184
184
|
`.codex/hooks.json` wired in a shape other than the documented one keeps it too.
|
|
185
185
|
|
|
186
|
+
**A review log git would not merge cleanly -- `check` names it (F-090).** When the docs
|
|
187
|
+
root holds `audit/reviews/REVIEW_LOG.md` and git reports no `merge` attribute for it (no
|
|
188
|
+
committed `.gitattributes` line covers it: a project set up before the stanza, a custom
|
|
189
|
+
docs root, a project below the repository root, a course project), `check` prints one
|
|
190
|
+
`[note]` with the exact line to add at the repository root. Same contract as above:
|
|
191
|
+
informational, never the exit code, never a `validate` warning. Personal attribute files
|
|
192
|
+
(except the per-clone `.git/info/attributes`) are ignored, so the note matches what a
|
|
193
|
+
teammate's clone does; a deliberate driver other
|
|
194
|
+
than `union` is respected. Session orientation does not run it: it stays zero-execution.
|
|
195
|
+
|
|
186
196
|
**Installing the package wires the hook machine-wide (F-042).** On Claude Code
|
|
187
197
|
with Python, `npm i -g` (and every update) wires a SessionStart orient hook into
|
|
188
198
|
the USER-level settings (`$CLAUDE_CONFIG_DIR/settings.json` when set, else
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentic-sdlc
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.52.0
|
|
4
4
|
description: Documentation-First SDLC protocol with risk-proportional triage, Vision as a guide, a complete Standalone mode and optional symbiosis with devPNT. Use for features, significant bugs, refactors, audits and documented maintenance.
|
|
5
5
|
author: Antonio Pinto (https://github.com/Antoneeo)
|
|
6
6
|
copyright: (c) 2026 Antonio Pinto
|
|
@@ -208,7 +208,7 @@ Hybrid L3:
|
|
|
208
208
|
### 4. Development and Testing
|
|
209
209
|
|
|
210
210
|
- Implement only after the documentation gate required by the level; at L3 it ends with the owner's design approval (`review.md` §When a review is due). **Flip the ANALYSIS frontmatter `PLANNED` → `IN_PROGRESS` when implementation starts** — that flip is what `gate` and the handoff registry key on, and nothing else performs it.
|
|
211
|
-
- Isolate the work: run an L3 change on its own branch. In Hybrid, prefer a git worktree from the start — a running devPNT server locks `.devpnt/*.db` and blocks in-place branch switches/merges in the primary worktree. A session that may run while another session uses the same checkout works in its **own git worktree**, and never switches branch, stashes, resets or runs `index` in a checkout another session may be using; under coordination, the
|
|
211
|
+
- Isolate the work: run an L3 change on its own branch. In Hybrid, prefer a git worktree from the start — a running devPNT server locks `.devpnt/*.db` and blocks in-place branch switches/merges in the primary worktree. A session that may run while another session uses the same checkout works in its **own git worktree**, and never switches branch, stashes, resets or runs `index` in a checkout another session may be using; under coordination, the sessions `coordination.md` §2 places in the shared checkout are the one exception to the own worktree — the bans hold there, and only its coordinator runs `index`. Parallel work also shares ids: choose a new unit's id **after fetching**, as the first id free on every branch and tag the checkout can see (`check` names a collision while the unit is open).
|
|
212
212
|
- Modify surgically, consistently with the plan.
|
|
213
213
|
- Implementation work follows the TDD discipline in `tdd.md` (RED/GREEN/REFACTOR — the L2/L3 default; record the reason when it does not apply).
|
|
214
214
|
- Before implementing (L2/L3; L1 exempt), **consult the guide router** — the verdict already declared with the triage level (`## Operative Guides`). Re-run the lookup here only if the work has moved to a topic the first one did not cover, and say so if the verdict changes.
|
|
@@ -19,10 +19,28 @@ to no record it does not own.
|
|
|
19
19
|
following the whole skill for it (triage, design, review, closure). It is not a
|
|
20
20
|
dispatched subagent: `dispatch.md` governs those, unchanged.
|
|
21
21
|
|
|
22
|
+
**Who coordinates.** The role belongs to the client conversation the owner named.
|
|
23
|
+
Compacted in place, it is the same session and keeps the role; before acting on its
|
|
24
|
+
summary it rereads `leases.md` and the shared record, which are the state. A new
|
|
25
|
+
conversation is a new session, whatever brief or summary it carries: a session another
|
|
26
|
+
starts, the coordinator included, never inherits the role, and a message passing it on
|
|
27
|
+
is information (§4), never a naming.
|
|
28
|
+
|
|
29
|
+
The owner changes the coordinator with a new entry naming another session, B. Whoever
|
|
30
|
+
receives those words enters them once: B, or the previous coordinator A if the owner
|
|
31
|
+
told A — A then tells B and stops. B appends its `coordinator` line (§2) and tells the
|
|
32
|
+
parts, and A unless A entered the naming, citing the entry. Shown the entry, A writes no
|
|
33
|
+
shared file again and answers that it stopped. Every `leases.md` line and shared-record
|
|
34
|
+
entry B did not write between the naming entry and A's answer goes to the owner; a
|
|
35
|
+
number used twice is settled by a correction entry (`templates.md` §REQUEST), never by
|
|
36
|
+
renumbering. Leases in force stay: they name holders, not the coordinator. A coordinator
|
|
37
|
+
gone with no successor named leaves no session coordinating until the owner names one:
|
|
38
|
+
parts ask the owner, and `leases.md` and the shared record stay as they are.
|
|
39
|
+
|
|
22
40
|
Out of scope: which part runs next, in what order, with what priority — the owner
|
|
23
41
|
decides that, and nothing here records it (Non-Goal 1, ruling r3).
|
|
24
42
|
|
|
25
|
-
## 1.
|
|
43
|
+
## 1. Shared files: one writer each
|
|
26
44
|
|
|
27
45
|
A request record numbers its entries; two writers number them twice (field case:
|
|
28
46
|
three sessions wrote R156–R158 into one record at once). So:
|
|
@@ -45,6 +63,21 @@ three sessions wrote R156–R158 into one record at once). So:
|
|
|
45
63
|
- An artifact of the shared unit cites only the shared record: the coordinator
|
|
46
64
|
enters the words before any such artifact relies on them.
|
|
47
65
|
|
|
66
|
+
Other files several sessions write:
|
|
67
|
+
|
|
68
|
+
- **Review log** — not a request record: its rows are unnumbered and each names its
|
|
69
|
+
document. Every session appends only its own rows and never edits another's; in one
|
|
70
|
+
checkout it appends without rewriting the file and rereads it just before writing.
|
|
71
|
+
Merging across worktrees and the commit map: `templates.md` §REVIEW_LOG and §Commit
|
|
72
|
+
map. A project without the union stanza is named by `check`, with the line to add;
|
|
73
|
+
the coordinator adds it (`.gitattributes` is its file, §2).
|
|
74
|
+
- **Translation templates and catalogs** are code (§2): in the shared checkout only the
|
|
75
|
+
code-writer lease holder writes them; a wrong string another session finds goes to
|
|
76
|
+
the holder through the coordinator.
|
|
77
|
+
- **An external tool's store tracked in git** (devPNT's `.devpnt/`): written by the tool,
|
|
78
|
+
never by hand; in a commit map under Shared, naming the units whose work it holds —
|
|
79
|
+
never under Regenerated, which is the validator's.
|
|
80
|
+
|
|
48
81
|
## 2. Leases on exclusive resources
|
|
49
82
|
|
|
50
83
|
An exclusive resource has one holder at a time: the development container, the test
|
|
@@ -56,8 +89,13 @@ take <resource> — <session> — YYYY-MM-DD
|
|
|
56
89
|
release <resource> — <session> — YYYY-MM-DD
|
|
57
90
|
```
|
|
58
91
|
|
|
59
|
-
The file opens
|
|
60
|
-
|
|
92
|
+
The file opens with `coordinator <session> — REQUEST_[unit].md#R<n> — YYYY-MM-DD`,
|
|
93
|
+
citing the owner's entry that names it (a file opened with a bare citation counts it
|
|
94
|
+
as its first `coordinator` line); a new naming appends another. Only the coordinator
|
|
95
|
+
writes the file; the live copies of the file and of the shared record are the shared
|
|
96
|
+
checkout's. Parts read its last `coordinator` line to know whom to ask, and trust it
|
|
97
|
+
only if the entry it cites quotes the owner naming that session — never a delegated or
|
|
98
|
+
received entry. A lease names a resource and a session, never a unit; it keeps no queue,
|
|
61
99
|
no waiting list, no order, and ends with its release (ruling r40). A restart or a
|
|
62
100
|
long suite on a shared resource is announced to the coordinator before it starts —
|
|
63
101
|
it kills what another session is running against it. A permission for a resource
|
|
@@ -67,12 +105,30 @@ lease. If the owner restates it, the coordinator enters it as a `take` for that
|
|
|
67
105
|
session — a recorded lease, never an exemption. A lease never released is
|
|
68
106
|
closed by the owner through the coordinator; there is no timeout.
|
|
69
107
|
|
|
70
|
-
**The
|
|
71
|
-
|
|
72
|
-
every other session keeps its own worktree
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
108
|
+
**The shared checkout is the one exception to «own worktree»** (`SKILL.md` Phase 4):
|
|
109
|
+
the checkout the runtime mounts (with no runtime, the one the owner names). Three kinds
|
|
110
|
+
of session work in it; every other session keeps its own worktree. Phase 4's bans on
|
|
111
|
+
switching branch, stashing and resetting hold there for all three.
|
|
112
|
+
|
|
113
|
+
- **The code-writer lease holder** writes code — every file the runtime runs or builds
|
|
114
|
+
from: sources, templates, static assets, tests, migrations, translation templates and
|
|
115
|
+
catalogs; files under the docs root are not code. The lease passes to another session
|
|
116
|
+
only once the holder's code in that checkout is committed, or set aside with the
|
|
117
|
+
owner's yes. Two sessions' code in that checkout is a violation, code a previous
|
|
118
|
+
holder left uncommitted included.
|
|
119
|
+
- **A documents-only part** writes only its own unit's files under the docs root and its
|
|
120
|
+
own review-log rows (§1); it runs no git command that changes the checkout and no
|
|
121
|
+
command that rewrites other units' files (`index`, `mark`). A change it needs
|
|
122
|
+
elsewhere goes to the session that writes that file. Before writing any code it asks
|
|
123
|
+
the coordinator: it takes the code-writer lease, or the owner commits its documents
|
|
124
|
+
and its own worktree is cut from that commit.
|
|
125
|
+
- **The coordinator** writes the shared files, and any file there that is neither code
|
|
126
|
+
nor under the docs root (root `README.md`, `CHANGELOG.md`, `.gitattributes`, CI
|
|
127
|
+
configuration — it runs `init` when needed); it alone runs `index`, `review-map` and
|
|
128
|
+
`mark` there, for the documents-only parts' closure steps too. There `review-map` sees
|
|
129
|
+
every session's files, so when a documents-only part closes, the coordinator writes
|
|
130
|
+
that unit's section of the commit map (§6) and the part's merge brief takes its file
|
|
131
|
+
table from it, and says so.
|
|
76
132
|
|
|
77
133
|
## 3. Decisions taken under delegation
|
|
78
134
|
|
|
@@ -111,6 +167,9 @@ Open points:
|
|
|
111
167
|
Needs the owner:
|
|
112
168
|
```
|
|
113
169
|
|
|
170
|
+
A documents-only part in the shared checkout lists under `Open points` the closure
|
|
171
|
+
steps it left to the coordinator (§2).
|
|
172
|
+
|
|
114
173
|
The coordinator checks each claim on the diff and the run output, never on the
|
|
115
174
|
message (`review.md`, an unproven completion claim), then tells the owner what is
|
|
116
175
|
done, what is left and what needs them.
|
|
@@ -1377,9 +1377,12 @@ def _open_units(root):
|
|
|
1377
1377
|
return units
|
|
1378
1378
|
|
|
1379
1379
|
|
|
1380
|
-
def _git_out(root, *args, timeout=30):
|
|
1380
|
+
def _git_out(root, *args, timeout=30, env=None):
|
|
1381
|
+
# `env` is merged into the inherited environment, never a replacement: a bare
|
|
1382
|
+
# dict would drop PATH and fail silently on Windows.
|
|
1381
1383
|
r = subprocess.run(["git", *args], cwd=str(root), capture_output=True, text=True,
|
|
1382
|
-
encoding="utf-8", errors="replace", timeout=timeout
|
|
1384
|
+
encoding="utf-8", errors="replace", timeout=timeout,
|
|
1385
|
+
env={**os.environ, **env} if env else None)
|
|
1383
1386
|
return r.stdout if r.returncode == 0 else None
|
|
1384
1387
|
|
|
1385
1388
|
|
|
@@ -2481,10 +2484,64 @@ def cmd_check(root, strict=False, hybrid=False, extra_validate=None, extra_secti
|
|
|
2481
2484
|
failed = any(rc for _, rc in rcs)
|
|
2482
2485
|
print(f"\ncheck: {'NOT CLEAN' if failed else 'CLEAN'} "
|
|
2483
2486
|
f"({', '.join(f'{title} rc={rc}' for title, rc in rcs)})")
|
|
2484
|
-
|
|
2487
|
+
print_check_notes(root)
|
|
2485
2488
|
return 1 if failed else 0
|
|
2486
2489
|
|
|
2487
2490
|
|
|
2491
|
+
def _attr_pattern(path):
|
|
2492
|
+
"""A .gitattributes pattern matching exactly `path`. Order matters (probed):
|
|
2493
|
+
a backslash, glob characters and a leading `#` or `!` (comment, negation)
|
|
2494
|
+
are escaped first, then the result is C-quoted when it holds whitespace,
|
|
2495
|
+
`"` or a backslash."""
|
|
2496
|
+
p = re.sub(r"([\\\[*?])", r"\\\1", path)
|
|
2497
|
+
if p.startswith(("#", "!")):
|
|
2498
|
+
p = "\\" + p
|
|
2499
|
+
if re.search(r'[\s"\\]', p):
|
|
2500
|
+
p = '"' + p.replace("\\", "\\\\").replace('"', '\\"') + '"'
|
|
2501
|
+
return p
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
def review_log_union_note(root):
|
|
2505
|
+
"""F-090: the note for a review log git would not merge with union, or None.
|
|
2506
|
+
|
|
2507
|
+
Git itself is asked (`check-attr`), so patterns and nested files count;
|
|
2508
|
+
personal and system attribute files do not, so the answer is the one a
|
|
2509
|
+
teammate's clone gets. Only `unspecified` is a gap: `union` or any other
|
|
2510
|
+
driver is a choice. Residual: `.git/info/attributes` is still read. Any
|
|
2511
|
+
failure -- no git, not a work tree, timeout -- is no note: `check` never
|
|
2512
|
+
breaks on it."""
|
|
2513
|
+
try:
|
|
2514
|
+
log = ai_path(root, "audit", "reviews", "REVIEW_LOG.md")
|
|
2515
|
+
if not log.is_file():
|
|
2516
|
+
return None
|
|
2517
|
+
prefix = _git_out(root, "rev-parse", "--show-prefix", timeout=3)
|
|
2518
|
+
if prefix is None:
|
|
2519
|
+
return None
|
|
2520
|
+
rel = log.resolve().relative_to(Path(root).resolve()).as_posix()
|
|
2521
|
+
out = _git_out(root, "-c", "core.attributesFile=", "check-attr", "-z", "merge",
|
|
2522
|
+
"--", rel, timeout=3, env={"GIT_ATTR_NOSYSTEM": "1"})
|
|
2523
|
+
if out is None:
|
|
2524
|
+
return None
|
|
2525
|
+
fields = out.split("\0")
|
|
2526
|
+
if len(fields) < 3 or fields[2] != "unspecified":
|
|
2527
|
+
return None
|
|
2528
|
+
path = prefix.rstrip("\r\n") + rel # a folder may begin with a space
|
|
2529
|
+
return (f"[note] {path} has no merge attribute: two branches that both add review "
|
|
2530
|
+
"rows conflict when merged. Fix: add this line to .gitattributes at the "
|
|
2531
|
+
f"repository root: {_attr_pattern(path)} merge=union")
|
|
2532
|
+
except Exception:
|
|
2533
|
+
return None
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
def print_check_notes(root):
|
|
2537
|
+
"""Every check-layer note, informational and never an exit code. The one
|
|
2538
|
+
place an overlay that replaces `check` calls, so a new note cannot miss it."""
|
|
2539
|
+
print_orient_hook_note(root)
|
|
2540
|
+
note = review_log_union_note(root)
|
|
2541
|
+
if note:
|
|
2542
|
+
print(note)
|
|
2543
|
+
|
|
2544
|
+
|
|
2488
2545
|
# --------------------------------------------------------------------- gate
|
|
2489
2546
|
|
|
2490
2547
|
# --- UserPromptSubmit reminder hook (F-046) --------------------------------
|
|
@@ -571,7 +571,7 @@ Written only by the coordinating session (`coordination.md` §2); append-only.
|
|
|
571
571
|
```markdown
|
|
572
572
|
# Leases
|
|
573
573
|
|
|
574
|
-
|
|
574
|
+
coordinator coordinating session — REQUEST_[unit].md#R<n> — YYYY-MM-DD
|
|
575
575
|
|
|
576
576
|
take dev-container — wave-6 session — YYYY-MM-DD
|
|
577
577
|
release dev-container — wave-6 session — YYYY-MM-DD
|
|
@@ -592,6 +592,7 @@ committed. Each item is a list line whose first code span is the path.
|
|
|
592
592
|
|
|
593
593
|
## Shared
|
|
594
594
|
- `ai_docs/audit/reviews/REVIEW_LOG.md` — F-001, F-002
|
|
595
|
+
- `.devpnt/plans/plans.db` — F-001, F-002 (written by devPNT)
|
|
595
596
|
|
|
596
597
|
## Regenerated
|
|
597
598
|
- `ai_docs/INDEX.md`
|
|
@@ -809,7 +810,7 @@ Concurrent reviews: `init` writes a `.gitattributes` stanza giving this file
|
|
|
809
810
|
Rows are date-stamped and their order carries no meaning, so a union merge keeps
|
|
810
811
|
both sides instead of asking a human to choose. It is defence in depth: without
|
|
811
812
|
git, or without the stanza, the outcome is today's — one conflict you resolve by
|
|
812
|
-
hand, never a lost row.
|
|
813
|
+
hand, never a lost row. `check` names a missing stanza and the line to add (F-090).
|
|
813
814
|
|
|
814
815
|
|
|
815
816
|
## ai_docs/audit/HANDOFF_[feature].md — one open workstream, its own file
|