You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit cfdabe0
Browse filesBrowse the repository at this point in the historyBrowse files
spec: issue-3561 add placeholder line for local-file captures
The agent writes a fixed placeholder below the header of a local-file capture. The push replaces it with the file content and never records it as spec content (R-002, R-003, D-010).
Refs #3561
Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
Chainloop-Trace-Sessions: 7cd3c552-17aa-4789-a8b3-50aa37a27e6d
Copy file name to clipboardExpand all lines: docs/specs/issue-3561-up-to-date-local-spec-evidence.md
+19-15Lines changed: 19 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ This spec makes sure that the spec evidence that a push records is up to date. A
11
11
12
12
This spec changes the spec capture of [Spec issue-3495](issue-3495-session-spec-capture.md) and [Spec issue-3515](issue-3515-spec-capture-during-session.md). It does not replace them. Today the agent copies the text of each source into the session spec folder, and the push records what the agent wrote. The agent can forget to copy a source again after a change, or write a summary. Then the evidence holds an old or false record.
13
13
14
-
In this spec, the scope is sources that are local files. The push reads each local source itself, and records its content at push time. The agent writes only a header with the path. The copies of the file in the transcript become pointers to the spec material, as [Spec issue-3556](issue-3556-session-image-placeholders.md) defines. The capture instruction also tells the agent that the captures are attested evidence. Remote sources, for example a Notion page or a Linear ticket, can also change during a session. A later spec looks into them.
14
+
In this spec, the scope is sources that are local files. The push reads each local source itself, and records its content at push time. The agent writes only a header with the path, and a placeholder that the push replaces. The copies of the file in the transcript become pointers to the spec material, as [Spec issue-3556](issue-3556-session-image-placeholders.md) defines. The capture instruction also tells the agent that the captures are attested evidence. Remote sources, for example a Notion page or a Linear ticket, can also change during a session. A later spec looks into them.
15
15
16
16
## Problem
17
17
- In a real session, the agent captured a repository spec with its full text. Later it edited that spec, and did not copy it again. The push recorded the old version.
@@ -23,7 +23,7 @@ In this spec, the scope is sources that are local files. The push reads each loc
23
23
24
24
## Goals and Non-Goals
25
25
- Goal: when a local source changes during the session, the next push records its current version. This does not depend on the agent.
26
-
- Goal: the agent does not copy the text of a local file. It writes a header with the path only.
26
+
- Goal: the agent does not copy the text of a local file. It writes a header with the path, and a placeholder.
27
27
- Goal: the transcript holds no exact copy of the recorded content of a local source. Each exact copy becomes a pointer to the spec material.
28
28
- Goal: the instruction and the reminder tell the agent that the captures are attested evidence.
29
29
- Non-goal, for now: up-to-date evidence for remote sources, for example a Notion page, a Linear ticket, or a URL. The agent still copies their text (D-001 of Spec issue-3495). A later spec looks into them (D-008).
@@ -43,12 +43,12 @@ A capture file has a header and a body. The header holds the kind, the source, t
43
43
The file MUST be a regular text file.
44
44
- Done when: the agent captures a repository spec, edits the spec three times, and does not touch the capture again. The push records the spec with its last edit.
45
45
46
-
### R-002: Header only for a local file
47
-
The capture instruction MUST tell the agent to write only the header for a local file, with the path as its source. The push MUST accept a capture with a header and no body when its source is a local file.
48
-
- Done when: the agent writes a design note outside the repository and captures it as a header with its path. The push records the full note.
46
+
### R-002: Header and placeholder for a local file
47
+
The capture instruction MUST tell the agent to write the header for a local file, with the path as its source. Below the header, the agent MUST write a fixed placeholder line, and no text of the file. The placeholder shows that the push fills the body. The push MUST accept a capture with the placeholder as its body, or with no body, when its source is a local file. The push MUST never record the placeholder as spec content.
48
+
- Done when: the agent writes a design note outside the repository and captures it as a header and the placeholder. The push records the full note.
49
49
50
50
### R-003: Fallback when the file cannot be read
51
-
The push can fail to use the local file. For example, it cannot read the file, or the file is not text or is too large. Then the push MUST record the body that the agent wrote, as today. When there is no body, the push MUST record a warning that names the capture. It MUST NOT record the capture. The push MUST NOT fail or stop.
51
+
The push can fail to use the local file. For example, it cannot read the file, or the file is not text or is too large. Then the push MUST record the body that the agent wrote, as today. When there is no body, or the body is only the placeholder, the push MUST record a warning that names the capture. It MUST NOT record the capture. The push MUST NOT fail or stop.
52
52
- Done when: the agent captures a local file and then deletes the file. The push succeeds, and the evidence holds a warning for that capture.
53
53
54
54
### R-004: Capture time
@@ -68,7 +68,7 @@ The capture instruction and the reminder MUST tell the agent that the captures a
68
68
- The redaction of Spec issue-3495 applies to the recorded content, as to any other capture.
69
69
70
70
## Proposal
71
-
The agent writes a capture file for each source, as today. A local source is, for example, a repository spec or a design note in a notes folder. For a local source, the agent writes only the header. The header has the kind, the role, the title, the description, and the path of the file as its source. For a ticket, a web page, pasted text, or an approved plan, the agent still copies the full text. For an image, it copies the file.
71
+
The agent writes a capture file for each source, as today. A local source is, for example, a repository spec or a design note in a notes folder. For a local source, the agent writes the header and a placeholder line. The header has the kind, the role, the title, the description, and the path of the file as its source. For a ticket, a web page, pasted text, or an approved plan, the agent still copies the full text. For an image, it copies the file.
72
72
73
73
The agent writes this capture for a repository spec:
74
74
@@ -80,9 +80,12 @@ role: spec
80
80
title: "Spec foo"
81
81
description: The spec that this session implements.
82
82
---
83
+
<!-- chainloop: content is read from the uri at push time -->
83
84
```
84
85
85
-
At push time, the CLI reads the spec folder as today. For each text capture whose source is a local file, it reads that file. When the read succeeds, and the file is text and under the limit, the CLI puts the file content below the header. It keeps the header that the agent wrote, and sets the capture time to the modification time of the file. The push stores this result:
86
+
The placeholder is a fixed line that the CLI recognizes exactly. A person who looks at the spec folder sees that the push has not filled the capture yet. An older CLI records the placeholder line as the text. That is wrong, but the error is visible. An older CLI drops a capture with an empty body with no message.
87
+
88
+
At push time, the CLI reads the spec folder as today. For each text capture whose source is a local file, it reads that file. When the read succeeds, and the file is text and under the limit, the CLI replaces the body with the file content. It keeps the header that the agent wrote, and sets the capture time to the modification time of the file. The push stores this result:
86
89
87
90
```markdown
88
91
---
@@ -98,13 +101,13 @@ description: The spec that this session implements.
98
101
(the current content of docs/specs/foo.md)
99
102
```
100
103
101
-
The stored result has the same form as a capture today. The CLI redacts it and stores it as a spec material, as today. The material and the entry in the spec list do not change. When the CLI cannot use the file, it keeps the agent's body, or records a warning when there is no body.
104
+
The stored result has the same form as a capture today. The CLI redacts it and stores it as a spec material, as today. The material and the entry in the spec list do not change. When the CLI cannot use the file, it keeps the agent's body. When there is no body, or only the placeholder, it records a warning.
102
105
103
106
The push compares by digest, so an unchanged source costs little. The CLI already keeps the redacted copy of each capture under its digest for the session. When a local source did not change since the last push, the result has the same digest. The CLI then uses the stored copy and does not scan it again. The only new work at each push is one read and one digest of each local source.
104
107
105
108
The CLI then knows two digests for the material of a local source. One is the digest of the capture as the CLI recorded it. The other is the digest of the file content. It gives both to the transcript replacement of Spec issue-3556. A full read of the file, and a full write of its final content, become pointers to the material. The spec content is then in the evidence one time, as the material.
106
109
107
-
The instruction leads with the stakes. The captures are attested evidence, like a commit. A partial or wrong capture is a false record. The instruction no longer says that there is no need to mention the capture to the user. It says that a local file needs a header with its path only. For a remote source, it asks for the full text, an update in the same turn as a change, and a check before a push. The reminder repeats these rules in a few lines.
110
+
The instruction leads with the stakes. The captures are attested evidence, like a commit. A partial or wrong capture is a false record. The instruction no longer says that there is no need to mention the capture to the user. It says that a local file needs a header with its path and the placeholder. For a remote source, it asks for the full text, an update in the same turn as a change, and a check before a push. The reminder repeats these rules in a few lines.
108
111
109
112
```mermaid
110
113
sequenceDiagram
@@ -114,14 +117,14 @@ sequenceDiagram
114
117
participant CLI as Trace push
115
118
116
119
Agent->>Note: Write or edit the spec
117
-
Agent->>Folder: Header only, source = path of the file
120
+
Agent->>Folder: Header and placeholder, source = path of the file
118
121
Agent->>Note: More edits (capture not touched)
119
122
CLI->>Folder: Read captures
120
123
CLI->>Note: Read current content
121
124
alt Readable text file under the limit
122
125
CLI->>CLI: Body = file content, time = file modification time
123
126
else Not readable
124
-
CLI->>CLI: Keep agent body, or warn when there is none
127
+
CLI->>CLI: Keep agent body, or warn when there is only the placeholder
125
128
end
126
129
CLI->>CLI: Redact and store spec material
127
130
CLI->>CLI: Replace copies of the file content in the transcript with pointers
@@ -132,14 +135,15 @@ sequenceDiagram
132
135
| ID | Decision | Choice | Why (and what we rejected) | Source |
| D-001 | How the push treats a local source | Read the file at push time and record its content | The record no longer depends on the agent. It never blocks the push. Rejected: compare the capture with the file and warn (the evidence still holds the wrong text). Rejected: refuse the push on a difference (Spec issue-3495 never blocks a push for a capture). | drafting |
135
-
| D-002 | Body of a local-file capture | Header with the path only| The push reads the file, so a copy from the agent is a duplicate that the push discards. The duplicate was the reason the agent skipped the copy. Rejected: always copy the full text (a copy the push throws away, and one more copy in the transcript). | drafting |
138
+
| D-002 | Body of a local-file capture | Header with the path, and no text of the file (see D-010 for the placeholder)| The push reads the file, so a copy from the agent is a duplicate that the push discards. The duplicate was the reason the agent skipped the copy. Rejected: always copy the full text (a copy the push throws away, and one more copy in the transcript). | drafting |
136
139
| D-003 | Forms of a local path | Absolute path, `~/` path, `file://` URI, and path relative to the repository root | A design note in a notes folder is outside the repository. Rejected: files inside the repository only (misses the case of the incident). | drafting |
137
-
| D-004 | Evidence signal when the push replaces the agent's body | No warning. The capture time is the modification time of the file | The record is correct, so a warning adds noise. The file time tells when the content last changed. Rejected: a warning for each replaced body. | drafting |
140
+
| D-004 | Evidence signal when the push replaces the agent's body | No warning. The capture time is the modification time of the file | The record is right, so a warning adds noise. The file time tells when the content last changed. Rejected: a warning for each replaced body. | drafting |
138
141
| D-005 | Copies of a local source in the transcript | Register the digest of the file content as a source for the pointers of Spec issue-3556 | The content is in the spec material, so a full copy in the transcript is a duplicate. The match stays exact, so no other content leaves the transcript. Rejected: keep the copies inline (the evidence holds the spec two or three times). | owner request |
139
142
| D-006 | Size limit for a local file | 1 MiB. Over the limit, the agent's body stays | A spec is text and small. A large file in the evidence is more likely an error. | drafting |
140
143
| D-007 | Instruction wording | State the stakes, drop "no need to mention", same-turn update and check before push for remote sources | The agent read the captures as bookkeeping. These rules still apply to remote sources, which the push cannot read. | drafting |
141
144
| D-008 | Scope | Local files only. Remote sources, for example Notion pages and Linear tickets, in a later spec | The push can read a local file with no credentials and no connector. A remote source needs a fetch, and Spec issue-3495 keeps the CLI free of connectors (D-001 of that spec). The problem is the same for remote sources, so a later spec looks into them. | owner request |
142
145
| D-009 | When the push does the work again | Compare by digest at push time, and reuse the stored redacted copy when the digest is the same | The push already keeps a redacted copy for each digest. Rejected: a hook that copies each changed source into the spec folder at each turn. It computes a digest at each turn, and the push must read the files anyway. | owner request |
146
+
| D-010 | Body that the agent writes for a local file | A fixed placeholder line. The push also accepts no body | The placeholder shows that the agent left the body to the push on purpose, and that the push has not filled it yet. An older CLI records the placeholder as visible wrong text, and does not drop the capture with no message. The push never records the placeholder as content. Rejected: header only (an empty body looks the same as a capture that the agent forgot to fill). | owner request |
143
147
144
148
## Open Questions
145
149
None.
@@ -154,5 +158,5 @@ None.
154
158
|------|------------|
155
159
| The agent sets a local path to a file that is not a spec, for example a file with credentials. | The redaction of Spec issue-3495 runs on the recorded content. The agent could already copy any file into the folder, so the risk is not new. Only text files under the limit are read. |
156
160
| The file changes after the last AI-assisted commit and before the push. The evidence then holds content that the session did not produce. | The push records the content at push time, as Spec issue-3515 defines for a changed spec. The capture time shows the file time. |
157
-
| The file is deleted before the push, and the capture has only a header. | The push records a warning (R-003). The transcript still holds the agent's writes of the file. |
161
+
| The file is deleted before the push, and the capture has only a header and the placeholder. | The push records a warning (R-003). The transcript still holds the agent's writes of the file. |
158
162
| The agent still writes a summary for a remote source. | The instruction states the stakes and asks for a check before a push. A remote source is the case that a hook cannot check. |
0 commit comments